Merge remote-tracking branch 'refs/remotes/origin/development' into pr/1153

This commit is contained in:
Anis A. Hireche 2016-02-26 14:39:38 +01:00
commit 10cb6ab9c4
893 changed files with 44063 additions and 6437 deletions

View file

@ -28,6 +28,8 @@
#include "T3D/gameBase/moveManager.h"
#include "console/engineAPI.h"
#include <cfloat>
static U32 sAIPlayerLoSMask = TerrainObjectType | StaticShapeObjectType | StaticObjectType;
IMPLEMENT_CO_NETOBJECT_V1(AIPlayer);
@ -107,6 +109,9 @@ AIPlayer::AIPlayer()
#endif
mIsAiControlled = true;
for( S32 i = 0; i < MaxTriggerKeys; i ++ )
mMoveTriggers[ i ] = false;
}
/**
@ -254,7 +259,7 @@ void AIPlayer::setAimObject( GameBase *targetObject )
* @param targetObject The object to target
* @param offset The offest from the target location to aim at
*/
void AIPlayer::setAimObject( GameBase *targetObject, Point3F offset )
void AIPlayer::setAimObject(GameBase *targetObject, const Point3F& offset)
{
mAimObject = targetObject;
mTargetInLOS = false;
@ -285,6 +290,53 @@ void AIPlayer::clearAim()
mAimOffset = Point3F(0.0f, 0.0f, 0.0f);
}
/**
* Set the state of a movement trigger.
*
* @param slot The trigger slot to set
* @param isSet set/unset the trigger
*/
void AIPlayer::setMoveTrigger( U32 slot, const bool isSet )
{
if(slot >= MaxTriggerKeys)
{
Con::errorf("Attempting to set an invalid trigger slot (%i)", slot);
}
else
{
mMoveTriggers[ slot ] = isSet; // set the trigger
setMaskBits(NoWarpMask); // force the client to updateMove
}
}
/**
* Get the state of a movement trigger.
*
* @param slot The trigger slot to query
* @return True if the trigger is set, false if it is not set
*/
bool AIPlayer::getMoveTrigger( U32 slot ) const
{
if(slot >= MaxTriggerKeys)
{
Con::errorf("Attempting to get an invalid trigger slot (%i)", slot);
return false;
}
else
{
return mMoveTriggers[ slot ];
}
}
/**
* Clear the trigger state for all movement triggers.
*/
void AIPlayer::clearMoveTriggers()
{
for( U32 i = 0; i < MaxTriggerKeys; i ++ )
setMoveTrigger( i, false );
}
/**
* This method calculates the moves for the AI player
*
@ -513,8 +565,8 @@ bool AIPlayer::getAIMove(Move *movePtr)
// Replicate the trigger state into the move so that
// triggers can be controlled from scripts.
for( int i = 0; i < MaxTriggerKeys; i++ )
movePtr->trigger[i] = getImageTriggerState(i);
for( U32 i = 0; i < MaxTriggerKeys; i++ )
movePtr->trigger[ i ] = mMoveTriggers[ i ];
#ifdef TORQUE_NAVIGATION_ENABLED
if(mJump == Now)
@ -673,24 +725,20 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
// Create a new path.
NavPath *path = new NavPath();
if(path)
path->mMesh = getNavMesh();
path->mFrom = getPosition();
path->mTo = pos;
path->mFromSet = path->mToSet = true;
path->mAlwaysRender = true;
path->mLinkTypes = mLinkTypes;
path->mXray = true;
// Paths plan automatically upon being registered.
if(!path->registerObject())
{
path->mMesh = getNavMesh();
path->mFrom = getPosition();
path->mTo = pos;
path->mFromSet = path->mToSet = true;
path->mAlwaysRender = true;
path->mLinkTypes = mLinkTypes;
path->mXray = true;
// Paths plan automatically upon being registered.
if(!path->registerObject())
{
delete path;
return false;
}
}
else
delete path;
return false;
}
if(path->success())
{
@ -779,11 +827,15 @@ void AIPlayer::followObject(SceneObject *obj, F32 radius)
if(!isServerObject())
return;
if ((mFollowData.lastPos - obj->getPosition()).len()<mMoveTolerance)
return;
if(setPathDestination(obj->getPosition()))
{
clearCover();
mFollowData.object = obj;
mFollowData.radius = radius;
mFollowData.lastPos = obj->getPosition();
}
}
@ -1256,3 +1308,43 @@ DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool ch
{
return object->checkInFoV(obj, fov, checkEnabled);
}
DefineEngineMethod( AIPlayer, setMoveTrigger, void, ( U32 slot ),,
"@brief Sets a movement trigger on an AI object.\n\n"
"@param slot The trigger slot to set.\n"
"@see getMoveTrigger()\n"
"@see clearMoveTrigger()\n"
"@see clearMoveTriggers()\n")
{
object->setMoveTrigger( slot, true );
}
DefineEngineMethod( AIPlayer, clearMoveTrigger, void, ( U32 slot ),,
"@brief Clears a movement trigger on an AI object.\n\n"
"@param slot The trigger slot to set.\n"
"@see setMoveTrigger()\n"
"@see getMoveTrigger()\n"
"@see clearMoveTriggers()\n")
{
object->setMoveTrigger( slot, false );
}
DefineEngineMethod( AIPlayer, getMoveTrigger, bool, ( U32 slot ),,
"@brief Tests if a movement trigger on an AI object is set.\n\n"
"@param slot The trigger slot to check.\n"
"@return a boolean indicating if the trigger is set/unset.\n"
"@see setMoveTrigger()\n"
"@see clearMoveTrigger()\n"
"@see clearMoveTriggers()\n")
{
return object->getMoveTrigger( slot );
}
DefineEngineMethod( AIPlayer, clearMoveTriggers, void, ( ),,
"@brief Clear ALL movement triggers on an AI object.\n"
"@see setMoveTrigger()\n"
"@see getMoveTrigger()\n"
"@see clearMoveTrigger()\n")
{
object->clearMoveTriggers();
}

View file

@ -63,6 +63,9 @@ private:
Point3F mAimOffset;
// move triggers
bool mMoveTriggers[MaxTriggerKeys];
// Utility Methods
void throwCallback( const char *name );
@ -119,10 +122,12 @@ private:
SimObjectPtr<SceneObject> object;
/// Distance at whcih to follow.
F32 radius;
Point3F lastPos;
/// Default constructor.
FollowData() : object(NULL)
{
radius = 5.0f;
lastPos = Point3F::Zero;
}
};
@ -158,7 +163,7 @@ public:
// Targeting and aiming sets/gets
void setAimObject( GameBase *targetObject );
void setAimObject( GameBase *targetObject, Point3F offset );
void setAimObject(GameBase *targetObject, const Point3F& offset);
GameBase* getAimObject() const { return mAimObject; }
void setAimLocation( const Point3F &location );
Point3F getAimLocation() const { return mAimLocation; }
@ -175,6 +180,11 @@ public:
Point3F getMoveDestination() const { return mMoveDestination; }
void stopMove();
// Trigger sets/gets
void setMoveTrigger( U32 slot, const bool isSet = true );
bool getMoveTrigger( U32 slot ) const;
void clearMoveTriggers();
#ifdef TORQUE_NAVIGATION_ENABLED
/// @name Pathfinding
/// @{

View file

@ -0,0 +1,127 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2013 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _EXAMPLE_ASSET_H_
#include "ExampleAsset.h"
#endif
#ifndef _ASSET_MANAGER_H_
#include "assets/assetManager.h"
#endif
#ifndef _CONSOLETYPES_H_
#include "console/consoleTypes.h"
#endif
#ifndef _TAML_
#include "persistence/taml/taml.h"
#endif
#ifndef _ASSET_PTR_H_
#include "assets/assetPtr.h"
#endif
// Debug Profiling.
#include "platform/profiler.h"
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(ExampleAsset);
ConsoleType(ExampleAssetPtr, TypeExampleAssetPtr, ExampleAsset, ASSET_ID_FIELD_PREFIX)
//-----------------------------------------------------------------------------
ConsoleGetType(TypeExampleAssetPtr)
{
// Fetch asset Id.
return (*((AssetPtr<ExampleAsset>*)dptr)).getAssetId();
}
//-----------------------------------------------------------------------------
ConsoleSetType(TypeExampleAssetPtr)
{
// Was a single argument specified?
if (argc == 1)
{
// Yes, so fetch field value.
const char* pFieldValue = argv[0];
// Fetch asset pointer.
AssetPtr<ExampleAsset>* pAssetPtr = dynamic_cast<AssetPtr<ExampleAsset>*>((AssetPtrBase*)(dptr));
// Is the asset pointer the correct type?
if (pAssetPtr == NULL)
{
// No, so fail.
//Con::warnf("(TypeTextureAssetPtr) - Failed to set asset Id '%d'.", pFieldValue);
return;
}
// Set asset.
pAssetPtr->setAssetId(pFieldValue);
return;
}
// Warn.
Con::warnf("(TypeTextureAssetPtr) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
ExampleAsset::ExampleAsset() :
mAcquireReferenceCount(0),
mpOwningAssetManager(NULL),
mAssetInitialized(false)
{
// Generate an asset definition.
mpAssetDefinition = new AssetDefinition();
}
//-----------------------------------------------------------------------------
ExampleAsset::~ExampleAsset()
{
// If the asset manager does not own the asset then we own the
// asset definition so delete it.
if (!getOwned())
delete mpAssetDefinition;
}
//-----------------------------------------------------------------------------
void ExampleAsset::initPersistFields()
{
// Call parent.
Parent::initPersistFields();
}
//------------------------------------------------------------------------------
void ExampleAsset::copyTo(SimObject* object)
{
// Call to parent.
Parent::copyTo(object);
}

View file

@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2013 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _EXAMPLE_ASSET_H_
#define _EXAMPLE_ASSET_H_
#ifndef _ASSET_BASE_H_
#include "assets/assetBase.h"
#endif
#ifndef _ASSET_DEFINITION_H_
#include "assets/assetDefinition.h"
#endif
#ifndef _STRINGUNIT_H_
#include "string/stringUnit.h"
#endif
#ifndef _ASSET_FIELD_TYPES_H_
#include "assets/assetFieldTypes.h"
#endif
//-----------------------------------------------------------------------------
class ExampleAsset : public AssetBase
{
typedef AssetBase Parent;
AssetManager* mpOwningAssetManager;
bool mAssetInitialized;
AssetDefinition* mpAssetDefinition;
U32 mAcquireReferenceCount;
public:
ExampleAsset();
virtual ~ExampleAsset();
/// Engine.
static void initPersistFields();
virtual void copyTo(SimObject* object);
/// Declare Console Object.
DECLARE_CONOBJECT(ExampleAsset);
protected:
virtual void initializeAsset(void) {}
virtual void onAssetRefresh(void) {}
};
DefineConsoleType(TypeExampleAssetPtr, ExampleAsset)
#endif // _ASSET_BASE_H_

View file

@ -0,0 +1,157 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2013 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHAPE_ASSET_H_
#include "ShapeAsset.h"
#endif
#ifndef _ASSET_MANAGER_H_
#include "assets/assetManager.h"
#endif
#ifndef _CONSOLETYPES_H_
#include "console/consoleTypes.h"
#endif
#ifndef _TAML_
#include "persistence/taml/taml.h"
#endif
#ifndef _ASSET_PTR_H_
#include "assets/assetPtr.h"
#endif
#include "core/resourceManager.h"
// Debug Profiling.
#include "platform/profiler.h"
static U32 execDepth = 0;
static U32 journalDepth = 1;
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(ShapeAsset);
ConsoleType(TestAssetPtr, TypeShapeAssetPtr, ShapeAsset, ASSET_ID_FIELD_PREFIX)
//-----------------------------------------------------------------------------
ConsoleGetType(TypeShapeAssetPtr)
{
// Fetch asset Id.
return (*((AssetPtr<ShapeAsset>*)dptr)).getAssetId();
}
//-----------------------------------------------------------------------------
ConsoleSetType(TypeShapeAssetPtr)
{
// Was a single argument specified?
if (argc == 1)
{
// Yes, so fetch field value.
const char* pFieldValue = argv[0];
// Fetch asset pointer.
AssetPtr<ShapeAsset>* pAssetPtr = dynamic_cast<AssetPtr<ShapeAsset>*>((AssetPtrBase*)(dptr));
// Is the asset pointer the correct type?
if (pAssetPtr == NULL)
{
// No, so fail.
//Con::warnf("(TypeTextureAssetPtr) - Failed to set asset Id '%d'.", pFieldValue);
return;
}
// Set asset.
pAssetPtr->setAssetId(pFieldValue);
return;
}
// Warn.
Con::warnf("(TypeTextureAssetPtr) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
ShapeAsset::ShapeAsset() :
mAcquireReferenceCount(0),
mpOwningAssetManager(NULL),
mAssetInitialized(false)
{
// Generate an asset definition.
mpAssetDefinition = new AssetDefinition();
}
//-----------------------------------------------------------------------------
ShapeAsset::~ShapeAsset()
{
// If the asset manager does not own the asset then we own the
// asset definition so delete it.
if (!getOwned())
delete mpAssetDefinition;
}
//-----------------------------------------------------------------------------
void ShapeAsset::initPersistFields()
{
// Call parent.
Parent::initPersistFields();
addField("fileName", TypeFilename, Offset(mFileName, ShapeAsset), "Path to the script file we want to execute");
}
void ShapeAsset::initializeAsset()
{
// Call parent.
Parent::initializeAsset();
if (dStrcmp(mFileName, "") == 0)
return;
loadShape();
}
bool ShapeAsset::loadShape()
{
mShape = ResourceManager::get().load(mFileName);
if (!mShape)
{
Con::errorf("StaticMesh::updateShape : failed to load shape file!");
return false; //if it failed to load, bail out
}
return true;
}
//------------------------------------------------------------------------------
void ShapeAsset::copyTo(SimObject* object)
{
// Call to parent.
Parent::copyTo(object);
}

View file

@ -0,0 +1,86 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2013 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHAPE_ASSET_H_
#define _SHAPE_ASSET_H_
#ifndef _ASSET_BASE_H_
#include "assets/assetBase.h"
#endif
#ifndef _ASSET_DEFINITION_H_
#include "assets/assetDefinition.h"
#endif
#ifndef _STRINGUNIT_H_
#include "string/stringUnit.h"
#endif
#ifndef _ASSET_FIELD_TYPES_H_
#include "assets/assetFieldTypes.h"
#endif
#ifndef _TSSHAPE_H_
#include "ts/tsShape.h"
#endif
#ifndef __RESOURCE_H__
#include "core/resource.h"
#endif
//-----------------------------------------------------------------------------
class ShapeAsset : public AssetBase
{
typedef AssetBase Parent;
AssetManager* mpOwningAssetManager;
bool mAssetInitialized;
AssetDefinition* mpAssetDefinition;
U32 mAcquireReferenceCount;
protected:
StringTableEntry mFileName;
Resource<TSShape> mShape;
public:
ShapeAsset();
virtual ~ShapeAsset();
/// Engine.
static void initPersistFields();
virtual void copyTo(SimObject* object);
virtual void initializeAsset();
/// Declare Console Object.
DECLARE_CONOBJECT(ShapeAsset);
bool loadShape();
TSShape* getShape() { return mShape; }
protected:
virtual void onAssetRefresh(void) {}
};
DefineConsoleType(TypeShapeAssetPtr, ShapeAsset)
#endif // _ASSET_BASE_H_

View file

@ -279,6 +279,7 @@ Camera::Camera()
mLastAbsoluteYaw = 0.0f;
mLastAbsolutePitch = 0.0f;
mLastAbsoluteRoll = 0.0f;
// For NewtonFlyMode
mNewtonRotation = false;
@ -379,6 +380,57 @@ void Camera::getCameraTransform(F32* pos, MatrixF* mat)
mat->mul( gCamFXMgr.getTrans() );
}
void Camera::getEyeCameraTransform(IDisplayDevice *displayDevice, U32 eyeId, MatrixF *outMat)
{
// The camera doesn't support a third person mode,
// so we want to override the default ShapeBase behavior.
ShapeBase * obj = dynamic_cast<ShapeBase*>(static_cast<SimObject*>(mOrbitObject));
if(obj && static_cast<ShapeBaseData*>(obj->getDataBlock())->observeThroughObject)
obj->getEyeCameraTransform(displayDevice, eyeId, outMat);
else
{
Parent::getEyeCameraTransform(displayDevice, eyeId, outMat);
}
}
DisplayPose Camera::calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose)
{
// NOTE: this is intended to be similar to updateMove
DisplayPose outPose;
outPose.orientation = EulerF(0,0,0);
outPose.position = inPose.position;
// Pitch
outPose.orientation.x = (inPose.orientation.x - mLastAbsolutePitch);
// Constrain the range of mRot.x
while (outPose.orientation.x < -M_PI_F)
outPose.orientation.x += M_2PI_F;
while (outPose.orientation.x > M_PI_F)
outPose.orientation.x -= M_2PI_F;
// Yaw
outPose.orientation.z = (inPose.orientation.z - mLastAbsoluteYaw);
// Constrain the range of mRot.z
while (outPose.orientation.z < -M_PI_F)
outPose.orientation.z += M_2PI_F;
while (outPose.orientation.z > M_PI_F)
outPose.orientation.z -= M_2PI_F;
// Bank
if (mDataBlock->cameraCanBank)
{
outPose.orientation.y = (inPose.orientation.y - mLastAbsoluteRoll);
}
// Constrain the range of mRot.y
while (outPose.orientation.y > M_PI_F)
outPose.orientation.y -= M_2PI_F;
return outPose;
}
//----------------------------------------------------------------------------
F32 Camera::getCameraFov()
@ -547,6 +599,7 @@ void Camera::processTick(const Move* move)
mLastAbsoluteYaw = emove->rotZ[emoveIndex];
mLastAbsolutePitch = emove->rotX[emoveIndex];
mLastAbsoluteRoll = emove->rotY[emoveIndex];
// Bank
mRot.y = emove->rotY[emoveIndex];

View file

@ -113,6 +113,7 @@ class Camera: public ShapeBase
F32 mLastAbsoluteYaw; ///< Stores that last absolute yaw value as passed in by ExtendedMove
F32 mLastAbsolutePitch; ///< Stores that last absolute pitch value as passed in by ExtendedMove
F32 mLastAbsoluteRoll; ///< Stores that last absolute roll value as passed in by ExtendedMove
/// @name NewtonFlyMode
/// @{
@ -235,6 +236,8 @@ class Camera: public ShapeBase
virtual void processTick( const Move* move );
virtual void interpolateTick( F32 delta);
virtual void getCameraTransform( F32* pos,MatrixF* mat );
virtual void getEyeCameraTransform( IDisplayDevice *display, U32 eyeId, MatrixF *outMat );
virtual DisplayPose calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose);
virtual void writePacketData( GameConnection* conn, BitStream* stream );
virtual void readPacketData( GameConnection* conn, BitStream* stream );

View file

@ -502,7 +502,7 @@ void ConvexShape::prepRenderImage( SceneRenderState *state )
}
*/
if ( mVertexBuffer.isNull() )
if ( mVertexBuffer.isNull() || !state)
return;
// If we don't have a material instance after the override then

View file

@ -284,6 +284,7 @@ void DecalData::unpackData( BitStream *stream )
Parent::unpackData( stream );
stream->read( &lookupName );
assignName(lookupName);
stream->read( &size );
stream->read( &materialName );
_updateMaterial();

View file

@ -1235,8 +1235,30 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
currentBatch = &batches.last();
currentBatch->startDecal = i;
currentBatch->decalCount = 1;
currentBatch->iCount = decal->mIndxCount;
currentBatch->vCount = decal->mVertCount;
// Shrink and warning: preventing a potential crash.
currentBatch->iCount =
(decal->mIndxCount > smMaxIndices) ? smMaxIndices : decal->mIndxCount;
currentBatch->vCount =
(decal->mVertCount > smMaxVerts) ? smMaxVerts : decal->mVertCount;
#ifdef TORQUE_DEBUG
// we didn't mean send a spam to the console
static U32 countMsgIndx = 0;
if ( (decal->mIndxCount > smMaxIndices) && ((countMsgIndx++ % 1024) == 0) ) {
Con::warnf(
"DecalManager::prepRenderImage() - Shrinked indices of decal."
" Lost %u.", (decal->mIndxCount - smMaxIndices)
);
}
static U32 countMsgVert = 0;
if ( (decal->mVertCount > smMaxVerts) && ((countMsgVert++ % 1024) == 0) ) {
Con::warnf(
"DecalManager::prepRenderImage() - Shrinked vertices of decal."
" Lost %u.", (decal->mVertCount - smMaxVerts)
);
}
#endif
currentBatch->mat = mat;
currentBatch->matInst = decal->mDataBlock->getMaterialInstance();
currentBatch->priority = decal->getRenderPriority();
@ -1299,15 +1321,21 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
{
DecalInstance *dinst = mDecalQueue[j];
for ( U32 k = 0; k < dinst->mIndxCount; k++ )
const U32 indxCount =
(dinst->mIndxCount > currentBatch.iCount) ?
currentBatch.iCount : dinst->mIndxCount;
for ( U32 k = 0; k < indxCount; k++ )
{
*( pbPtr + ioffset + k ) = dinst->mIndices[k] + voffset;
}
ioffset += dinst->mIndxCount;
ioffset += indxCount;
dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * dinst->mVertCount );
voffset += dinst->mVertCount;
const U32 vertCount =
(dinst->mVertCount > currentBatch.vCount) ?
currentBatch.vCount : dinst->mVertCount;
dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * vertCount );
voffset += vertCount;
// Ugly hack for ProjectedShadow!
if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL )
@ -1357,8 +1385,10 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
pb->lock( &pbPtr );
// Memcpy from system to video memory.
dMemcpy( vpPtr, vertData, sizeof( DecalVertex ) * currentBatch.vCount );
dMemcpy( pbPtr, indexData, sizeof( U16 ) * currentBatch.iCount );
const U32 vpCount = sizeof( DecalVertex ) * currentBatch.vCount;
dMemcpy( vpPtr, vertData, vpCount );
const U32 pbCount = sizeof( U16 ) * currentBatch.iCount;
dMemcpy( pbPtr, indexData, pbCount );
pb->unlock();
vb->unlock();

View file

@ -269,7 +269,7 @@ void RenderMeshExample::prepRenderImage( SceneRenderState *state )
createGeometry();
// If we have no material then skip out.
if ( !mMaterialInst )
if ( !mMaterialInst || !state)
return;
// If we don't have a material instance after the override then

View file

@ -87,6 +87,7 @@ ConsoleDocClass( GuiClockHud,
GuiClockHud::GuiClockHud()
{
mShowFrame = mShowFill = true;
mTimeReversed = false;
mFillColor.set(0, 0, 0, 0.5);
mFrameColor.set(0, 1, 0, 1);
mTextColor.set( 0, 1, 0, 1 );
@ -112,9 +113,11 @@ void GuiClockHud::initPersistFields()
void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
{
GFXDrawUtil* drawUtil = GFX->getDrawUtil();
// Background first
if (mShowFill)
GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
drawUtil->drawRectFill(updateRect, mFillColor);
// Convert ms time into hours, minutes and seconds.
S32 time = S32(getTime());
@ -128,13 +131,13 @@ void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
// Center the text
offset.x += (getWidth() - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
offset.y += (getHeight() - mProfile->mFont->getHeight()) / 2;
GFX->getDrawUtil()->setBitmapModulation(mTextColor);
GFX->getDrawUtil()->drawText(mProfile->mFont, offset, buf);
GFX->getDrawUtil()->clearBitmapModulation();
drawUtil->setBitmapModulation(mTextColor);
drawUtil->drawText(mProfile->mFont, offset, buf);
drawUtil->clearBitmapModulation();
// Border last
if (mShowFrame)
GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);
drawUtil->drawRect(updateRect, mFrameColor);
}

View file

@ -162,10 +162,12 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
else
mValue = 100 - (100 * control->getDamageValue());
}
GFXDrawUtil* drawUtil = GFX->getDrawUtil();
// If enabled draw background first
if (mShowFill)
GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
drawUtil->drawRectFill(updateRect, mFillColor);
// Prepare text and center it
S32 val = (S32)mValue;
@ -190,11 +192,11 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
}
}
GFX->getDrawUtil()->setBitmapModulation(tColor);
GFX->getDrawUtil()->drawText(mProfile->mFont, offset, buf);
GFX->getDrawUtil()->clearBitmapModulation();
drawUtil->setBitmapModulation(tColor);
drawUtil->drawText(mProfile->mFont, offset, buf);
drawUtil->clearBitmapModulation();
// If enabled draw the border last
if (mShowFrame)
GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);
drawUtil->drawRect(updateRect, mFrameColor);
}

View file

@ -117,8 +117,11 @@ GuiShapeNameHud::GuiShapeNameHud()
{
mFillColor.set( 0.25f, 0.25f, 0.25f, 0.25f );
mFrameColor.set( 0, 1, 0, 1 );
mLabelFillColor.set( 0.25f, 0.25f, 0.25f, 0.25f );
mLabelFrameColor.set( 0, 1, 0, 1 );
mTextColor.set( 0, 1, 0, 1 );
mShowFrame = mShowFill = true;
mShowLabelFrame = mShowLabelFill = false;
mVerticalOffset = 0.5f;
mDistanceFade = 0.1f;
mLabelPadding.set(0, 0);
@ -193,7 +196,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
// Collision info. We're going to be running LOS tests and we
// don't want to collide with the control object.
static U32 losMask = TerrainObjectType | ShapeBaseObjectType;
static U32 losMask = TerrainObjectType | ShapeBaseObjectType | StaticObjectType;
control->disableCollision();
// All ghosted objects are added to the server connection group,
@ -298,18 +301,20 @@ void GuiShapeNameHud::drawName(Point2I offset, const char *name, F32 opacity)
offset.x -= width / 2;
offset.y -= height / 2;
GFXDrawUtil* drawUtil = GFX->getDrawUtil();
// Background fill first
if (mShowLabelFill)
GFX->getDrawUtil()->drawRectFill(RectI(offset, extent), mLabelFillColor);
drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor);
// Deal with opacity and draw.
mTextColor.alpha = opacity;
GFX->getDrawUtil()->setBitmapModulation(mTextColor);
GFX->getDrawUtil()->drawText(mProfile->mFont, offset + mLabelPadding, name);
GFX->getDrawUtil()->clearBitmapModulation();
drawUtil->setBitmapModulation(mTextColor);
drawUtil->drawText(mProfile->mFont, offset + mLabelPadding, name);
drawUtil->clearBitmapModulation();
// Border last
if (mShowLabelFrame)
GFX->getDrawUtil()->drawRect(RectI(offset, extent), mLabelFrameColor);
drawUtil->drawRect(RectI(offset, extent), mLabelFrameColor);
}

View file

@ -254,10 +254,6 @@ ExplosionData::ExplosionData()
lifetimeVariance = 0;
offset = 0.0f;
shockwave = NULL;
shockwaveID = 0;
shockwaveOnTerrain = false;
shakeCamera = false;
camShakeFreq.set( 10.0f, 10.0f, 10.0f );
camShakeAmp.set( 1.0f, 1.0f, 1.0f );
@ -321,9 +317,6 @@ void ExplosionData::initPersistFields()
"explosion.\n\n"
"@see particleEmitter" );
// addField( "shockwave", TypeShockwaveDataPtr, Offset(shockwave, ExplosionData) );
// addField( "shockwaveOnTerrain", TypeBool, Offset(shockwaveOnTerrain, ExplosionData) );
addField( "debris", TYPEID< DebrisData >(), Offset(debrisList, ExplosionData), EC_NUM_DEBRIS_TYPES,
"List of DebrisData objects to spawn with this explosion." );
addField( "debrisThetaMin", TypeF32, Offset(debrisThetaMin, ExplosionData),

View file

@ -41,7 +41,6 @@ class ParticleEmitterData;
class TSThread;
class SFXTrack;
struct DebrisData;
class ShockwaveData;
//--------------------------------------------------------------------------
class ExplosionData : public GameBaseData {
@ -77,10 +76,6 @@ class ExplosionData : public GameBaseData {
ParticleEmitterData* emitterList[EC_NUM_EMITTERS];
S32 emitterIDList[EC_NUM_EMITTERS];
ShockwaveData * shockwave;
S32 shockwaveID;
bool shockwaveOnTerrain;
DebrisData * debrisList[EC_NUM_DEBRIS_TYPES];
S32 debrisIDList[EC_NUM_DEBRIS_TYPES];

View file

@ -248,7 +248,7 @@ fxFoliageCulledList::fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* I
//------------------------------------------------------------------------------
void fxFoliageCulledList::FindCandidates(Box3F SearchBox, fxFoliageCulledList* InVec)
void fxFoliageCulledList::FindCandidates(const Box3F& SearchBox, fxFoliageCulledList* InVec)
{
// Search the Culled List.
for (U32 i = 0; i < InVec->GetListCount(); i++)
@ -1028,7 +1028,7 @@ void fxFoliageReplicator::SetupBuffers()
//------------------------------------------------------------------------------
Box3F fxFoliageReplicator::FetchQuadrant(Box3F Box, U32 Quadrant)
Box3F fxFoliageReplicator::FetchQuadrant(const Box3F& Box, U32 Quadrant)
{
Box3F QuadrantBox;

View file

@ -86,7 +86,7 @@ public:
fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* InVec);
~fxFoliageCulledList() {};
void FindCandidates(Box3F SearchBox, fxFoliageCulledList* InVec);
void FindCandidates(const Box3F& SearchBox, fxFoliageCulledList* InVec);
U32 GetListCount(void) { return mCulledObjectSet.size(); };
fxFoliageItem* GetElement(U32 index) { return mCulledObjectSet[index]; };
@ -157,7 +157,7 @@ protected:
void SyncFoliageReplicators(void);
Box3F FetchQuadrant(Box3F Box, U32 Quadrant);
Box3F FetchQuadrant(const Box3F& Box, U32 Quadrant);
void ProcessQuadrant(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList, U32 Quadrant);
void ProcessNodeChildren(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList);

View file

@ -148,7 +148,7 @@ protected:
public:
GroundCoverCell() {}
GroundCoverCell() : mDirty(false) {}
~GroundCoverCell()
{

View file

@ -156,6 +156,7 @@ LightningStrikeEvent::LightningStrikeEvent()
{
mLightning = NULL;
mTarget = NULL;
mClientId = 0;
}
LightningStrikeEvent::~LightningStrikeEvent()

View file

@ -1293,7 +1293,7 @@ void Precipitation::interpolateTick(F32 delta)
void Precipitation::processTick(const Move *)
{
//nothing to do on the server
if (isServerObject() || mDataBlock == NULL)
if (isServerObject() || mDataBlock == NULL || isHidden())
return;
const U32 currTime = Platform::getVirtualMilliseconds();

View file

@ -39,6 +39,9 @@
#include "scene/sceneManager.h"
#define __SCENEMANAGER_H__
#endif
#ifndef _IDISPLAYDEVICE_H_
#include "platform/output/IDisplayDevice.h"
#endif
class NetConnection;
class ProcessList;
@ -418,6 +421,7 @@ public:
// Not implemented here, but should return the Camera to world transformation matrix
virtual void getCameraTransform (F32 *pos, MatrixF *mat ) { *mat = MatrixF::Identity; }
virtual void getEyeCameraTransform ( IDisplayDevice *device, U32 eyeId, MatrixF *mat ) { *mat = MatrixF::Identity; }
/// Returns the water object we are colliding with, it is up to derived
/// classes to actually set this object.

View file

@ -235,6 +235,7 @@ GameConnection::GameConnection()
GameConnection::~GameConnection()
{
setDisplayDevice(NULL);
delete mAuthInfo;
for(U32 i = 0; i < mConnectArgc; i++)
dFree(mConnectArgv[i]);
@ -459,6 +460,14 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
return false;
}
ConsoleValueRef connectArgv[MaxConnectArgs + 3];
ConsoleValue connectArgvValue[MaxConnectArgs + 3];
for(U32 i = 0; i < mConnectArgc+3; i++)
{
connectArgv[i].value = &connectArgvValue[i];
connectArgvValue[i].init();
}
for(U32 i = 0; i < mConnectArgc; i++)
{
char argString[256];
@ -466,11 +475,11 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
mConnectArgv[i] = dStrdup(argString);
connectArgv[i + 3] = mConnectArgv[i];
}
connectArgv[0] = "onConnectRequest";
connectArgv[1] = 0;
connectArgvValue[0].setStackStringValue("onConnectRequest");
connectArgvValue[1].setIntValue(0);
char buffer[256];
Net::addressToString(getNetAddress(), buffer);
connectArgv[2] = buffer;
connectArgvValue[2].setStackStringValue(buffer);
// NOTE: Cannot convert over to IMPLEMENT_CALLBACK as it has variable args.
const char *ret = Con::execute(this, mConnectArgc + 3, connectArgv);
@ -665,6 +674,30 @@ bool GameConnection::getControlCameraTransform(F32 dt, MatrixF* mat)
return true;
}
bool GameConnection::getControlCameraEyeTransforms(IDisplayDevice *display, MatrixF *transforms)
{
GameBase* obj = getCameraObject();
if(!obj)
return false;
GameBase* cObj = obj;
while((cObj = cObj->getControlObject()) != 0)
{
if(cObj->useObjsEyePoint())
obj = cObj;
}
// Perform operation on left & right eyes. For each we need to calculate the world space
// of the rotated eye offset and add that onto the camera world space.
for (U32 i=0; i<2; i++)
{
obj->getEyeCameraTransform(display, i, &transforms[i]);
}
return true;
}
bool GameConnection::getControlCameraDefaultFov(F32 * fov)
{
//find the last control object in the chain (client->player->turret->whatever...)
@ -991,8 +1024,10 @@ bool GameConnection::readDemoStartBlock(BitStream *stream)
void GameConnection::demoPlaybackComplete()
{
static ConsoleValueRef demoPlaybackArgv[1] = { "demoPlaybackComplete" };
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(1, demoPlaybackArgv, false));
static const char* demoPlaybackArgv[1] = { "demoPlaybackComplete" };
static StringStackConsoleWrapper demoPlaybackCmd(1, demoPlaybackArgv);
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(demoPlaybackCmd.argc, demoPlaybackCmd.argv, false));
Parent::demoPlaybackComplete();
}

View file

@ -269,6 +269,10 @@ public:
bool getControlCameraTransform(F32 dt,MatrixF* mat);
bool getControlCameraVelocity(Point3F *vel);
/// Returns the eye transforms for the control object, using supplemental information
/// from the provided IDisplayDevice.
bool getControlCameraEyeTransforms(IDisplayDevice *display, MatrixF *transforms);
bool getControlCameraDefaultFov(F32 *fov);
bool getControlCameraFov(F32 *fov);
bool setControlCameraFov(F32 fov);
@ -280,8 +284,8 @@ public:
void setFirstPerson(bool firstPerson);
bool hasDisplayDevice() const { return mDisplayDevice != NULL; }
const IDisplayDevice* getDisplayDevice() const { return mDisplayDevice; }
void setDisplayDevice(IDisplayDevice* display) { mDisplayDevice = display; }
IDisplayDevice* getDisplayDevice() const { return mDisplayDevice; }
void setDisplayDevice(IDisplayDevice* display) { if (mDisplayDevice) mDisplayDevice->setDrawCanvas(NULL); mDisplayDevice = display; }
void clearDisplayDevice() { mDisplayDevice = NULL; }
void setControlSchemeParameters(bool absoluteRotation, bool addYawToAbsRot, bool addPitchToAbsRot);

View file

@ -32,6 +32,7 @@
#include "app/game.h"
#include "T3D/gameBase/gameConnection.h"
#include "T3D/gameBase/gameConnectionEvents.h"
#include "console/engineAPI.h"
#define DebugChecksum 0xF00DBAAD
@ -234,7 +235,7 @@ void SimDataBlockEvent::process(NetConnection *cptr)
if(mProcess)
{
//call the console function to set the number of blocks to be sent
Con::executef("onDataBlockObjectReceived", Con::getIntArg(mIndex), Con::getIntArg(mTotal));
Con::executef("onDataBlockObjectReceived", mIndex, mTotal);
String &errorBuffer = NetConnection::getErrorBuffer();

View file

@ -349,8 +349,13 @@ bool GameProcessCameraQuery(CameraQuery *query)
// Provide some default values
query->projectionOffset = Point2F::Zero;
query->eyeOffset = Point3F::Zero;
query->stereoTargets[0] = 0;
query->stereoTargets[1] = 0;
query->eyeOffset[0] = Point3F::Zero;
query->eyeOffset[1] = Point3F::Zero;
query->hasFovPort = false;
query->hasStereoTargets = false;
F32 cameraFov = 0.0f;
bool fovSet = false;
@ -358,14 +363,14 @@ bool GameProcessCameraQuery(CameraQuery *query)
// is not open
if(!gEditingMission && connection->hasDisplayDevice())
{
const IDisplayDevice* display = connection->getDisplayDevice();
IDisplayDevice* display = connection->getDisplayDevice();
// Note: all eye values are invalid until this is called
display->setDrawCanvas(query->drawCanvas);
// The connection's display device may want to set the FOV
if(display->providesYFOV())
{
cameraFov = mRadToDeg(display->getYFOV());
fovSet = true;
}
display->setCurrentConnection(connection);
// Display may activate AFTER so we need to call this again just in case
display->onStartFrame();
// The connection's display device may want to set the projection offset
if(display->providesProjectionOffset())
@ -374,14 +379,34 @@ bool GameProcessCameraQuery(CameraQuery *query)
}
// The connection's display device may want to set the eye offset
if(display->providesEyeOffset())
if(display->providesEyeOffsets())
{
query->eyeOffset = display->getEyeOffset();
display->getEyeOffsets(query->eyeOffset);
}
// Grab field of view for both eyes
if (display->providesFovPorts())
{
display->getFovPorts(query->fovPort);
fovSet = true;
query->hasFovPort = true;
}
// Grab the latest overriding render view transforms
connection->getControlCameraEyeTransforms(display, query->eyeTransforms);
display->getStereoViewports(query->stereoViewports);
display->getStereoTargets(query->stereoTargets);
query->hasStereoTargets = true;
}
else
{
query->eyeTransforms[0] = query->cameraMatrix;
query->eyeTransforms[1] = query->cameraMatrix;
}
// Use the connection's FOV settings if requried
if(!fovSet && !connection->getControlCameraFov(&cameraFov))
if(!connection->getControlCameraFov(&cameraFov))
{
return false;
}

View file

@ -55,10 +55,6 @@ bool GameTSCtrl::onAdd()
if ( !Parent::onAdd() )
return false;
#ifdef TORQUE_DEMO_WATERMARK
mWatermark.init();
#endif
return true;
}
@ -172,10 +168,6 @@ void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect)
if(!skipRender || true)
Parent::onRender(offset, updateRect);
#ifdef TORQUE_DEMO_WATERMARK
mWatermark.render(getExtent());
#endif
}
//--------------------------------------------------------------------------

View file

@ -30,12 +30,6 @@
#include "gui/3d/guiTSControl.h"
#endif
#ifdef TORQUE_DEMO_WATERMARK
#ifndef _WATERMARK_H_
#include "demo/watermark/watermark.h"
#endif
#endif
class ProjectileData;
class GameBase;
@ -45,10 +39,6 @@ class GameTSCtrl : public GuiTSCtrl
private:
typedef GuiTSCtrl Parent;
#ifdef TORQUE_DEMO_WATERMARK
Watermark mWatermark;
#endif
void makeScriptCall(const char *func, const GuiEvent &evt) const;
public:

View file

@ -292,7 +292,7 @@ IMPLEMENT_CALLBACK( Item, onStickyCollision, void, ( const char* objID ),( objID
"@see Item, ItemData\n"
);
IMPLEMENT_CALLBACK( Item, onEnterLiquid, void, ( const char* objID, const char* waterCoverage, const char* liquidType ),( objID, waterCoverage, liquidType ),
IMPLEMENT_CALLBACK( Item, onEnterLiquid, void, ( const char* objID, F32 waterCoverage, const char* liquidType ),( objID, waterCoverage, liquidType ),
"Informs an Item object that it has entered liquid, along with information about the liquid type.\n"
"@param objID Object ID for this Item object.\n"
"@param waterCoverage How much coverage of water this Item object has.\n"
@ -1005,7 +1005,7 @@ void Item::updatePos(const U32 /*mask*/, const F32 dt)
{
if(!mInLiquid && mWaterCoverage != 0.0f)
{
onEnterLiquid_callback( getIdString(), Con::getFloatArg(mWaterCoverage), mLiquidType.c_str() );
onEnterLiquid_callback( getIdString(), mWaterCoverage, mLiquidType.c_str() );
mInLiquid = true;
}
else if(mInLiquid && mWaterCoverage == 0.0f)

View file

@ -114,7 +114,7 @@ class Item: public ShapeBase
protected:
DECLARE_CALLBACK( void, onStickyCollision, ( const char* objID ));
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objID, const char* waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objID, F32 waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onLeaveLiquid, ( const char* objID, const char* liquidType ));
public:

View file

@ -195,6 +195,7 @@ bool LightAnimData::AnimValue<COUNT>::animate( F32 time, F32 *output )
F32 scaledTime, lerpFactor, valueRange, keyFrameLerp;
U32 posFrom, posTo;
S32 keyFrameFrom, keyFrameTo;
F32 initialValue = *output;
bool wasAnimated = false;
@ -215,13 +216,13 @@ bool LightAnimData::AnimValue<COUNT>::animate( F32 time, F32 *output )
valueRange = ( value2[i] - value1[i] ) / 25.0f;
if ( !smooth[i] )
output[i] = value1[i] + ( keyFrameFrom * valueRange );
output[i] = (value1[i] + (keyFrameFrom * valueRange)) * initialValue;
else
{
lerpFactor = scaledTime - posFrom;
keyFrameLerp = ( keyFrameTo - keyFrameFrom ) * lerpFactor;
output[i] = value1[i] + ( ( keyFrameFrom + keyFrameLerp ) * valueRange );
output[i] = (value1[i] + ((keyFrameFrom + keyFrameLerp) * valueRange)) * initialValue;
}
}

View file

@ -60,6 +60,8 @@ LightBase::LightBase()
mColor( ColorF::WHITE ),
mBrightness( 1.0f ),
mCastShadows( false ),
mStaticRefreshFreq( 250 ),
mDynamicRefreshFreq( 8 ),
mPriority( 1.0f ),
mAnimationData( NULL ),
mFlareData( NULL ),
@ -90,6 +92,8 @@ void LightBase::initPersistFields()
addField( "color", TypeColorF, Offset( mColor, LightBase ), "Changes the base color hue of the light." );
addField( "brightness", TypeF32, Offset( mBrightness, LightBase ), "Adjusts the lights power, 0 being off completely." );
addField( "castShadows", TypeBool, Offset( mCastShadows, LightBase ), "Enables/disabled shadow casts by this light." );
addField( "staticRefreshFreq", TypeS32, Offset( mStaticRefreshFreq, LightBase ), "static shadow refresh rate (milliseconds)" );
addField( "dynamicRefreshFreq", TypeS32, Offset( mDynamicRefreshFreq, LightBase ), "dynamic shadow refresh rate (milliseconds)" );
addField( "priority", TypeF32, Offset( mPriority, LightBase ), "Used for sorting of lights by the light manager. "
"Priority determines if a light has a stronger effect than, those with a lower value" );
@ -277,6 +281,8 @@ U32 LightBase::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
stream->write( mBrightness );
stream->writeFlag( mCastShadows );
stream->write(mStaticRefreshFreq);
stream->write(mDynamicRefreshFreq);
stream->write( mPriority );
@ -322,6 +328,8 @@ void LightBase::unpackUpdate( NetConnection *conn, BitStream *stream )
stream->read( &mColor );
stream->read( &mBrightness );
mCastShadows = stream->readFlag();
stream->read(&mStaticRefreshFreq);
stream->read(&mDynamicRefreshFreq);
stream->read( &mPriority );
@ -431,7 +439,7 @@ DefineConsoleMethod( LightBase, playAnimation, void, (const char * anim), (""),
"existing one is played."
"@hide")
{
if ( dStrIsEmpty(anim) )
if ( String::isEmpty(anim) )
{
object->playAnimation();
return;

View file

@ -56,7 +56,8 @@ protected:
F32 mBrightness;
bool mCastShadows;
S32 mStaticRefreshFreq;
S32 mDynamicRefreshFreq;
F32 mPriority;
LightInfo *mLight;

View file

@ -36,6 +36,8 @@ LightDescription::LightDescription()
brightness( 1.0f ),
range( 5.0f ),
castShadows( false ),
mStaticRefreshFreq( 250 ),
mDynamicRefreshFreq( 8 ),
animationData( NULL ),
animationDataId( 0 ),
animationPeriod( 1.0f ),
@ -94,6 +96,8 @@ void LightDescription::initPersistFields()
addField( "brightness", TypeF32, Offset( brightness, LightDescription ), "Adjusts the lights power, 0 being off completely." );
addField( "range", TypeF32, Offset( range, LightDescription ), "Controls the size (radius) of the light" );
addField( "castShadows", TypeBool, Offset( castShadows, LightDescription ), "Enables/disabled shadow casts by this light." );
addField( "staticRefreshFreq", TypeS32, Offset( mStaticRefreshFreq, LightDescription ), "static shadow refresh rate (milliseconds)" );
addField( "dynamicRefreshFreq", TypeS32, Offset( mDynamicRefreshFreq, LightDescription ), "dynamic shadow refresh rate (milliseconds)" );
endGroup( "Light" );
@ -153,6 +157,8 @@ void LightDescription::packData( BitStream *stream )
stream->write( brightness );
stream->write( range );
stream->writeFlag( castShadows );
stream->write(mStaticRefreshFreq);
stream->write(mDynamicRefreshFreq);
stream->write( animationPeriod );
stream->write( animationPhase );
@ -181,6 +187,8 @@ void LightDescription::unpackData( BitStream *stream )
stream->read( &brightness );
stream->read( &range );
castShadows = stream->readFlag();
stream->read(&mStaticRefreshFreq);
stream->read(&mDynamicRefreshFreq);
stream->read( &animationPeriod );
stream->read( &animationPhase );
@ -200,6 +208,8 @@ void LightDescription::submitLight( LightState *state, const MatrixF &xfm, Light
li->setRange( range );
li->setColor( color );
li->setCastShadows( castShadows );
li->setStaticRefreshFreq(mStaticRefreshFreq);
li->setDynamicRefreshFreq(mDynamicRefreshFreq);
li->setTransform( xfm );
if ( animationData )

View file

@ -101,6 +101,8 @@ public:
F32 brightness;
F32 range;
bool castShadows;
S32 mStaticRefreshFreq;
S32 mDynamicRefreshFreq;
LightAnimData *animationData;
S32 animationDataId;

View file

@ -104,7 +104,7 @@ ConsoleDocClass( PathCamera,
"@ingroup PathCameras\n"
);
IMPLEMENT_CALLBACK( PathCamera, onNode, void, (const char* node), (node),
IMPLEMENT_CALLBACK( PathCamera, onNode, void, (S32 node), (node),
"A script callback that indicates the path camera has arrived at a specific node in its path. Server side only.\n"
"@param Node Unique ID assigned to this node.\n");
@ -408,7 +408,7 @@ void PathCamera::popFront()
void PathCamera::onNode(S32 node)
{
if (!isGhost())
onNode_callback(Con::getIntArg(node));
onNode_callback(node);
}

View file

@ -93,7 +93,7 @@ private:
public:
DECLARE_CONOBJECT(PathCamera);
DECLARE_CALLBACK( void, onNode, (const char* node));
DECLARE_CALLBACK( void, onNode, (S32 node));
PathCamera();
~PathCamera();

View file

@ -24,10 +24,14 @@
#define _BULLET_H_
// NOTE: We set these defines which bullet needs here.
#ifdef TORQUE_OS_WIN
#if defined TORQUE_OS_WIN && !defined(WIN32)
#define WIN32
#endif
#ifdef TORQUE_CPU_X86
#define __BT_SKIP_UINT64_H
#endif
// NOTE: All the Bullet includes we use should be here and
// nowhere else.... beware!

View file

@ -290,8 +290,9 @@ bool BtPlayer::_sweep( btVector3 *inOutCurrPos, const btVector3 &disp, Collision
BtPlayerSweepCallback callback( mGhostObject, disp.normalized() );
callback.m_collisionFilterGroup = mGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = mGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
mGhostObject->convexSweepTest( mColShape, start, end, callback, 0.0f );
if (disp.length()>0.0001)
mGhostObject->convexSweepTest( mColShape, start, end, callback, 0.0f );
inOutCurrPos->setInterpolate3( start.getOrigin(), end.getOrigin(), callback.m_closestHitFraction );
if ( callback.hasHit() )
@ -340,7 +341,8 @@ void BtPlayer::_stepForward( btVector3 *inOutCurrPos, const btVector3 &displacem
callback.m_collisionFilterGroup = mGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = mGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
mGhostObject->convexSweepTest( mColShape, start, end, callback, 0.0f );
if (disp.length()>0.0001)
mGhostObject->convexSweepTest( mColShape, start, end, callback, 0.0f );
// Subtract from the travel fraction.
fraction -= callback.m_closestHitFraction;
@ -434,9 +436,8 @@ void BtPlayer::findContact( SceneObject **contactObject,
if ( other == mGhostObject )
other = (btCollisionObject*)pair.m_pProxy1->m_clientObject;
AssertFatal( !outOverlapObjects->contains( PhysicsUserData::getObject( other->getUserPointer() ) ),
"Got multiple pairs of the same object!" );
outOverlapObjects->push_back( PhysicsUserData::getObject( other->getUserPointer() ) );
if (!outOverlapObjects->contains(PhysicsUserData::getObject(other->getUserPointer())))
outOverlapObjects->push_back( PhysicsUserData::getObject( other->getUserPointer() ) );
if ( other->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE )
continue;

View file

@ -1650,6 +1650,7 @@ Player::Player()
mLastAbsoluteYaw = 0.0f;
mLastAbsolutePitch = 0.0f;
mLastAbsoluteRoll = 0.0f;
}
Player::~Player()
@ -2608,6 +2609,7 @@ void Player::updateMove(const Move* move)
}
mLastAbsoluteYaw = emove->rotZ[emoveIndex];
mLastAbsolutePitch = emove->rotX[emoveIndex];
mLastAbsoluteRoll = emove->rotY[emoveIndex];
// Head bank
mHead.y = emove->rotY[emoveIndex];
@ -4657,9 +4659,9 @@ Point3F Player::_move( const F32 travelTime, Collision *outCol )
}
Point3F distance = end - start;
if (mFabs(distance.x) < mObjBox.len_x() &&
mFabs(distance.y) < mObjBox.len_y() &&
mFabs(distance.z) < mObjBox.len_z())
if (mFabs(distance.x) < mScaledBox.len_x() &&
mFabs(distance.y) < mScaledBox.len_y() &&
mFabs(distance.z) < mScaledBox.len_z())
{
// We can potentially early out of this. If there are no polys in the clipped polylist at our
// end position, then we can bail, and just set start = end;
@ -5584,6 +5586,57 @@ void Player::getMuzzleTransform(U32 imageSlot,MatrixF* mat)
*mat = nmat;
}
DisplayPose Player::calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose)
{
// NOTE: this is intended to be similar to updateMove
DisplayPose outPose;
outPose.orientation = getRenderTransform().toEuler();
outPose.position = inPose.position;
if (con && con->getControlSchemeAbsoluteRotation())
{
// Pitch
outPose.orientation.x = (inPose.orientation.x - mLastAbsolutePitch);
// Constrain the range of mRot.x
while (outPose.orientation.x < -M_PI_F)
outPose.orientation.x += M_2PI_F;
while (outPose.orientation.x > M_PI_F)
outPose.orientation.x -= M_2PI_F;
// Yaw
// Rotate (heading) head or body?
if ((isMounted() && getMountNode() == 0) || (con && !con->isFirstPerson()))
{
// Rotate head
outPose.orientation.z = (inPose.orientation.z - mLastAbsoluteYaw);
}
else
{
// Rotate body
outPose.orientation.z = (inPose.orientation.z - mLastAbsoluteYaw);
}
// Constrain the range of mRot.z
while (outPose.orientation.z < 0.0f)
outPose.orientation.z += M_2PI_F;
while (outPose.orientation.z > M_2PI_F)
outPose.orientation.z -= M_2PI_F;
// Bank
if (mDataBlock->cameraCanBank)
{
outPose.orientation.y = (inPose.orientation.y - mLastAbsoluteRoll);
}
// Constrain the range of mRot.y
while (outPose.orientation.y > M_PI_F)
outPose.orientation.y -= M_2PI_F;
}
return outPose;
}
void Player::getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat)
{

View file

@ -439,6 +439,7 @@ protected:
F32 mLastAbsoluteYaw; ///< Stores that last absolute yaw value as passed in by ExtendedMove
F32 mLastAbsolutePitch; ///< Stores that last absolute pitch value as passed in by ExtendedMove
F32 mLastAbsoluteRoll; ///< Stores that last absolute roll value as passed in by ExtendedMove
S32 mMountPending; ///< mMountPending suppresses tickDelay countdown so players will sit until
///< their mount, or another animation, comes through (or 13 seconds elapses).
@ -683,6 +684,7 @@ public:
void getEyeBaseTransform(MatrixF* mat, bool includeBank);
void getRenderEyeTransform(MatrixF* mat);
void getRenderEyeBaseTransform(MatrixF* mat, bool includeBank);
virtual DisplayPose calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose);
void getCameraParameters(F32 *min, F32 *max, Point3F *offset, MatrixF *rot);
void getMuzzleTransform(U32 imageSlot,MatrixF* mat);
void getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat);

View file

@ -116,6 +116,8 @@ void PointLight::_conformLights()
mLight->setBrightness( mBrightness );
mLight->setCastShadows( mCastShadows );
mLight->setStaticRefreshFreq(mStaticRefreshFreq);
mLight->setDynamicRefreshFreq(mDynamicRefreshFreq);
mLight->setPriority( mPriority );
// Update the bounds and scale to fit our light.

View file

@ -1018,7 +1018,7 @@ void Projectile::explode( const Point3F &p, const Point3F &n, const U32 collideT
// Client (impact) decal.
if ( mDataBlock->decal )
gDecalManager->addDecal(p, n, mRandF(0.0f, M_2PI_F), mDataBlock->decal);
gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
// Client object
updateSound();

View file

@ -156,7 +156,7 @@ bool Rigid::resolveCollision(const Point3F& p, const Point3F &normal, Rigid* rig
return false;
// Compute impulse
F32 d, n = -nv * (1.0f + restitution * rigid->restitution);
F32 d, n = -nv * (2.0f + restitution * rigid->restitution);
Point3F a1,b1,c1;
mCross(r1,normal,&a1);
invWorldInertia.mulV(a1,&b1);
@ -173,7 +173,7 @@ bool Rigid::resolveCollision(const Point3F& p, const Point3F &normal, Rigid* rig
applyImpulse(r1,impulse);
impulse.neg();
applyImpulse(r2,impulse);
rigid->applyImpulse(r2, impulse);
return true;
}

View file

@ -153,7 +153,7 @@ ConsoleDocClass( RigidShape,
);
IMPLEMENT_CALLBACK( RigidShape, onEnterLiquid, void, ( const char* objId, const char* waterCoverage, const char* liquidType ),
IMPLEMENT_CALLBACK( RigidShape, onEnterLiquid, void, ( const char* objId, F32 waterCoverage, const char* liquidType ),
( objId, waterCoverage, liquidType ),
"@brief Called whenever this RigidShape object enters liquid.\n\n"
"@param objId The ID of the rigidShape object.\n"
@ -1088,7 +1088,7 @@ void RigidShape::updatePos(F32 dt)
// Water script callbacks
if (!inLiquid && mWaterCoverage != 0.0f)
{
onEnterLiquid_callback(getIdString(), Con::getFloatArg(mWaterCoverage), mLiquidType.c_str() );
onEnterLiquid_callback(getIdString(), mWaterCoverage, mLiquidType.c_str() );
inLiquid = true;
}
else if (inLiquid && mWaterCoverage == 0.0f)

View file

@ -296,7 +296,7 @@ public:
void unpackUpdate(NetConnection *conn, BitStream *stream);
DECLARE_CONOBJECT(RigidShape);
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objId, const char* waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objId, F32 waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onLeaveLiquid, ( const char* objId, const char* liquidType ));
};

View file

@ -40,7 +40,6 @@
#include "scene/sceneRenderState.h"
#include "scene/sceneObjectLightingPlugin.h"
#include "T3D/fx/explosion.h"
#include "T3D/fx/particleEmitter.h"
#include "T3D/fx/cameraFXMgr.h"
#include "environment/waterBlock.h"
#include "T3D/debris.h"
@ -154,28 +153,8 @@ ShapeBaseData::ShapeBaseData()
shadowSphereAdjust( 1.0f ),
shapeName( StringTable->insert("") ),
cloakTexName( StringTable->insert("") ),
mass( 1.0f ),
drag( 0.0f ),
density( 1.0f ),
maxEnergy( 0.0f ),
maxDamage( 1.0f ),
disabledLevel( 1.0f ),
destroyedLevel( 1.0f ),
repairRate( 0.0033f ),
eyeNode( -1 ),
earNode( -1 ),
cameraNode( -1 ),
damageSequence( -1 ),
hulkSequence( -1 ),
cameraMaxDist( 0.0f ),
cameraMinDist( 0.2f ),
cameraDefaultFov( 75.0f ),
cameraMinFov( 5.0f ),
cameraMaxFov( 120.f ),
cameraCanBank( false ),
mountedImagesBank( false ),
isInvincible( false ),
renderWhenDestroyed( true ),
cubeDescId( 0 ),
reflectorDesc( NULL ),
debris( NULL ),
debrisID( 0 ),
debrisShapeName( StringTable->insert("") ),
@ -183,15 +162,35 @@ ShapeBaseData::ShapeBaseData()
explosionID( 0 ),
underwaterExplosion( NULL ),
underwaterExplosionID( 0 ),
mass( 1.0f ),
drag( 0.0f ),
density( 1.0f ),
maxEnergy( 0.0f ),
maxDamage( 1.0f ),
destroyedLevel( 1.0f ),
disabledLevel( 1.0f ),
repairRate( 0.0033f ),
eyeNode( -1 ),
earNode( -1 ),
cameraNode( -1 ),
cameraMaxDist( 0.0f ),
cameraMinDist( 0.2f ),
cameraDefaultFov( 75.0f ),
cameraMinFov( 5.0f ),
cameraMaxFov( 120.f ),
cameraCanBank( false ),
mountedImagesBank( false ),
debrisDetail( -1 ),
damageSequence( -1 ),
hulkSequence( -1 ),
observeThroughObject( false ),
firstPersonOnly( false ),
useEyePoint( false ),
cubeDescId( 0 ),
reflectorDesc( NULL ),
observeThroughObject( false ),
isInvincible( false ),
renderWhenDestroyed( true ),
computeCRC( false ),
inheritEnergyFromMount( false ),
mCRC( 0 ),
debrisDetail( -1 )
mCRC( 0 )
{
dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
}
@ -878,46 +877,46 @@ IMPLEMENT_CALLBACK( ShapeBase, validateCameraFov, F32, (F32 fov), (fov),
"@see ShapeBaseData\n\n");
ShapeBase::ShapeBase()
: mDrag( 0.0f ),
mBuoyancy( 0.0f ),
mWaterCoverage( 0.0f ),
mLiquidHeight( 0.0f ),
: mDataBlock( NULL ),
mIsAiControlled( false ),
mControllingObject( NULL ),
mGravityMod( 1.0f ),
mAppliedForce( Point3F::Zero ),
mTimeoutList( NULL ),
mDataBlock( NULL ),
mMoveMotion( false ),
mShapeBaseMount( NULL ),
mShapeInstance( NULL ),
mConvexList( new Convex ),
mEnergy( 0.0f ),
mRechargeRate( 0.0f ),
mMass( 1.0f ),
mOneOverMass( 1.0f ),
mDrag( 0.0f ),
mBuoyancy( 0.0f ),
mLiquidHeight( 0.0f ),
mWaterCoverage( 0.0f ),
mAppliedForce( Point3F::Zero ),
mGravityMod( 1.0f ),
mDamageFlash( 0.0f ),
mWhiteOut( 0.0f ),
mFlipFadeVal( false ),
mTimeoutList( NULL ),
mDamage( 0.0f ),
mRepairRate( 0.0f ),
mRepairReserve( 0.0f ),
mDamageState( Enabled ),
mDamageThread( NULL ),
mHulkThread( NULL ),
mLastRenderFrame( 0 ),
mLastRenderDistance( 0.0f ),
damageDir( 0.0f, 0.0f, 1.0f ),
mCloaked( false ),
mCloakLevel( 0.0f ),
mDamageFlash( 0.0f ),
mWhiteOut( 0.0f ),
mIsControlled( false ),
mConvexList( new Convex ),
mCameraFov( 90.0f ),
mFadeOut( true ),
mFading( false ),
mFadeVal( 1.0f ),
mFadeTime( 1.0f ),
mFadeElapsedTime( 0.0f ),
mFadeTime( 1.0f ),
mFadeDelay( 0.0f ),
mFlipFadeVal( false ),
damageDir( 0.0f, 0.0f, 1.0f ),
mShapeBaseMount( NULL ),
mMass( 1.0f ),
mOneOverMass( 1.0f ),
mMoveMotion( false ),
mIsAiControlled( false )
mCameraFov( 90.0f ),
mIsControlled( false ),
mLastRenderFrame( 0 ),
mLastRenderDistance( 0.0f )
{
mTypeMask |= ShapeBaseObjectType | LightObjectType;
@ -1192,13 +1191,13 @@ void ShapeBase::onDeleteNotify( SimObject *obj )
Parent::onDeleteNotify( obj );
}
void ShapeBase::onImpact(SceneObject* obj, VectorF vec)
void ShapeBase::onImpact(SceneObject* obj, const VectorF& vec)
{
if (!isGhost())
mDataBlock->onImpact_callback( this, obj, vec, vec.len() );
}
void ShapeBase::onImpact(VectorF vec)
void ShapeBase::onImpact(const VectorF& vec)
{
if (!isGhost())
mDataBlock->onImpact_callback( this, NULL, vec, vec.len() );
@ -1969,6 +1968,75 @@ void ShapeBase::getCameraTransform(F32* pos,MatrixF* mat)
mat->mul( gCamFXMgr.getTrans() );
}
void ShapeBase::getEyeCameraTransform(IDisplayDevice *displayDevice, U32 eyeId, MatrixF *outMat)
{
MatrixF temp(1);
Point3F eyePos;
Point3F rotEyePos;
DisplayPose inPose;
displayDevice->getFrameEyePose(&inPose, eyeId);
DisplayPose newPose = calcCameraDeltaPose(displayDevice->getCurrentConnection(), inPose);
// Ok, basically we just need to add on newPose to the camera transform
// NOTE: currently we dont support third-person camera in this mode
MatrixF cameraTransform(1);
F32 fakePos = 0;
getCameraTransform(&fakePos, &cameraTransform);
QuatF baserot = cameraTransform;
QuatF qrot = QuatF(newPose.orientation);
QuatF concatRot;
concatRot.mul(baserot, qrot);
concatRot.setMatrix(&temp);
temp.setPosition(cameraTransform.getPosition() + concatRot.mulP(newPose.position, &rotEyePos));
*outMat = temp;
}
DisplayPose ShapeBase::calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose)
{
// NOTE: this is intended to be similar to updateMove
// WARNING: does not take into account any move values
DisplayPose outPose;
outPose.orientation = getRenderTransform().toEuler();
outPose.position = inPose.position;
if (con && con->getControlSchemeAbsoluteRotation())
{
// Pitch
outPose.orientation.x = inPose.orientation.x;
// Constrain the range of mRot.x
while (outPose.orientation.x < -M_PI_F)
outPose.orientation.x += M_2PI_F;
while (outPose.orientation.x > M_PI_F)
outPose.orientation.x -= M_2PI_F;
// Yaw
outPose.orientation.z = inPose.orientation.z;
// Constrain the range of mRot.z
while (outPose.orientation.z < -M_PI_F)
outPose.orientation.z += M_2PI_F;
while (outPose.orientation.z > M_PI_F)
outPose.orientation.z -= M_2PI_F;
// Bank
if (mDataBlock->cameraCanBank)
{
outPose.orientation.y = inPose.orientation.y;
}
// Constrain the range of mRot.y
while (outPose.orientation.y > M_PI_F)
outPose.orientation.y -= M_2PI_F;
}
return outPose;
}
void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
{
*min = mDataBlock->cameraMinDist;
@ -1977,7 +2045,6 @@ void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
rot->identity();
}
//----------------------------------------------------------------------------
F32 ShapeBase::getDamageFlash() const
{

View file

@ -63,6 +63,8 @@
#include "console/dynamicTypes.h"
#endif
// Need full definition visible for SimObjectPtr<ParticleEmitter>
#include "T3D/fx/particleEmitter.h"
class GFXCubemap;
class TSShapeInstance;
@ -70,8 +72,6 @@ class SceneRenderState;
class TSThread;
class GameConnection;
struct CameraScopeQuery;
class ParticleEmitter;
class ParticleEmitterData;
class ProjectileData;
class ExplosionData;
struct DebrisData;
@ -1104,8 +1104,8 @@ protected:
virtual void shakeCamera( U32 imageSlot );
virtual void updateDamageLevel();
virtual void updateDamageState();
virtual void onImpact(SceneObject* obj, VectorF vec);
virtual void onImpact(VectorF vec);
virtual void onImpact(SceneObject* obj, const VectorF& vec);
virtual void onImpact(const VectorF& vec);
/// @}
/// The inner prep render function that does the
@ -1583,6 +1583,13 @@ public:
/// @param mat Camera transform (out)
virtual void getCameraTransform(F32* pos,MatrixF* mat);
/// Gets the view transform for a particular eye, taking into account the current absolute
/// orient and position values of the display device.
virtual void getEyeCameraTransform( IDisplayDevice *display, U32 eyeId, MatrixF *outMat );
/// Calculates a delta camera angle and view position based on inPose
virtual DisplayPose calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose);
/// Gets the index of a node inside a mounted image given the name
/// @param imageSlot Image slot
/// @param nodeName Node name

View file

@ -122,6 +122,8 @@ void SpotLight::_conformLights()
mLight->setColor( mColor );
mLight->setBrightness( mBrightness );
mLight->setCastShadows( mCastShadows );
mLight->setStaticRefreshFreq(mStaticRefreshFreq);
mLight->setDynamicRefreshFreq(mDynamicRefreshFreq);
mLight->setPriority( mPriority );
mOuterConeAngle = getMax( 0.01f, mOuterConeAngle );

View file

@ -236,7 +236,7 @@ DECLARE_STRUCT( Polyhedron );
IMPLEMENT_STRUCT( Polyhedron, Polyhedron,,
"" )
END_IMPLEMENT_STRUCT;
ConsoleType( floatList, TypeTriggerPolyhedron, Polyhedron )
ConsoleType(floatList, TypeTriggerPolyhedron, Polyhedron, "")
ConsoleGetType( TypeTriggerPolyhedron )

View file

@ -87,6 +87,10 @@ class Trigger : public GameBase
String mLeaveCommand;
String mTickCommand;
static const U32 CMD_SIZE = 1024;
protected:
enum TriggerUpdateBits
{
TransformMask = Parent::NextFreeMask << 0,
@ -97,10 +101,6 @@ class Trigger : public GameBase
NextFreeMask = Parent::NextFreeMask << 5,
};
static const U32 CMD_SIZE = 1024;
protected:
static bool smRenderTriggers;
bool testObject(GameBase* enter);
void processTick(const Move *move);
@ -142,7 +142,7 @@ class Trigger : public GameBase
// Trigger
void setTriggerPolyhedron(const Polyhedron&);
void potentialEnterObject(GameBase*);
virtual void potentialEnterObject(GameBase*);
U32 getNumTriggeringObjects() const;
GameBase* getObject(const U32);
const Vector<GameBase*>& getObjects() const { return mObjects; }

View file

@ -91,6 +91,9 @@ ConsoleDocClass( TSStatic,
);
TSStatic::TSStatic()
:
cubeDescId( 0 ),
reflectorDesc( NULL )
{
mNetFlags.set(Ghostable | ScopeAlways);
@ -102,7 +105,7 @@ TSStatic::TSStatic()
mPlayAmbient = true;
mAmbientThread = NULL;
mAllowPlayerStep = true;
mAllowPlayerStep = false;
mConvexList = new Convex;
@ -186,6 +189,11 @@ void TSStatic::initPersistFields()
endGroup("Rendering");
addGroup( "Reflection" );
addField( "cubeReflectorDesc", TypeRealString, Offset( cubeDescName, TSStatic ),
"References a ReflectorDesc datablock that defines performance and quality properties for dynamic reflections.\n");
endGroup( "Reflection" );
addGroup("Collision");
addField( "collisionType", TypeTSMeshType, Offset( mCollisionType, TSStatic ),
@ -292,6 +300,14 @@ bool TSStatic::onAdd()
addToScene();
if ( isClientObject() )
{
mCubeReflector.unregisterReflector();
if ( reflectorDesc )
mCubeReflector.registerReflector( this, reflectorDesc );
}
_updateShouldTick();
// Accumulation
@ -357,6 +373,16 @@ bool TSStatic::_createShape()
if ( mAmbientThread )
mShapeInstance->setSequence( mAmbientThread, ambientSeq, 0);
// Resolve CubeReflectorDesc.
if ( cubeDescName.isNotEmpty() )
{
Sim::findObject( cubeDescName, reflectorDesc );
}
else if( cubeDescId > 0 )
{
Sim::findObject( cubeDescId, reflectorDesc );
}
return true;
}
@ -429,6 +455,8 @@ void TSStatic::onRemove()
mShapeInstance = NULL;
mAmbientThread = NULL;
if ( isClientObject() )
mCubeReflector.unregisterReflector();
Parent::onRemove();
}
@ -561,6 +589,12 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z));
// If we're currently rendering our own reflection we
// don't want to render ourselves into it.
if ( mCubeReflector.isRendering() )
return;
if ( mForceDetail == -1 )
mShapeInstance->setDetailFromDistance( state, dist * invScale );
else
@ -577,6 +611,9 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
rdata.setFadeOverride( 1.0f );
rdata.setOriginSort( mUseOriginSort );
if ( mCubeReflector.isEnabled() )
rdata.setCubemap( mCubeReflector.getCubemap() );
// Acculumation
rdata.setAccuTex(mAccuTex);
@ -604,6 +641,20 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
mat.scale( mObjScale );
GFX->setWorldMatrix( mat );
if ( state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery() )
{
RenderPassManager *pass = state->getRenderPass();
OccluderRenderInst *ri = pass->allocInst<OccluderRenderInst>();
ri->type = RenderPassManager::RIT_Occluder;
ri->query = mCubeReflector.getOcclusionQuery();
mObjToWorld.mulP( mObjBox.getCenter(), &ri->position );
ri->scale.set( mObjBox.getExtents() );
ri->orientation = pass->allocUniqueXform( mObjToWorld );
ri->isSphere = false;
state->getRenderPass()->addInst( ri );
}
mShapeInstance->animate();
if(mShapeInstance)
{
@ -715,6 +766,10 @@ U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
if ( mLightPlugin )
retMask |= mLightPlugin->packUpdate(this, AdvancedStaticOptionsMask, con, mask, stream);
if( stream->writeFlag( reflectorDesc != NULL ) )
{
stream->writeRangedU32( reflectorDesc->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
return retMask;
}
@ -782,6 +837,11 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream)
mLightPlugin->unpackUpdate(this, con, stream);
}
if( stream->readFlag() )
{
cubeDescId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
if ( isProperlyAdded() )
_updateShouldTick();
}
@ -1171,8 +1231,10 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia
return;
}
TSMaterialList* shapeMaterialList = object->getShape()->materialList;
// Check the mapTo name exists for this shape
S32 matIndex = object->getShape()->materialList->getMaterialNameList().find_next(String(mapTo));
S32 matIndex = shapeMaterialList->getMaterialNameList().find_next(String(mapTo));
if (matIndex < 0)
{
Con::errorf("TSShape::changeMaterial failed: Invalid mapTo name '%s'", mapTo);
@ -1190,13 +1252,13 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia
// Replace instances with the new material being traded in. Lets make sure that we only
// target the specific targets per inst, this is actually doing more than we thought
delete object->getShape()->materialList->mMatInstList[matIndex];
object->getShape()->materialList->mMatInstList[matIndex] = newMat->createMatInstance();
delete shapeMaterialList->mMatInstList[matIndex];
shapeMaterialList->mMatInstList[matIndex] = newMat->createMatInstance();
// Finish up preparing the material instances for rendering
const GFXVertexFormat *flags = getGFXVertexFormat<GFXVertexPNTTB>();
FeatureSet features = MATMGR->getDefaultFeatures();
object->getShape()->materialList->getMaterialInst(matIndex)->init( features, flags );
shapeMaterialList->getMaterialInst(matIndex)->init(features, flags);
}
DefineEngineMethod( TSStatic, getModelFile, const char *, (),,

View file

@ -39,6 +39,10 @@
#include "ts/tsShape.h"
#endif
#ifndef _REFLECTOR_H_
#include "scene/reflector.h"
#endif
class TSShapeInstance;
class TSThread;
class TSStatic;
@ -147,6 +151,11 @@ protected:
/// Start or stop processing ticks depending on our state.
void _updateShouldTick();
String cubeDescName;
U32 cubeDescId;
ReflectorDesc *reflectorDesc;
CubeReflector mCubeReflector;
protected:
Convex *mConvexList;

View file

@ -1059,9 +1059,9 @@ void TurretShape::writePacketData(GameConnection *connection, BitStream *stream)
{
// Update client regardless of status flags.
Parent::writePacketData(connection, stream);
stream->write(mRot.x);
stream->write(mRot.z);
stream->writeSignedFloat(mRot.x / M_2PI_F, 7);
stream->writeSignedFloat(mRot.z / M_2PI_F, 7);
}
void TurretShape::readPacketData(GameConnection *connection, BitStream *stream)
@ -1069,9 +1069,8 @@ void TurretShape::readPacketData(GameConnection *connection, BitStream *stream)
Parent::readPacketData(connection, stream);
Point3F rot(0.0f, 0.0f, 0.0f);
stream->read(&rot.x);
stream->read(&rot.z);
rot.x = stream->readSignedFloat(7) * M_2PI_F;
rot.z = stream->readSignedFloat(7) * M_2PI_F;
_setRotation(rot);
mTurretDelta.rot = rot;
@ -1100,8 +1099,8 @@ U32 TurretShape::packUpdate(NetConnection *connection, U32 mask, BitStream *stre
if (stream->writeFlag(mask & TurretUpdateMask))
{
stream->write(mRot.x);
stream->write(mRot.z);
stream->writeSignedFloat(mRot.x / M_2PI_F, 7);
stream->writeSignedFloat(mRot.z / M_2PI_F, 7);
stream->write(allowManualRotation);
stream->write(allowManualFire);
}
@ -1137,8 +1136,8 @@ void TurretShape::unpackUpdate(NetConnection *connection, BitStream *stream)
if (stream->readFlag())
{
Point3F rot(0.0f, 0.0f, 0.0f);
stream->read(&rot.x);
stream->read(&rot.z);
rot.x = stream->readSignedFloat(7) * M_2PI_F;
rot.z = stream->readSignedFloat(7) * M_2PI_F;
_setRotation(rot);
// New delta for client side interpolation

View file

@ -1086,6 +1086,9 @@ void WheeledVehicle::updateForces(F32 dt)
if (mJetting)
mRigid.force += by * mDataBlock->jetForce;
// Add in force from physical zones...
mRigid.force += mAppliedForce;
// Container drag & buoyancy
mRigid.force += Point3F(0, 0, -mBuoyancy * sWheeledVehicleGravity * mRigid.mass);
mRigid.force -= mRigid.linVelocity * mDrag;