Merge branch 'GarageGames/master' into ueberengine-dev

This commit is contained in:
Duion 2015-10-06 23:46:47 +02:00
commit 3831cd6ccf
185 changed files with 793 additions and 328 deletions

View file

@ -60,8 +60,12 @@ NvRemoveTjunctions.cpp : A code snippet to remove tjunctions from a triangle mes
#include <vector> #include <vector>
#ifdef __APPLE__ #ifdef __APPLE__
#include <ext/hash_map> #include <ext/hash_map>
#else #elif LINUX
#include <hash_map> #include <hash_map>
#elif _MSC_VER < 1500
#include <hash_map>
#elif _MSC_VER > 1800
#include <unordered_map>
#endif #endif
#include "NvUserMemAlloc.h" #include "NvUserMemAlloc.h"
#include "NvHashMap.h" #include "NvHashMap.h"

View file

@ -450,7 +450,7 @@ long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
} }
} }
}else{ }else{
int i,j; int i;
for(i=0;i<n;){ for(i=0;i<n;){
a[i++]=0.f; a[i++]=0.f;

View file

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

View file

@ -1235,8 +1235,30 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
currentBatch = &batches.last(); currentBatch = &batches.last();
currentBatch->startDecal = i; currentBatch->startDecal = i;
currentBatch->decalCount = 1; 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->mat = mat;
currentBatch->matInst = decal->mDataBlock->getMaterialInstance(); currentBatch->matInst = decal->mDataBlock->getMaterialInstance();
currentBatch->priority = decal->getRenderPriority(); currentBatch->priority = decal->getRenderPriority();
@ -1299,15 +1321,21 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
{ {
DecalInstance *dinst = mDecalQueue[j]; 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; *( pbPtr + ioffset + k ) = dinst->mIndices[k] + voffset;
} }
ioffset += dinst->mIndxCount; ioffset += indxCount;
dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * dinst->mVertCount ); const U32 vertCount =
voffset += dinst->mVertCount; (dinst->mVertCount > currentBatch.vCount) ?
currentBatch.vCount : dinst->mVertCount;
dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * vertCount );
voffset += vertCount;
// Ugly hack for ProjectedShadow! // Ugly hack for ProjectedShadow!
if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL ) if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL )
@ -1357,8 +1385,10 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
pb->lock( &pbPtr ); pb->lock( &pbPtr );
// Memcpy from system to video memory. // Memcpy from system to video memory.
dMemcpy( vpPtr, vertData, sizeof( DecalVertex ) * currentBatch.vCount ); const U32 vpCount = sizeof( DecalVertex ) * currentBatch.vCount;
dMemcpy( pbPtr, indexData, sizeof( U16 ) * currentBatch.iCount ); dMemcpy( vpPtr, vertData, vpCount );
const U32 pbCount = sizeof( U16 ) * currentBatch.iCount;
dMemcpy( pbPtr, indexData, pbCount );
pb->unlock(); pb->unlock();
vb->unlock(); vb->unlock();

View file

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

View file

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

View file

@ -103,7 +103,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
ArrayObject::Element* ea = ( ArrayObject::Element* )( a ); ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
ArrayObject::Element* eb = ( ArrayObject::Element* )( b ); ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
S32 result = dAtoi( Con::executef( (const char*)smCompareFunction, ea->value, eb->key ) ); S32 result = dAtoi(Con::executef((const char*)smCompareFunction, ea->key, eb->key));
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 ); S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
return ( smDecreasing ? -res : res ); return ( smDecreasing ? -res : res );
} }

View file

@ -258,7 +258,6 @@ void IfStmtNode::propagateSwitchExpr(ExprNode *left, bool string)
U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip) U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
{ {
U32 start = ip;
U32 endifIp, elseIp; U32 endifIp, elseIp;
addBreakLine(codeStream); addBreakLine(codeStream);
@ -340,7 +339,6 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
addBreakLine(codeStream); addBreakLine(codeStream);
codeStream.pushFixScope(true); codeStream.pushFixScope(true);
U32 start = ip;
if(initExpr) if(initExpr)
ip = initExpr->compile(codeStream, ip, TypeReqNone); ip = initExpr->compile(codeStream, ip, TypeReqNone);
@ -1565,8 +1563,6 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
CodeBlock::smInFunction = false; CodeBlock::smInFunction = false;
U32 start = ip;
codeStream.emit(OP_FUNC_DECL); codeStream.emit(OP_FUNC_DECL);
codeStream.emitSTE(fnName); codeStream.emitSTE(fnName);
codeStream.emitSTE(nameSpace); codeStream.emitSTE(nameSpace);

View file

@ -435,7 +435,8 @@ static void setFieldComponent( SimObject* object, StringTableEntry field, const
ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame) ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
{ {
#ifdef TORQUE_DEBUG
#ifdef TORQUE_VALIDATE_STACK
U32 stackStart = STR.mStartStackSize; U32 stackStart = STR.mStartStackSize;
U32 consoleStackStart = CSTK.mStackPos; U32 consoleStackStart = CSTK.mStackPos;
#endif #endif
@ -2245,9 +2246,9 @@ execFinished:
decRefCount(); decRefCount();
#ifdef TORQUE_DEBUG #ifdef TORQUE_VALIDATE_STACK
//AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec"); AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
//AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec"); AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
#endif #endif
return returnValue; return returnValue;

View file

@ -476,7 +476,7 @@ DefineConsoleFunction( strreplace, const char*, ( const char* source, const char
if(!scan) if(!scan)
{ {
dStrcpy(ret + dstp, source + scanp); dStrcpy(ret + dstp, source + scanp);
break; return ret;
} }
U32 len = scan - (source + scanp); U32 len = scan - (source + scanp);
dStrncpy(ret + dstp, source + scanp, len); dStrncpy(ret + dstp, source + scanp, len);
@ -1594,6 +1594,7 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),,
DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"), DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"),
"Display a startup splash window suitable for showing while the engine still starts up.\n\n" "Display a startup splash window suitable for showing while the engine still starts up.\n\n"
"@note This is currently only implemented on Windows.\n\n" "@note This is currently only implemented on Windows.\n\n"
"@param path relative path to splash screen image to display.\n"
"@return True if the splash window could be successfully initialized.\n\n" "@return True if the splash window could be successfully initialized.\n\n"
"@ingroup Platform" ) "@ingroup Platform" )
{ {

View file

@ -847,12 +847,13 @@ DefineEngineFunction(linkNamespaces, bool, ( String childNSName, String parentNS
Namespace *childNS = Namespace::find(childNSSTE); Namespace *childNS = Namespace::find(childNSSTE);
Namespace *parentNS = Namespace::find(parentNSSTE); Namespace *parentNS = Namespace::find(parentNSSTE);
Namespace *currentParent = childNS->getParent();
if (!childNS) if (!childNS)
{ {
return false; return false;
} }
Namespace *currentParent = childNS->getParent();
// Link to new NS if applicable // Link to new NS if applicable

View file

@ -318,6 +318,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
DECLARE_ENUM( type ); \ DECLARE_ENUM( type ); \
DefineConsoleType( Type ## type, type ); DefineConsoleType( Type ## type, type );
#define DefineEnumType_R( type ) \
DECLARE_ENUM_R( type ); \
DefineConsoleType( Type ## type, type );
#define _ConsoleEnumType( typeName, type, nativeType ) \ #define _ConsoleEnumType( typeName, type, nativeType ) \
S32 type; \ S32 type; \
ImplementConsoleTypeCasters( type, nativeType ) \ ImplementConsoleTypeCasters( type, nativeType ) \
@ -347,6 +351,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
DECLARE_BITFIELD( type ); \ DECLARE_BITFIELD( type ); \
DefineConsoleType( Type ## type, type ); DefineConsoleType( Type ## type, type );
#define DefineBitfieldType_R( type ) \
DECLARE_BITFIELD_R( type ); \
DefineConsoleType( Type ## type, type );
#define _ConsoleBitfieldType( typeName, type, nativeType ) \ #define _ConsoleBitfieldType( typeName, type, nativeType ) \
S32 type; \ S32 type; \
ImplementConsoleTypeCasters( type, nativeType ) \ ImplementConsoleTypeCasters( type, nativeType ) \

View file

@ -34,14 +34,14 @@
DECLARE_PRIMITIVE( bool ); DECLARE_PRIMITIVE_R( bool );
DECLARE_PRIMITIVE( S8 ); DECLARE_PRIMITIVE_R(S8);
DECLARE_PRIMITIVE( U8 ); DECLARE_PRIMITIVE_R(U8);
DECLARE_PRIMITIVE( S32 ); DECLARE_PRIMITIVE_R(S32);
DECLARE_PRIMITIVE( U32 ); DECLARE_PRIMITIVE_R(U32);
DECLARE_PRIMITIVE( F32 ); DECLARE_PRIMITIVE_R(F32);
DECLARE_PRIMITIVE( F64 ); DECLARE_PRIMITIVE_R(F64);
DECLARE_PRIMITIVE( void* ); DECLARE_PRIMITIVE_R(void*);
//FIXME: this allows String to be used as a struct field type //FIXME: this allows String to be used as a struct field type
@ -52,7 +52,7 @@ DECLARE_PRIMITIVE( void* );
// are considered to be owned by the API layer itself. The rule here is that such // are considered to be owned by the API layer itself. The rule here is that such
// a string is only valid until the next API call is made. Usually, control layers // a string is only valid until the next API call is made. Usually, control layers
// will immediately copy and convert strings to their own string type. // will immediately copy and convert strings to their own string type.
_DECLARE_TYPE( String ); _DECLARE_TYPE_R(String);
template<> template<>
struct EngineTypeTraits< String > : public _EnginePrimitiveTypeTraits< String > struct EngineTypeTraits< String > : public _EnginePrimitiveTypeTraits< String >
{ {

View file

@ -41,11 +41,11 @@ class ColorI;
class ColorF; class ColorF;
DECLARE_STRUCT( Vector< bool > ); DECLARE_STRUCT_R(Vector< bool >);
DECLARE_STRUCT( Vector< S32 > ); DECLARE_STRUCT_R(Vector< S32 >);
DECLARE_STRUCT( Vector< F32 > ); DECLARE_STRUCT_R(Vector< F32 >);
DECLARE_STRUCT( Torque::UUID ); DECLARE_STRUCT_R(Torque::UUID);
DECLARE_STRUCT( ColorI ); DECLARE_STRUCT_R(ColorI);
DECLARE_STRUCT( ColorF ); DECLARE_STRUCT_R(ColorF);
#endif // !_ENGINESTRUCTS_H_ #endif // !_ENGINESTRUCTS_H_

View file

@ -44,7 +44,7 @@ enum EngineTypeKind
EngineTypeKindClass ///< Pointer to opaque EngineObject. EngineTypeKindClass ///< Pointer to opaque EngineObject.
}; };
DECLARE_ENUM( EngineTypeKind ); DECLARE_ENUM_R( EngineTypeKind );
/// Flags for an EngineTypeInfo. /// Flags for an EngineTypeInfo.
enum EngineTypeFlags enum EngineTypeFlags

View file

@ -416,6 +416,16 @@ namespace _Private {
#define _DECLARE_TYPE( type ) \ #define _DECLARE_TYPE( type ) \
template<> const EngineTypeInfo* TYPE< type >(); \
template<> struct _SCOPE< type > { \
EngineExportScope& operator()() const { \
return *static_cast< EngineExportScope* >( \
const_cast< EngineTypeInfo* >( ( TYPE< type >() ) ) \
); \
} \
};
#define _DECLARE_TYPE_R( type ) \
template<> const EngineTypeInfo* TYPE< type >(); \ template<> const EngineTypeInfo* TYPE< type >(); \
template<> struct _SCOPE< type > { \ template<> struct _SCOPE< type > { \
EngineExportScope& operator()() const { \ EngineExportScope& operator()() const { \
@ -432,22 +442,42 @@ namespace _Private {
_DECLARE_TYPE( type ) \ _DECLARE_TYPE( type ) \
template<> \ template<> \
struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {}; struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
#define _DECLARE_PRIMITIVE_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
#define _DECLARE_ENUM( type ) \ #define _DECLARE_ENUM( type ) \
_DECLARE_TYPE( type ) \ _DECLARE_TYPE( type ) \
template<> \ template<> \
struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {}; struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
#define _DECLARE_ENUM_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
#define _DECLARE_BITFIELD( type ) \ #define _DECLARE_BITFIELD( type ) \
_DECLARE_TYPE( type ) \ _DECLARE_TYPE( type ) \
template<> \ template<> \
struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {}; struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
#define _DECLARE_BITFIELD_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
#define _DECLARE_STRUCT( type ) \ #define _DECLARE_STRUCT( type ) \
_DECLARE_TYPE( type ) \ _DECLARE_TYPE( type ) \
template<> \ template<> \
struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {}; struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
#define _DECLARE_STRUCT_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
#define _IMPLEMENT_TYPE( type, exportName ) \ #define _IMPLEMENT_TYPE( type, exportName ) \
template<> \ template<> \
@ -524,6 +554,10 @@ namespace _Private {
#define DECLARE_PRIMITIVE( type ) \ #define DECLARE_PRIMITIVE( type ) \
_DECLARE_PRIMITIVE( type ) _DECLARE_PRIMITIVE( type )
///
#define DECLARE_PRIMITIVE_R( type ) \
_DECLARE_PRIMITIVE_R( type )
/// ///
#define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \ #define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \
_IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )
@ -531,11 +565,19 @@ namespace _Private {
/// ///
#define DECLARE_ENUM( type ) \ #define DECLARE_ENUM( type ) \
_DECLARE_ENUM( type ) _DECLARE_ENUM( type )
///
#define DECLARE_ENUM_R( type ) \
_DECLARE_ENUM_R( type )
/// ///
#define DECLARE_BITFIELD( type ) \ #define DECLARE_BITFIELD( type ) \
_DECLARE_BITFIELD( type ) _DECLARE_BITFIELD( type )
///
#define DECLARE_BITFIELD_R( type ) \
_DECLARE_BITFIELD_R( type )
/// ///
#define IMPLEMENT_ENUM( type, exportName, scope, doc ) \ #define IMPLEMENT_ENUM( type, exportName, scope, doc ) \
_IMPLEMENT_ENUM( type, exportName, scope, doc ) _IMPLEMENT_ENUM( type, exportName, scope, doc )
@ -556,6 +598,10 @@ namespace _Private {
#define DECLARE_STRUCT( type ) \ #define DECLARE_STRUCT( type ) \
_DECLARE_STRUCT( type ) _DECLARE_STRUCT( type )
///
#define DECLARE_STRUCT_R( type ) \
_DECLARE_STRUCT_R( type )
/// ///
#define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \ #define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \
_IMPLEMENT_STRUCT( type, exportName, scope, doc ) _IMPLEMENT_STRUCT( type, exportName, scope, doc )

View file

@ -64,7 +64,7 @@ typedef U32 SimObjectId;
enum SimObjectsConstants enum SimObjectsConstants
{ {
DataBlockObjectIdFirst = 3, DataBlockObjectIdFirst = 3,
DataBlockObjectIdBitSize = 10, DataBlockObjectIdBitSize = 14,
DataBlockObjectIdLast = DataBlockObjectIdFirst + (1 << DataBlockObjectIdBitSize) - 1, DataBlockObjectIdLast = DataBlockObjectIdFirst + (1 << DataBlockObjectIdBitSize) - 1,
MessageObjectIdFirst = DataBlockObjectIdLast + 1, MessageObjectIdFirst = DataBlockObjectIdLast + 1,

View file

@ -101,7 +101,7 @@ void Point3NormalizeValidator::validateType(SimObject *object, void *typePtr)
namespace CommonValidators namespace CommonValidators
{ {
FRangeValidator PositiveFloat(0.0f, F32_MAX); FRangeValidator PositiveFloat(0.0f, F32_MAX);
FRangeValidator PositiveNonZeroFloat(F32( POINT_EPSILON ) , F32_MAX); FRangeValidator PositiveNonZeroFloat((F32)POINT_EPSILON, F32_MAX);
FRangeValidator NormalizedFloat(0.0f, 1.0f); FRangeValidator NormalizedFloat(0.0f, 1.0f);
Point3NormalizeValidator NormalizedPoint3(1.0f); Point3NormalizeValidator NormalizedPoint3(1.0f);
}; };

View file

@ -684,13 +684,13 @@ template<class T> inline void Vector<T>::pop_back()
template<class T> inline T& Vector<T>::operator[](U32 index) template<class T> inline T& Vector<T>::operator[](U32 index)
{ {
AssertFatal(index < mElementCount, "Vector<T>::operator[] - out of bounds array access!"); AssertFatal(index < mElementCount, avar("Vector<T>::operator[%i/%i] - out of bounds array access!", index, mElementCount));
return mArray[index]; return mArray[index];
} }
template<class T> inline const T& Vector<T>::operator[](U32 index) const template<class T> inline const T& Vector<T>::operator[](U32 index) const
{ {
AssertFatal(index < mElementCount, "Vector<T>::operator[] - out of bounds array access!"); AssertFatal(index < mElementCount, avar("Vector<T>::operator[%i/%i] - out of bounds array access!", index, mElementCount));
return mArray[index]; return mArray[index];
} }

View file

@ -521,8 +521,8 @@ void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderSta
{ {
// If the camera is close to the sphere, shrink the sphere so it remains visible. // If the camera is close to the sphere, shrink the sphere so it remains visible.
GameConnection* gc = GameConnection::getConnectionToServer(); GameConnection* gc = GameConnection::getConnectionToServer();
GameBase* gb; GameBase *gb = gc ? gc->getCameraObject() : NULL;
if ( gc && (gb = gc->getCameraObject()) ) if (gb)
{ {
F32 camDist = (gb->getPosition() - getPosition()).len(); F32 camDist = (gb->getPosition() - getPosition()).len();
if ( camDist < mWindRadius ) if ( camDist < mWindRadius )

View file

@ -66,7 +66,7 @@ void GFXPCD3D9Device::createDirect3D9(LPDIRECT3D9 &d3d9, LPDIRECT3D9EX &d3d9ex)
if (pfnCreate9Ex) if (pfnCreate9Ex)
{ {
if (!FAILED(pfnCreate9Ex(D3D_SDK_VERSION, &d3d9ex)) && d3d9ex) if (d3d9ex && !FAILED(pfnCreate9Ex(D3D_SDK_VERSION, &d3d9ex)))
d3d9ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d9)); d3d9ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d9));
} }

View file

@ -568,6 +568,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
for (U32 i = 0; i < len;) for (U32 i = 0; i < len;)
{ {
U32 wide = 0;
startLine = i; startLine = i;
startLineOffset.push_back(startLine); startLineOffset.push_back(startLine);
@ -584,6 +585,10 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
else if(isValidChar(txt[i])) else if(isValidChar(txt[i]))
{ {
lineStrWidth += getCharInfo(txt[i]).xIncrement; lineStrWidth += getCharInfo(txt[i]).xIncrement;
if(txt[i] < 0) // symbols which code > 127
{
wide++; i++;
}
if( lineStrWidth > lineWidth ) if( lineStrWidth > lineWidth )
{ {
needsNewLine = true; needsNewLine = true;
@ -595,7 +600,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
if (!needsNewLine) if (!needsNewLine)
{ {
// we are done! // we are done!
lineLen.push_back(i - startLine); lineLen.push_back(i - startLine - wide);
return; return;
} }
@ -628,7 +633,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
} }
} }
lineLen.push_back(j - startLine); lineLen.push_back(j - startLine - wide);
i = j; i = j;
// Now we need to increment through any space characters at the // Now we need to increment through any space characters at the

View file

@ -14,7 +14,9 @@ public:
~GLFenceRange() ~GLFenceRange()
{ {
AssertFatal( mSync == 0, ""); //the order of creation/destruction of static variables is indetermined... depends on detail of the build
//looks like for some reason on windows + sdl + opengl the order make invalid / wrong the process TODO: Refactor -LAR
//AssertFatal( mSync == 0, "");
} }
void init(U32 start, U32 end) void init(U32 start, U32 end)
@ -87,7 +89,9 @@ public:
~GLOrderedFenceRangeManager( ) ~GLOrderedFenceRangeManager( )
{ {
waitAllRanges( ); //the order of creation/destruction of static variables is indetermined... depends on detail of the build
//looks like for some reason on windows + sdl + opengl the order make invalid / wrong the process TODO: Refactor -LAR
//waitAllRanges( );
} }
void protectOrderedRange( U32 start, U32 end ) void protectOrderedRange( U32 start, U32 end )

View file

@ -578,14 +578,12 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0); GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
const FovPort *currentFovPort = GFX->getStereoFovPort(); const FovPort *currentFovPort = GFX->getStereoFovPort();
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms(); const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
const Point3F *eyeOffset = GFX->getStereoEyeOffsets(); const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
Frustum gfxFrustum = originalFrustum;
for (U32 i=0; i<2; i++) for (U32 i=0; i<2; i++)
{ {
GFX->activateStereoTarget(i); GFX->activateStereoTarget(i);
Frustum gfxFrustum = originalFrustum;
const F32 frustumDepth = gfxFrustum.getNearDist();
MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]); MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]);
GFX->setFrustum(gfxFrustum); GFX->setFrustum(gfxFrustum);
@ -618,11 +616,11 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
F32 screenBottom = rectHeight * 0.5; F32 screenBottom = rectHeight * 0.5;
const F32 fillConv = 0.0f; const F32 fillConv = 0.0f;
const F32 frustumDepth = gfxFrustum.getNearDist() + 0.012; const F32 frustumDepthAdjusted = gfxFrustum.getNearDist() + 0.012;
verts[0].point.set( screenLeft - fillConv, frustumDepth, screenTop - fillConv ); verts[0].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenTop - fillConv );
verts[1].point.set( screenRight - fillConv, frustumDepth, screenTop - fillConv ); verts[1].point.set( screenRight - fillConv, frustumDepthAdjusted, screenTop - fillConv );
verts[2].point.set( screenLeft - fillConv, frustumDepth, screenBottom - fillConv ); verts[2].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
verts[3].point.set( screenRight - fillConv, frustumDepth, screenBottom - fillConv ); verts[3].point.set( screenRight - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255); verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);

View file

@ -128,9 +128,6 @@ bool GuiContainer::reOrder(SimObject* obj, SimObject* target)
bool GuiContainer::resize( const Point2I &newPosition, const Point2I &newExtent ) bool GuiContainer::resize( const Point2I &newPosition, const Point2I &newExtent )
{ {
RectI oldBounds = getBounds();
Point2I minExtent = getMinExtent();
if( !Parent::resize( newPosition, newExtent ) ) if( !Parent::resize( newPosition, newExtent ) )
return false; return false;

View file

@ -493,6 +493,8 @@ void GuiScrollCtrl::calcThumbs()
void GuiScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY) void GuiScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY)
{ {
scrollTo(mChildRelPos.x + deltaX, mChildRelPos.y + deltaY); scrollTo(mChildRelPos.x + deltaX, mChildRelPos.y + deltaY);
onScroll_callback();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -622,7 +622,7 @@ S32 GuiTabBookCtrl::calculatePageTabWidth( GuiTabPageCtrl *page )
const char* text = page->getText(); const char* text = page->getText();
if( !text || dStrlen(text) == 0 || mProfile->mFont == NULL ) if( !text || dStrlen(text) == 0 || mProfile == NULL || mProfile->mFont == NULL )
return mMinTabWidth; return mMinTabWidth;
GFont *font = mProfile->mFont; GFont *font = mProfile->mFont;

View file

@ -1212,7 +1212,7 @@ void GuiWindowCtrl::onMouseUp(const GuiEvent &event)
// We're either moving out of a collapse group or moving to another one // We're either moving out of a collapse group or moving to another one
// Not valid for windows not previously in a group // Not valid for windows not previously in a group
if( mCollapseGroup >= 0 && if( mCollapseGroup >= 0 &&
( snapType == -1 || ( snapType >= 0 && mCollapseGroup != hitWindow->mCollapseGroup) ) ) (snapType == -1 || (hitWindow && snapType >= 0 && mCollapseGroup != hitWindow->mCollapseGroup)))
moveFromCollapseGroup(); moveFromCollapseGroup();
// No window to connect to // No window to connect to

View file

@ -113,7 +113,10 @@ void GuiConsoleTextCtrl::onPreRender()
{ {
if ( mConsoleExpression.isNotEmpty() ) if ( mConsoleExpression.isNotEmpty() )
{ {
mResult = (const char*)Con::evaluatef( "$guiConsoleTextCtrlTemp = %s;", mConsoleExpression.c_str() ); Con::evaluatef( "$guiConsoleTextCtrlTemp = %s;", mConsoleExpression.c_str() );
//Fixes a bug with the above not always grabbing the console text.
mResult = Con::getVariable("$guiConsoleTextCtrlTemp");
// Of the resulting string we will be printing, // Of the resulting string we will be printing,
// Find the number of lines and length of each. // Find the number of lines and length of each.

View file

@ -168,7 +168,7 @@ DefineEngineMethod( GuiMLTextCtrl, scrollToTag, void, (S32 tagID),,
object->scrollToTag( tagID ); object->scrollToTag( tagID );
} }
DefineEngineMethod( GuiMLTextCtrl, scrollToTop, void, ( S32 param1, S32 param2),, DefineEngineMethod( GuiMLTextCtrl, scrollToTop, void, (),,
"@brief Scroll to the top of the text.\n\n" "@brief Scroll to the top of the text.\n\n"
"@tsexample\n" "@tsexample\n"
"// Inform GuiMLTextCtrl object to scroll to its top\n" "// Inform GuiMLTextCtrl object to scroll to its top\n"
@ -631,7 +631,7 @@ bool GuiMLTextCtrl::setCursorPosition(const S32 newPosition)
mCursorPosition = 0; mCursorPosition = 0;
return true; return true;
} }
else if (newPosition >= mTextBuffer.length()) else if (newPosition >= mTextBuffer.length() - 1)
{ {
mCursorPosition = mTextBuffer.length(); mCursorPosition = mTextBuffer.length();
return true; return true;
@ -669,11 +669,11 @@ void GuiMLTextCtrl::getCursorPositionAndColor(Point2I &cursorTop, Point2I &curso
{ {
S32 x = 0; S32 x = 0;
S32 y = 0; S32 y = 0;
S32 height = mProfile->mFont->getHeight(); S32 height = (mProfile && mProfile->mFont) ? mProfile->mFont->getHeight() : 0;
color = mProfile->mCursorColor; color = mProfile->mCursorColor;
for(Line *walk = mLineList; walk; walk = walk->next) for(Line *walk = mLineList; walk; walk = walk->next)
{ {
if ((mCursorPosition <= walk->textStart + walk->len) || (walk->next == NULL)) if ((mCursorPosition < walk->textStart + walk->len) || (walk->next == NULL))
{ {
// it's in the atoms on this line... // it's in the atoms on this line...
y = walk->y; y = walk->y;
@ -768,7 +768,7 @@ void GuiMLTextCtrl::onMouseDown(const GuiEvent& event)
mSelectionAnchorDropped = event.mousePoint; mSelectionAnchorDropped = event.mousePoint;
if (mSelectionAnchor < 0) if (mSelectionAnchor < 0)
mSelectionAnchor = 0; mSelectionAnchor = 0;
else if (mSelectionAnchor >= mTextBuffer.length()) else if (mSelectionAnchor >= mTextBuffer.length() - 1)
mSelectionAnchor = mTextBuffer.length(); mSelectionAnchor = mTextBuffer.length();
mVertMoveAnchorValid = false; mVertMoveAnchorValid = false;

View file

@ -213,7 +213,7 @@ void GuiTextEditCtrl::execConsoleCallback()
// Update the console variable: // Update the console variable:
if ( mConsoleVariable[0] ) if ( mConsoleVariable[0] )
Con::setVariable( mConsoleVariable, mTextBuffer.getPtr8() ); Con::setVariable(mConsoleVariable, mTextBuffer.getPtr8());
} }
void GuiTextEditCtrl::updateHistory( StringBuffer *inTxt, bool moveIndex ) void GuiTextEditCtrl::updateHistory( StringBuffer *inTxt, bool moveIndex )
@ -374,6 +374,8 @@ S32 GuiTextEditCtrl::calculateCursorPos( const Point2I &globalPos )
void GuiTextEditCtrl::onMouseDown( const GuiEvent &event ) void GuiTextEditCtrl::onMouseDown( const GuiEvent &event )
{ {
if(!isActive())
return;
mDragHit = false; mDragHit = false;
// If we have a double click, select all text. Otherwise // If we have a double click, select all text. Otherwise

View file

@ -604,6 +604,8 @@ void GuiControl::setUpdate()
void GuiControl::renderJustifiedText(Point2I offset, Point2I extent, const char *text) void GuiControl::renderJustifiedText(Point2I offset, Point2I extent, const char *text)
{ {
GFont *font = mProfile->mFont; GFont *font = mProfile->mFont;
if(!font)
return;
S32 textWidth = font->getStrWidthPrecise((const UTF8*)text); S32 textWidth = font->getStrWidthPrecise((const UTF8*)text);
U32 textHeight = font->getHeight(); U32 textHeight = font->getHeight();
@ -1755,41 +1757,48 @@ void GuiControl::write(Stream &stream, U32 tabStop, U32 flags)
{ {
//note: this will return false if either we, or any of our parents, are non-save controls //note: this will return false if either we, or any of our parents, are non-save controls
bool bCanSave = ( flags & IgnoreCanSave ) || ( flags & NoCheckParentCanSave && getCanSave() ) || getCanSaveParent(); bool bCanSave = ( flags & IgnoreCanSave ) || ( flags & NoCheckParentCanSave && getCanSave() ) || getCanSaveParent();
StringTableEntry steName = mAddGroup->getInternalName();
if(bCanSave && mAddGroup && (steName != NULL) && (steName != StringTable->insert("null")) && getName() ) if (bCanSave && mAddGroup)
{ {
MutexHandle handle; StringTableEntry steName = mAddGroup->getInternalName();
handle.lock(mMutex);
// export selected only? if ((steName != NULL) && (steName != StringTable->insert("null")) && getName())
if((flags & SelectedOnly) && !isSelected())
{ {
for(U32 i = 0; i < size(); i++) MutexHandle handle;
(*this)[i]->write(stream, tabStop, flags); handle.lock(mMutex);
// export selected only?
if ((flags & SelectedOnly) && !isSelected())
{
for (U32 i = 0; i < size(); i++)
(*this)[i]->write(stream, tabStop, flags);
return;
}
stream.writeTabs(tabStop);
char buffer[1024];
dSprintf(buffer, sizeof(buffer), "new %s(%s,%s) {\r\n", getClassName(), getName() ? getName() : "", mAddGroup->getInternalName());
stream.write(dStrlen(buffer), buffer);
writeFields(stream, tabStop + 1);
if (size())
{
stream.write(2, "\r\n");
for (U32 i = 0; i < size(); i++)
(*this)[i]->write(stream, tabStop + 1, flags);
}
stream.writeTabs(tabStop);
stream.write(4, "};\r\n");
return; return;
} }
stream.writeTabs(tabStop);
char buffer[1024];
dSprintf(buffer, sizeof(buffer), "new %s(%s,%s) {\r\n", getClassName(), getName() ? getName() : "", mAddGroup->getInternalName());
stream.write(dStrlen(buffer), buffer);
writeFields(stream, tabStop + 1);
if(size())
{
stream.write(2, "\r\n");
for(U32 i = 0; i < size(); i++)
(*this)[i]->write(stream, tabStop + 1, flags);
}
stream.writeTabs(tabStop);
stream.write(4, "};\r\n");
} }
else if (bCanSave)
if (bCanSave)
Parent::write( stream, tabStop, flags ); Parent::write( stream, tabStop, flags );
} }
//============================================================================= //=============================================================================

View file

@ -159,7 +159,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const ch
// console methods // console methods
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
DefineEngineMethod( GuiMenuBar, clearMenus, void, ( S32 param1, S32 param2),, DefineEngineMethod( GuiMenuBar, clearMenus, void, (),,
"@brief Clears all the menus from the menu bar.\n\n" "@brief Clears all the menus from the menu bar.\n\n"
"@tsexample\n" "@tsexample\n"
"// Inform the GuiMenuBar control to clear all menus from itself.\n" "// Inform the GuiMenuBar control to clear all menus from itself.\n"
@ -795,14 +795,14 @@ GuiMenuBar::Menu* GuiMenuBar::sCreateMenu(const char *menuText, U32 menuId)
return newMenu; return newMenu;
} }
void GuiMenuBar::addMenu(GuiMenuBar::Menu *newMenu) void GuiMenuBar::addMenu(GuiMenuBar::Menu *newMenu, S32 pos)
{ {
// add it to the menu list // add it to the menu list
menuBarDirty = true; menuBarDirty = true;
Menu **walk; if (pos == -1)
for(walk = &menuList; *walk; walk = &(*walk)->nextMenu) mMenuList.push_back(newMenu);
; else
*walk = newMenu; mMenuList.insert(pos, newMenu);
} }
void GuiMenuBar::addMenu(const char *menuText, U32 menuId) void GuiMenuBar::addMenu(const char *menuText, U32 menuId)
@ -817,16 +817,16 @@ GuiMenuBar::Menu *GuiMenuBar::findMenu(const char *menu)
if(dIsdigit(menu[0])) if(dIsdigit(menu[0]))
{ {
U32 id = dAtoi(menu); U32 id = dAtoi(menu);
for(Menu *walk = menuList; walk; walk = walk->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
if(id == walk->id) if (id == mMenuList[i]->id)
return walk; return mMenuList[i];
return NULL; return NULL;
} }
else else
{ {
for(Menu *walk = menuList; walk; walk = walk->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
if(!dStricmp(menu, walk->text)) if (!dStricmp(menu, mMenuList[i]->text))
return walk; return mMenuList[i];
return NULL; return NULL;
} }
} }
@ -854,16 +854,15 @@ void GuiMenuBar::removeMenu(Menu *menu)
{ {
menuBarDirty = true; menuBarDirty = true;
clearMenuItems(menu); clearMenuItems(menu);
for(Menu **walk = &menuList; *walk; walk = &(*walk)->nextMenu)
for (U32 i = 0; i < mMenuList.size(); ++i)
{ {
if(*walk == menu) if (mMenuList[i] == menu)
{ {
*walk = menu->nextMenu; mMenuList.erase(i);
break; break;
} }
} }
dFree(menu->text);
delete menu;
} }
void GuiMenuBar::removeMenuItem(Menu *menu, MenuItem *menuItem) void GuiMenuBar::removeMenuItem(Menu *menu, MenuItem *menuItem)
@ -945,8 +944,26 @@ void GuiMenuBar::clearMenuItems(Menu *menu)
void GuiMenuBar::clearMenus() void GuiMenuBar::clearMenus()
{ {
while(menuList) mMenuList.clear();
removeMenu(menuList); }
void GuiMenuBar::attachToMenuBar(Menu* menu, S32 pos)
{
addMenu(menu, pos);
}
void GuiMenuBar::removeFromMenuBar(Menu* menu)
{
menuBarDirty = true;
for (U32 i = 0; i < mMenuList.size(); ++i)
{
if (mMenuList[i] == menu)
{
mMenuList.erase(i);
break;
}
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1018,7 +1035,7 @@ void GuiMenuBar::addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text,
newMenuItem->checkGroup = checkGroup; newMenuItem->checkGroup = checkGroup;
newMenuItem->nextMenuItem = NULL; newMenuItem->nextMenuItem = NULL;
newMenuItem->acceleratorIndex = 0; newMenuItem->acceleratorIndex = 0;
newMenuItem->enabled = text[0] != '-'; newMenuItem->enabled = (dStrlen(text) > 1 || text[0] != '-');
newMenuItem->visible = true; newMenuItem->visible = true;
newMenuItem->bitmapIndex = -1; newMenuItem->bitmapIndex = -1;
@ -1083,7 +1100,7 @@ void GuiMenuBar::clearSubmenuItems(MenuItem *menuitem)
GuiMenuBar::GuiMenuBar() GuiMenuBar::GuiMenuBar()
{ {
menuList = NULL; mMenuList.clear();
menuBarDirty = true; menuBarDirty = true;
mouseDownMenu = NULL; mouseDownMenu = NULL;
mouseOverMenu = NULL; mouseOverMenu = NULL;
@ -1140,9 +1157,9 @@ GuiMenuBar::Menu *GuiMenuBar::findHitMenu(Point2I mousePoint)
{ {
Point2I pos = globalToLocalCoord(mousePoint); Point2I pos = globalToLocalCoord(mousePoint);
for(Menu *walk = menuList; walk; walk = walk->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
if(walk->visible && walk->bounds.pointInRect(pos)) if (mMenuList[i]->visible && mMenuList[i]->bounds.pointInRect(pos))
return walk; return mMenuList[i];
return NULL; return NULL;
} }
@ -1153,35 +1170,35 @@ void GuiMenuBar::onPreRender()
{ {
menuBarDirty = false; menuBarDirty = false;
U32 curX = mPadding; U32 curX = mPadding;
for(Menu *walk = menuList; walk; walk = walk->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
{ {
if(!walk->visible) if (!mMenuList[i]->visible)
continue; continue;
// Bounds depends on if there is a bitmap to be drawn or not // Bounds depends on if there is a bitmap to be drawn or not
if(walk->bitmapIndex == -1) if (mMenuList[i]->bitmapIndex == -1)
{ {
// Text only // Text only
walk->bounds.set(curX, 0, mProfile->mFont->getStrWidth(walk->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); mMenuList[i]->bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2));
} else } else
{ {
// Will the bitmap and text be draw? // Will the bitmap and text be draw?
if(!walk->drawBitmapOnly) if (!mMenuList[i]->drawBitmapOnly)
{ {
// Draw the bitmap and the text // Draw the bitmap and the text
RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); RectI *bitmapBounds = mProfile->mBitmapArrayRects.address();
walk->bounds.set(curX, 0, bitmapBounds[walk->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(walk->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2));
} else } else
{ {
// Only the bitmap will be drawn // Only the bitmap will be drawn
RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); RectI *bitmapBounds = mProfile->mBitmapArrayRects.address();
walk->bounds.set(curX, 0, bitmapBounds[walk->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2));
} }
} }
curX += walk->bounds.extent.x; curX += mMenuList[i]->bounds.extent.x;
} }
mouseOverMenu = NULL; mouseOverMenu = NULL;
mouseDownMenu = NULL; mouseDownMenu = NULL;
@ -1290,58 +1307,58 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
if (mProfile->mBorder) if (mProfile->mBorder)
renderBorder(ctrlRect, mProfile); renderBorder(ctrlRect, mProfile);
for(Menu *walk = menuList; walk; walk = walk->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
{ {
if(!walk->visible) if (!mMenuList[i]->visible)
continue; continue;
ColorI fontColor = mProfile->mFontColor; ColorI fontColor = mProfile->mFontColor;
RectI bounds = walk->bounds; RectI bounds = mMenuList[i]->bounds;
bounds.point += offset; bounds.point += offset;
Point2I start; Point2I start;
start.x = walk->bounds.point.x + mHorizontalMargin; start.x = mMenuList[i]->bounds.point.x + mHorizontalMargin;
start.y = walk->bounds.point.y + ( walk->bounds.extent.y - mProfile->mFont->getHeight() ) / 2; start.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - mProfile->mFont->getHeight()) / 2;
// Draw the border // Draw the border
if(walk->drawBorder) if (mMenuList[i]->drawBorder)
{ {
RectI highlightBounds = bounds; RectI highlightBounds = bounds;
highlightBounds.inset(1,1); highlightBounds.inset(1,1);
if(walk == mouseDownMenu) if (mMenuList[i] == mouseDownMenu)
renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL ); renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL );
else if(walk == mouseOverMenu && mouseDownMenu == NULL) else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL)
renderFilledBorder(highlightBounds, mProfile->mBorderColor, mProfile->mFillColor ); renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL);
} }
// Do we draw a bitmap? // Do we draw a bitmap?
if(walk->bitmapIndex != -1) if (mMenuList[i]->bitmapIndex != -1)
{ {
S32 index = walk->bitmapIndex * 3; S32 index = mMenuList[i]->bitmapIndex * 3;
if(walk == mouseDownMenu) if (mMenuList[i] == mouseDownMenu)
++index; ++index;
else if(walk == mouseOverMenu && mouseDownMenu == NULL) else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL)
index += 2; index += 2;
RectI rect = mProfile->mBitmapArrayRects[index]; RectI rect = mProfile->mBitmapArrayRects[index];
Point2I bitmapstart(start); Point2I bitmapstart(start);
bitmapstart.y = walk->bounds.point.y + ( walk->bounds.extent.y - rect.extent.y ) / 2; bitmapstart.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - rect.extent.y) / 2;
drawUtil->clearBitmapModulation(); drawUtil->clearBitmapModulation();
drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect); drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect);
// Should we also draw the text? // Should we also draw the text?
if(!walk->drawBitmapOnly) if (!mMenuList[i]->drawBitmapOnly)
{ {
start.x += mBitmapMargin; start.x += mBitmapMargin;
drawUtil->setBitmapModulation( fontColor ); drawUtil->setBitmapModulation( fontColor );
drawUtil->drawText( mProfile->mFont, start + offset, walk->text, mProfile->mFontColors ); drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors);
} }
} else } else
{ {
drawUtil->setBitmapModulation( fontColor ); drawUtil->setBitmapModulation( fontColor );
drawUtil->drawText( mProfile->mFont, start + offset, walk->text, mProfile->mFontColors ); drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors);
} }
} }
@ -1354,9 +1371,9 @@ void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator
// add all our keys: // add all our keys:
mCurAcceleratorIndex = 1; mCurAcceleratorIndex = 1;
for(Menu *menu = menuList; menu; menu = menu->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
{ {
for(MenuItem *item = menu->firstMenuItem; item; item = item->nextMenuItem) for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem)
{ {
if(!item->accelerator) if(!item->accelerator)
{ {
@ -1384,20 +1401,20 @@ void GuiMenuBar::acceleratorKeyPress(U32 index)
{ {
// loop through all the menus // loop through all the menus
// and find the item that corresponds to the accelerator index // and find the item that corresponds to the accelerator index
for(Menu *menu = menuList; menu; menu = menu->nextMenu) for (U32 i = 0; i < mMenuList.size(); ++i)
{ {
if(!menu->visible) if (!mMenuList[i]->visible)
continue; continue;
for(MenuItem *item = menu->firstMenuItem; item; item = item->nextMenuItem) for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem)
{ {
if(item->acceleratorIndex == index) if(item->acceleratorIndex == index)
{ {
// first, call the script callback for menu selection: // first, call the script callback for menu selection:
onMenuSelect_callback(menu->id, menu->text); onMenuSelect_callback(mMenuList[i]->id, mMenuList[i]->text);
if(item->visible) if(item->visible)
menuItemSelected(menu, item); menuItemSelected(mMenuList[i], item);
return; return;
} }
} }

View file

@ -133,7 +133,7 @@ public:
GuiSubmenuBackgroundCtrl *mSubmenuBackground; // Background for a submenu GuiSubmenuBackgroundCtrl *mSubmenuBackground; // Background for a submenu
GuiMenuTextListCtrl *mSubmenuTextList; // Text list for a submenu GuiMenuTextListCtrl *mSubmenuTextList; // Text list for a submenu
Menu *menuList; Vector<Menu*> mMenuList;
Menu *mouseDownMenu; Menu *mouseDownMenu;
Menu *mouseOverMenu; Menu *mouseOverMenu;
@ -164,7 +164,7 @@ public:
// internal menu handling functions // internal menu handling functions
// these are used by the script manipulation functions to add/remove/change menu items // these are used by the script manipulation functions to add/remove/change menu items
static Menu* sCreateMenu(const char *menuText, U32 menuId); static Menu* sCreateMenu(const char *menuText, U32 menuId);
void addMenu(Menu *menu); void addMenu(Menu *menu, S32 pos = -1);
void addMenu(const char *menuText, U32 menuId); void addMenu(const char *menuText, U32 menuId);
Menu *findMenu(const char *menu); // takes either a menu text or a string id Menu *findMenu(const char *menu); // takes either a menu text or a string id
static MenuItem *findMenuItem(Menu *menu, const char *menuItem); // takes either a menu text or a string id static MenuItem *findMenuItem(Menu *menu, const char *menuItem); // takes either a menu text or a string id
@ -175,6 +175,9 @@ public:
static void clearMenuItems(Menu *menu); static void clearMenuItems(Menu *menu);
void clearMenus(); void clearMenus();
void attachToMenuBar(Menu* menu, S32 pos = -1);
void removeFromMenuBar(Menu* menu);
// Methods to deal with submenus // Methods to deal with submenus
static MenuItem* findSubmenuItem(Menu *menu, const char *menuItem, const char *submenuItem); static MenuItem* findSubmenuItem(Menu *menu, const char *menuItem, const char *submenuItem);
static MenuItem* findSubmenuItem(MenuItem *menuItem, const char *submenuItem); static MenuItem* findSubmenuItem(MenuItem *menuItem, const char *submenuItem);

View file

@ -1608,6 +1608,8 @@ void GuiShapeEdPreview::renderNodes() const
void GuiShapeEdPreview::renderNodeAxes(S32 index, const ColorF& nodeColor) const void GuiShapeEdPreview::renderNodeAxes(S32 index, const ColorF& nodeColor) const
{ {
if(mModel->mNodeTransforms.size() <= index || index < 0)
return;
const Point3F xAxis( 1.0f, 0.15f, 0.15f ); const Point3F xAxis( 1.0f, 0.15f, 0.15f );
const Point3F yAxis( 0.15f, 1.0f, 0.15f ); const Point3F yAxis( 0.15f, 1.0f, 0.15f );
const Point3F zAxis( 0.15f, 0.15f, 1.0f ); const Point3F zAxis( 0.15f, 0.15f, 1.0f );
@ -1631,6 +1633,8 @@ void GuiShapeEdPreview::renderNodeAxes(S32 index, const ColorF& nodeColor) const
void GuiShapeEdPreview::renderNodeName(S32 index, const ColorF& textColor) const void GuiShapeEdPreview::renderNodeName(S32 index, const ColorF& textColor) const
{ {
if(index < 0 || index >= mModel->getShape()->nodes.size() || index >= mProjectedNodes.size())
return;
const TSShape::Node& node = mModel->getShape()->nodes[index]; const TSShape::Node& node = mModel->getShape()->nodes[index];
const String& nodeName = mModel->getShape()->getName( node.nameIndex ); const String& nodeName = mModel->getShape()->getName( node.nameIndex );

View file

@ -46,7 +46,7 @@ ConsoleDocClass( GuiMouseEventCtrl,
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDown, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDown, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse is pressed down while in this control.\n\n" "@brief Callback that occurs whenever the mouse is pressed down while in this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -70,7 +70,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDown, void, ( U8 modifier, Point2I
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseUp, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseUp, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse is released while in this control.\n\n" "@brief Callback that occurs whenever the mouse is released while in this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -94,7 +94,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseUp, void, ( U8 modifier, Point2I m
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseMove, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseMove, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse is moved (without dragging) while in this control.\n\n" "@brief Callback that occurs whenever the mouse is moved (without dragging) while in this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -118,7 +118,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseMove, void, ( U8 modifier, Point2I
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDragged, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDragged, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse is dragged while in this control.\n\n" "@brief Callback that occurs whenever the mouse is dragged while in this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -142,7 +142,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDragged, void, ( U8 modifier, Poi
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseEnter, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseEnter, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse enters this control.\n\n" "@brief Callback that occurs whenever the mouse enters this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -166,7 +166,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseEnter, void, ( U8 modifier, Point
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseLeave, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseLeave, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse leaves this control.\n\n" "@brief Callback that occurs whenever the mouse leaves this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -190,7 +190,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseLeave, void, ( U8 modifier, Point
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDown, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDown, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the right mouse button is pressed while in this control.\n\n" "@brief Callback that occurs whenever the right mouse button is pressed while in this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -214,7 +214,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDown, void, ( U8 modifier, P
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseUp, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseUp, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the right mouse button is released while in this control.\n\n" "@brief Callback that occurs whenever the right mouse button is released while in this control.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -238,7 +238,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseUp, void, ( U8 modifier, Poi
"@see GuiControl\n\n" "@see GuiControl\n\n"
); );
IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDragged, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ), IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDragged, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
( modifier, mousePoint, mouseClickCount ), ( modifier, mousePoint, mouseClickCount ),
"@brief Callback that occurs whenever the mouse is dragged in this control while the right mouse button is pressed.\n\n" "@brief Callback that occurs whenever the mouse is dragged in this control while the right mouse button is pressed.\n\n"
"@param modifier Key that was pressed during this callback. Values are:\n\n" "@param modifier Key that was pressed during this callback. Values are:\n\n"
@ -270,11 +270,6 @@ GuiMouseEventCtrl::GuiMouseEventCtrl()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void GuiMouseEventCtrl::sendMouseEvent(const char * name, const GuiEvent & event) void GuiMouseEventCtrl::sendMouseEvent(const char * name, const GuiEvent & event)
{ {
char buf[3][32];
dSprintf(buf[0], 32, "%d", event.modifier);
dSprintf(buf[1], 32, "%d %d", event.mousePoint.x, event.mousePoint.y);
dSprintf(buf[2], 32, "%d", event.mouseClickCount);
if(dStricmp(name,"onMouseDown") == 0) if(dStricmp(name,"onMouseDown") == 0)
onMouseDown_callback(event.modifier, event.mousePoint, event.mouseClickCount); onMouseDown_callback(event.modifier, event.mousePoint, event.mouseClickCount);
else if(dStricmp(name,"onMouseUp") == 0) else if(dStricmp(name,"onMouseUp") == 0)

View file

@ -41,15 +41,15 @@ class GuiMouseEventCtrl : public GuiControl
GuiMouseEventCtrl(); GuiMouseEventCtrl();
DECLARE_CALLBACK( void, onMouseDown, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onMouseDown, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onMouseUp, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onMouseUp, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onMouseMove, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onMouseMove, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onMouseDragged, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onMouseDragged, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onMouseEnter, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onMouseEnter, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onMouseLeave, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onMouseLeave, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onRightMouseDown, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onRightMouseDown, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onRightMouseUp, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onRightMouseUp, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onRightMouseDragged, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount )); DECLARE_CALLBACK( void, onRightMouseDragged, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
// GuiControl // GuiControl
void onMouseDown(const GuiEvent & event); void onMouseDown(const GuiEvent & event);

View file

@ -2655,7 +2655,7 @@ void WorldEditor::renderScene( const RectI &updateRect )
// Probably should test the entire icon screen-rect instead of just the centerpoint // Probably should test the entire icon screen-rect instead of just the centerpoint
// but would need to move some code from renderScreenObj to here. // but would need to move some code from renderScreenObj to here.
if ( mDragSelect ) if (mDragSelect && selection)
if ( mDragRect.pointInRect(sPosI) && !selection->objInSet(obj) ) if ( mDragRect.pointInRect(sPosI) && !selection->objInSet(obj) )
mDragSelected->addObject(obj); mDragSelected->addObject(obj);

View file

@ -396,11 +396,9 @@ void ProcessedShaderMaterial::_determineFeatures( U32 stageNum,
// cannot do on SM 2.0 and below. // cannot do on SM 2.0 and below.
if ( shaderVersion > 2.0f ) if ( shaderVersion > 2.0f )
{ {
// Only allow parallax if we have a normal map and
// we're not using DXTnm compression.
if ( mMaterial->mParallaxScale[stageNum] > 0.0f && if ( mMaterial->mParallaxScale[stageNum] > 0.0f &&
fd.features[ MFT_NormalMap ] && fd.features[ MFT_NormalMap ] )
!fd.features[ MFT_IsDXTnm ] )
fd.features.addFeature( MFT_Parallax ); fd.features.addFeature( MFT_Parallax );
// If not parallax then allow per-pixel specular if // If not parallax then allow per-pixel specular if

View file

@ -163,7 +163,7 @@ EulerF MatrixF::toEuler() const
const F32 * mat = m; const F32 * mat = m;
EulerF r; EulerF r;
r.x = mAsin(mat[MatrixF::idx(2,1)]); r.x = mAsin(mClampF(mat[MatrixF::idx(2,1)], -1.0, 1.0));
if(mCos(r.x) != 0.f) if(mCos(r.x) != 0.f)
{ {

View file

@ -233,11 +233,13 @@ class Point3D
bool isZero() const; bool isZero() const;
F64 len() const; F64 len() const;
F64 lenSquared() const; F64 lenSquared() const;
F64 magnitudeSafe() const;
//-------------------------------------- Mathematical mutators //-------------------------------------- Mathematical mutators
public: public:
void neg(); void neg();
void normalize(); void normalize();
void normalizeSafe();
void normalize(F64 val); void normalize(F64 val);
void convolve(const Point3D&); void convolve(const Point3D&);
void convolveInverse(const Point3D&); void convolveInverse(const Point3D&);
@ -728,11 +730,13 @@ inline Point3F& Point3F::operator*=(const Point3F &_vec)
inline Point3F Point3F::operator/(const Point3F &_vec) const inline Point3F Point3F::operator/(const Point3F &_vec) const
{ {
AssertFatal(_vec.x != 0.0f && _vec.y != 0.0f && _vec.z != 0.0f, "Error, div by zero attempted");
return Point3F(x / _vec.x, y / _vec.y, z / _vec.z); return Point3F(x / _vec.x, y / _vec.y, z / _vec.z);
} }
inline Point3F& Point3F::operator/=(const Point3F &_vec) inline Point3F& Point3F::operator/=(const Point3F &_vec)
{ {
AssertFatal(_vec.x != 0.0f && _vec.y != 0.0f && _vec.z != 0.0f, "Error, div by zero attempted");
x /= _vec.x; x /= _vec.x;
y /= _vec.y; y /= _vec.y;
z /= _vec.z; z /= _vec.z;
@ -855,7 +859,8 @@ inline F64 Point3D::lenSquared() const
inline F64 Point3D::len() const inline F64 Point3D::len() const
{ {
return mSqrtD(x*x + y*y + z*z); F64 temp = x*x + y*y + z*z;
return (temp > 0.0) ? mSqrtD(temp) : 0.0;
} }
inline void Point3D::normalize() inline void Point3D::normalize()
@ -863,6 +868,28 @@ inline void Point3D::normalize()
m_point3D_normalize(*this); m_point3D_normalize(*this);
} }
inline F64 Point3D::magnitudeSafe() const
{
if( isZero() )
{
return 0.0;
}
else
{
return len();
}
}
inline void Point3D::normalizeSafe()
{
F64 vmag = magnitudeSafe();
if( vmag > POINT_EPSILON )
{
*this *= F64(1.0 / vmag);
}
}
inline void Point3D::normalize(F64 val) inline void Point3D::normalize(F64 val)
{ {
m_point3D_normalize_f(*this, val); m_point3D_normalize_f(*this, val);

View file

@ -32,33 +32,48 @@ const QuatF QuatF::Identity(0.0f,0.0f,0.0f,1.0f);
QuatF& QuatF::set( const EulerF & e ) QuatF& QuatF::set( const EulerF & e )
{ {
F32 cx, sx; /*
F32 cy, sy; F32 cx, sx;
F32 cz, sz; F32 cy, sy;
mSinCos( e.x * 0.5f, sx, cx ); F32 cz, sz;
mSinCos( e.y * 0.5f, sy, cy ); mSinCos( -e.x * 0.5f, sx, cx );
mSinCos( e.z * 0.5f, sz, cz ); mSinCos( -e.y * 0.5f, sy, cy );
mSinCos( -e.z * 0.5f, sz, cz );
// Qyaw(z) = [ (0, 0, sin z/2), cos z/2 ] // Qyaw(z) = [ (0, 0, sin z/2), cos z/2 ]
// Qpitch(x) = [ (sin x/2, 0, 0), cos x/2 ] // Qpitch(x) = [ (sin x/2, 0, 0), cos x/2 ]
// Qroll(y) = [ (0, sin y/2, 0), cos y/2 ] // Qroll(y) = [ (0, sin y/2, 0), cos y/2 ]
// this = Qresult = Qyaw*Qpitch*Qroll ZXY // this = Qresult = Qyaw*Qpitch*Qroll ZXY
// //
// The code that folows is a simplification of: // The code that folows is a simplification of:
// roll*=pitch; // roll*=pitch;
// roll*=yaw; // roll*=yaw;
// *this = roll; // *this = roll;
F32 cycz, sysz, sycz, cysz; F32 cycz, sysz, sycz, cysz;
cycz = cy*cz; cycz = cy*cz;
sysz = sy*sz; sysz = sy*sz;
sycz = sy*cz; sycz = sy*cz;
cysz = cy*sz; cysz = cy*sz;
w = cycz*cx - sysz*sx; w = cycz*cx + sysz*sx;
x = cycz*sx + sysz*cx; x = cycz*sx + sysz*cx;
y = sycz*cx + cysz*sx; y = sycz*cx - cysz*sx;
z = cysz*cx - sycz*sx; z = cysz*cx - sycz*sx;
*/
// Assuming the angles are in radians.
F32 c1 = mCos(e.y * 0.5f);
F32 s1 = mSin(e.y * 0.5f);
F32 c2 = mCos(e.z * 0.5f);
F32 s2 = mSin(e.z * 0.5f);
F32 c3 = mCos(e.x * 0.5f);
F32 s3 = mSin(e.x * 0.5f);
F32 c1c2 = c1*c2;
F32 s1s2 = s1*s2;
w =c1c2*c3 - s1s2*s3;
x =c1c2*s3 + s1s2*c3;
y =s1*c2*c3 + c1*s2*s3;
z =c1*s2*c3 - s1*c2*s3;
return *this; return *this;
} }
QuatF& QuatF::operator *=( const QuatF & b ) QuatF& QuatF::operator *=( const QuatF & b )
@ -289,7 +304,7 @@ QuatF & QuatF::interpolate( const QuatF & q1, const QuatF & q2, F32 t )
return *this; return *this;
} }
Point3F & QuatF::mulP(const Point3F& p, Point3F* r) Point3F & QuatF::mulP(const Point3F& p, Point3F* r) const
{ {
QuatF qq; QuatF qq;
QuatF qi = *this; QuatF qi = *this;

View file

@ -81,7 +81,7 @@ public:
QuatF& interpolate( const QuatF & q1, const QuatF & q2, F32 t ); QuatF& interpolate( const QuatF & q1, const QuatF & q2, F32 t );
F32 angleBetween( const QuatF & q ); F32 angleBetween( const QuatF & q );
Point3F& mulP(const Point3F& a, Point3F* b); // r = p * this Point3F& mulP(const Point3F& a, Point3F* r) const; // r = p * this
QuatF& mul(const QuatF& a, const QuatF& b); // This = a * b QuatF& mul(const QuatF& a, const QuatF& b); // This = a * b
// Vectors passed in must be normalized // Vectors passed in must be normalized

View file

@ -88,13 +88,13 @@ void MRandomLCG::setSeed(S32 s)
U32 MRandomLCG::randI() U32 MRandomLCG::randI()
{ {
if ( mSeed <= msQuotient ) if ( mSeed <= msQuotient )
mSeed = (mSeed * 16807L) % S32_MAX; mSeed = (mSeed * 16807) % S32_MAX;
else else
{ {
S32 high_part = mSeed / msQuotient; S32 high_part = mSeed / msQuotient;
S32 low_part = mSeed % msQuotient; S32 low_part = mSeed % msQuotient;
S32 test = (16807L * low_part) - (msRemainder * high_part); S32 test = (16807 * low_part) - (msRemainder * high_part);
if ( test > 0 ) if ( test > 0 )
mSeed = test; mSeed = test;

View file

@ -54,7 +54,7 @@ public:
inline F32 MRandomGenerator::randF() inline F32 MRandomGenerator::randF()
{ {
// default: multiply by 1/(2^31) // default: multiply by 1/(2^31)
return F32(randI()) * (1.0f/2147483647.0f); return F32(randI()) * (1.0f / S32_MAX);
} }
inline S32 MRandomGenerator::randI(S32 i, S32 n) inline S32 MRandomGenerator::randI(S32 i, S32 n)

View file

@ -77,8 +77,11 @@ bool SphereF::intersectsRay( const Point3F &start, const Point3F &end ) const
// value for getting the exact // value for getting the exact
// intersection point, by interpolating // intersection point, by interpolating
// start to end by t. // start to end by t.
/*
F32 t = 0; F32 t = 0;
TORQUE_UNUSED(t); TORQUE_UNUSED(t);
*/
// if t1 is less than zero, the object is in the ray's negative direction // if t1 is less than zero, the object is in the ray's negative direction
// and consequently the ray misses the sphere // and consequently the ray misses the sphere

View file

@ -308,7 +308,6 @@ void GuiNavEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
U8 keys = Input::getModifierKeys(); U8 keys = Input::getModifierKeys();
bool shift = keys & SI_LSHIFT; bool shift = keys & SI_LSHIFT;
bool ctrl = keys & SI_LCTRL; bool ctrl = keys & SI_LCTRL;
bool alt = keys & SI_LALT;
if(mMode == mLinkMode && !mMesh.isNull()) if(mMode == mLinkMode && !mMesh.isNull())
{ {

View file

@ -44,6 +44,20 @@ public:
mResults[mIndex] = mIndex; mResults[mIndex] = mIndex;
} }
}; };
// A worker that delays for some time. We'll use this to test the ThreadPool's
// synchronous and asynchronous operations.
struct DelayItem : public ThreadPool::WorkItem
{
U32 ms;
DelayItem(U32 _ms) : ms(_ms) {}
protected:
virtual void execute()
{
Platform::sleep(ms);
}
};
}; };
TEST_FIX(ThreadPool, BasicAPI) TEST_FIX(ThreadPool, BasicAPI)
@ -63,8 +77,7 @@ TEST_FIX(ThreadPool, BasicAPI)
pool->queueWorkItem(item); pool->queueWorkItem(item);
} }
// Wait for all items to complete. pool->waitForAllItems();
pool->flushWorkItems();
// Verify. // Verify.
for (U32 i = 0; i < numItems; i++) for (U32 i = 0; i < numItems; i++)
@ -72,4 +85,37 @@ TEST_FIX(ThreadPool, BasicAPI)
results.clear(); results.clear();
} }
TEST_FIX(ThreadPool, Asynchronous)
{
const U32 delay = 500; //ms
// Launch a single delaying work item.
ThreadPool* pool = &ThreadPool::GLOBAL();
ThreadSafeRef<DelayItem> item(new DelayItem(delay));
pool->queueWorkItem(item);
// The thread should not yet be finished.
EXPECT_EQ(false, item->hasExecuted());
// Wait til the item should have completed.
Platform::sleep(delay * 2);
EXPECT_EQ(true, item->hasExecuted());
}
TEST_FIX(ThreadPool, Synchronous)
{
const U32 delay = 500; //ms
// Launch a single delaying work item.
ThreadPool* pool = &ThreadPool::GLOBAL();
ThreadSafeRef<DelayItem> item(new DelayItem(delay));
pool->queueWorkItem(item);
// Wait for the item to complete.
pool->waitForAllItems();
EXPECT_EQ(true, item->hasExecuted());
}
#endif #endif

View file

@ -120,6 +120,7 @@ void ThreadPool::Context::updateAccumulatedPriorityBiases()
void ThreadPool::WorkItem::process() void ThreadPool::WorkItem::process()
{ {
execute(); execute();
mExecuted = true;
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -281,6 +282,8 @@ void ThreadPool::WorkerThread::run( void* arg )
Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' takes item '0x%x'", getId(), *workItem ); Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' takes item '0x%x'", getId(), *workItem );
#endif #endif
workItem->process(); workItem->process();
dFetchAndAdd( mPool->mNumPendingItems, ( U32 ) -1 );
} }
else else
waitForSignal = true; waitForSignal = true;
@ -318,6 +321,7 @@ ThreadPool::ThreadPool( const char* name, U32 numThreads )
: mName( name ), : mName( name ),
mNumThreads( numThreads ), mNumThreads( numThreads ),
mNumThreadsAwake( 0 ), mNumThreadsAwake( 0 ),
mNumPendingItems( 0 ),
mThreads( 0 ), mThreads( 0 ),
mSemaphore( 0 ) mSemaphore( 0 )
{ {
@ -409,7 +413,7 @@ void ThreadPool::queueWorkItem( WorkItem* item )
else else
{ {
// Put the item in the queue. // Put the item in the queue.
dFetchAndAdd( mNumPendingItems, 1 );
mWorkItemQueue.insert( item->getPriority(), item ); mWorkItemQueue.insert( item->getPriority(), item );
mSemaphore.release(); mSemaphore.release();
@ -440,6 +444,26 @@ void ThreadPool::flushWorkItems( S32 timeOut )
} }
} }
void ThreadPool::waitForAllItems( S32 timeOut )
{
U32 endTime = 0;
if( timeOut != -1 )
endTime = Platform::getRealMilliseconds() + timeOut;
// Spinlock until there are no items that have not been processed.
while( dAtomicRead( mNumPendingItems ) )
{
Platform::sleep( 25 );
// Stop if we have exceeded our processing time budget.
if( timeOut != -1
&& Platform::getRealMilliseconds() >= endTime )
break;
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void ThreadPool::queueWorkItemOnMainThread( WorkItem* item ) void ThreadPool::queueWorkItemOnMainThread( WorkItem* item )

View file

@ -194,6 +194,9 @@ class ThreadPool
/// This is the primary function to implement by subclasses. /// This is the primary function to implement by subclasses.
virtual void execute() = 0; virtual void execute() = 0;
/// This flag is set after the execute() method has completed.
bool mExecuted;
public: public:
/// Construct a new work item. /// Construct a new work item.
@ -201,7 +204,8 @@ class ThreadPool
/// @param context The work context in which the item should be placed. /// @param context The work context in which the item should be placed.
/// If NULL, the root context will be used. /// If NULL, the root context will be used.
WorkItem( Context* context = 0 ) WorkItem( Context* context = 0 )
: mContext( context ? context : Context::ROOT_CONTEXT() ) : mContext( context ? context : Context::ROOT_CONTEXT() ),
mExecuted( false )
{ {
} }
@ -229,6 +233,12 @@ class ThreadPool
/// Return the item's base priority value. /// Return the item's base priority value.
/// @return item priority; defaults to 1.0. /// @return item priority; defaults to 1.0.
virtual F32 getPriority(); virtual F32 getPriority();
/// Has this work item been executed already?
bool hasExecuted() const
{
return mExecuted;
}
}; };
typedef ThreadSafeRef< WorkItem > WorkItemPtr; typedef ThreadSafeRef< WorkItem > WorkItemPtr;
@ -254,6 +264,9 @@ class ThreadPool
/// Number of worker threads guaranteed to be non-blocking. /// Number of worker threads guaranteed to be non-blocking.
U32 mNumThreadsReady; U32 mNumThreadsReady;
/// Number of work items that have not yet completed execution.
U32 mNumPendingItems;
/// Semaphore used to wake up threads, if necessary. /// Semaphore used to wake up threads, if necessary.
Semaphore mSemaphore; Semaphore mSemaphore;
@ -306,6 +319,18 @@ class ThreadPool
/// the queue to flush out. -1 = infinite. /// the queue to flush out. -1 = infinite.
void flushWorkItems( S32 timeOut = -1 ); void flushWorkItems( S32 timeOut = -1 );
/// If you're using a non-global thread pool to parallelise some work, you
/// may want to block until all the parallel work is complete. As with
/// flushWorkItems, this method may block indefinitely if new items keep
/// getting added to the pool before old ones finish.
///
/// <em>This method will not wait for items queued on the main thread using
/// queueWorkItemOnMainThread!</em>
///
/// @param timeOut Soft limit on the number of milliseconds to wait for
/// all items to complete. -1 = infinite.
void waitForAllItems( S32 timeOut = -1 );
/// Add a work item to the main thread's work queue. /// Add a work item to the main thread's work queue.
/// ///
/// The main thread's work queue will be processed each frame using /// The main thread's work queue will be processed each frame using

View file

@ -112,15 +112,37 @@ void MenuBar::updateMenuBar(PopupMenu *popupMenu /* = NULL */)
GuiPlatformGenericMenuBar* menuBarGui = _FindMenuBarCtrl(); GuiPlatformGenericMenuBar* menuBarGui = _FindMenuBarCtrl();
popupMenu->mData->mMenuBar = this; popupMenu->mData->mMenuBar = this;
AssertFatal( dStrcmp( popupMenu->mData->mMenuGui->text, popupMenu->getBarTitle() ) == 0, ""); String menuTitle = popupMenu->getBarTitle();
GuiMenuBar::Menu* menuGui = menuBarGui->findMenu( popupMenu->getBarTitle() );
if(!menuGui)
{
menuBarGui->addMenu( popupMenu->mData->mMenuGui );
menuGui = menuBarGui->findMenu( popupMenu->getBarTitle() );
}
PlatformPopupMenuData::mMenuMap[ menuGui ] = popupMenu; //Next, find out if we're still in the list of entries
SimSet::iterator itr = find(begin(), end(), popupMenu);
GuiMenuBar::Menu* menuGui = menuBarGui->findMenu(menuTitle);
if (!menuGui)
{
//This is our first time setting this particular menu up, so we'll OK it.
if (itr == end())
menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui);
else
menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui, itr - begin());
}
else
{
//Not our first time through, so we're really updating it.
//So, first, remove it from the menubar
menuBarGui->removeFromMenuBar(menuGui);
//Next, find out if we're still in the list of entries
SimSet::iterator itr = find(begin(), end(), popupMenu);
//if we're no longer in the list, we're pretty much done here
if (itr == end())
return;
//We're still here, so this is a valid menu for our current bar configuration, so add us back in.
menuBarGui->attachToMenuBar(menuGui, itr - begin());
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -154,17 +176,47 @@ void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos)
mCanvas->setMenuBar( base ); mCanvas->setMenuBar( base );
} }
for (S32 i = 0; i < size(); ++i)
{
PopupMenu *mnu = dynamic_cast<PopupMenu *>(at(i));
if (mnu == NULL)
{
Con::warnf("MenuBar::attachToMenuBar - Non-PopupMenu object in set");
continue;
}
if (mnu->isAttachedToMenuBar())
mnu->removeFromMenuBar();
mnu->attachToMenuBar(owner, pos + i);
}
} }
void MenuBar::removeFromCanvas() void MenuBar::removeFromCanvas()
{ {
_FindMenuBarCtrl()->clearMenus(); if (mCanvas == NULL || !isAttachedToCanvas())
return;
//_FindMenuBarCtrl()->clearMenus();
// Add the items
for (S32 i = 0; i < size(); ++i)
{
PopupMenu *mnu = dynamic_cast<PopupMenu *>(at(i));
if (mnu == NULL)
{
Con::warnf("MenuBar::removeFromMenuBar - Non-PopupMenu object in set");
continue;
}
mnu->removeFromMenuBar();
}
mCanvas->setMenuBar(NULL); mCanvas->setMenuBar(NULL);
if(mCanvas == NULL || !isAttachedToCanvas()) mCanvas = NULL;
return;
} }
#endif #endif

View file

@ -76,6 +76,10 @@ S32 Platform::messageBox(const UTF8 *title, const UTF8 *message, MBButtons butto
initMsgBox_ButtonData(); initMsgBox_ButtonData();
SDL_Window *window = WindowManager->getFirstWindow() ? SDL_GetWindowFromID( WindowManager->getFirstWindow()->getWindowId() ) : NULL; SDL_Window *window = WindowManager->getFirstWindow() ? SDL_GetWindowFromID( WindowManager->getFirstWindow()->getWindowId() ) : NULL;
if (window) //release the mouse from the window constaints
SDL_SetWindowGrab(window, SDL_FALSE);
if(buttons == MBOk) if(buttons == MBOk)
return SDL_ShowSimpleMessageBox(0, title, message, window ); return SDL_ShowSimpleMessageBox(0, title, message, window );

View file

@ -998,7 +998,7 @@ S32 Platform::getFileSize(const char *pFilePath)
return -1; return -1;
// must be a real file then // must be a real file then
return findData.nFileSizeLow; return ((findData.nFileSizeHigh * (MAXDWORD+1)) + findData.nFileSizeLow);
} }

View file

@ -236,6 +236,14 @@ Win32FileSystem::~Win32FileSystem()
{ {
} }
void Win32FileSystem::verifyCompatibility(const Path& _path, WIN32_FIND_DATAW _info)
{
if (_path.getFullFileName().isNotEmpty() && _path.getFullFileName().compare(String(_info.cFileName)) != 0)
{
Con::warnf("Linux Compatibility Warning: %s != %s", String(_info.cFileName).c_str(), _path.getFullFileName().c_str());
}
}
FileNodeRef Win32FileSystem::resolve(const Path& path) FileNodeRef Win32FileSystem::resolve(const Path& path)
{ {
String file = _BuildFileName(mVolume,path); String file = _BuildFileName(mVolume,path);
@ -245,6 +253,9 @@ FileNodeRef Win32FileSystem::resolve(const Path& path)
::FindClose(handle); ::FindClose(handle);
if (handle != INVALID_HANDLE_VALUE) if (handle != INVALID_HANDLE_VALUE)
{ {
#ifdef TORQUE_DEBUG
verifyCompatibility(path, info);
#endif
if (S_ISREG(info.dwFileAttributes)) if (S_ISREG(info.dwFileAttributes))
return new Win32File(path,file); return new Win32File(path,file);
if (S_ISDIR(info.dwFileAttributes)) if (S_ISDIR(info.dwFileAttributes))

View file

@ -45,6 +45,7 @@ public:
String getTypeStr() const { return "Win32"; } String getTypeStr() const { return "Win32"; }
FileNodeRef resolve(const Path& path); FileNodeRef resolve(const Path& path);
void verifyCompatibility(const Path& _path, WIN32_FIND_DATAW _info);
FileNodeRef create(const Path& path,FileNode::Mode); FileNodeRef create(const Path& path,FileNode::Mode);
bool remove(const Path& path); bool remove(const Path& path);
bool rename(const Path& from,const Path& to); bool rename(const Path& from,const Path& to);

View file

@ -737,7 +737,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
mShaderConsts->set( mMatPrevScreenToWorldSC, tempMat ); mShaderConsts->set( mMatPrevScreenToWorldSC, tempMat );
} }
if ( mAmbientColorSC->isValid() ) if (mAmbientColorSC->isValid() && state)
{ {
const ColorF &sunlight = state->getAmbientLightColor(); const ColorF &sunlight = state->getAmbientLightColor();
Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue ); Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue );

View file

@ -202,21 +202,20 @@ void RenderPrePassMgr::addElement( RenderInst *inst )
if ( isMeshInst || isDecalMeshInst ) if ( isMeshInst || isDecalMeshInst )
matInst = static_cast<MeshRenderInst*>(inst)->matInst; matInst = static_cast<MeshRenderInst*>(inst)->matInst;
// Skip decals if they don't have normal maps. if (matInst)
if ( isDecalMeshInst && !matInst->hasNormalMap() )
return;
// If its a custom material and it refracts... skip it.
if ( matInst &&
matInst->isCustomMaterial() &&
static_cast<CustomMaterial*>( matInst->getMaterial() )->mRefract )
return;
// Make sure we got a prepass material.
if ( matInst )
{ {
matInst = getPrePassMaterial( matInst ); // Skip decals if they don't have normal maps.
if ( !matInst || !matInst->isValid() ) if (isDecalMeshInst && !matInst->hasNormalMap())
return;
// If its a custom material and it refracts... skip it.
if (matInst->isCustomMaterial() &&
static_cast<CustomMaterial*>(matInst->getMaterial())->mRefract)
return;
// Make sure we got a prepass material.
matInst = getPrePassMaterial(matInst);
if (!matInst || !matInst->isValid())
return; return;
} }
@ -241,7 +240,7 @@ void RenderPrePassMgr::addElement( RenderInst *inst )
elem.key = *((U32*)&invSortDistSq); elem.key = *((U32*)&invSortDistSq);
// Next sort by pre-pass material if its a mesh... use the original sort key. // Next sort by pre-pass material if its a mesh... use the original sort key.
if ( isMeshInst ) if (isMeshInst && matInst)
elem.key2 = matInst->getStateHint(); elem.key2 = matInst->getStateHint();
else else
elem.key2 = originalKey; elem.key2 = originalKey;

View file

@ -1012,6 +1012,11 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en
F32 currStartX = normalStart.x; F32 currStartX = normalStart.x;
AssertFatal(currStartX != normalEnd.x, "This is going to cause problems in SceneContainer::castRay"); AssertFatal(currStartX != normalEnd.x, "This is going to cause problems in SceneContainer::castRay");
if(mIsNaN_F(currStartX))
{
PROFILE_END();
return false;
}
while (currStartX != normalEnd.x) while (currStartX != normalEnd.x)
{ {
F32 currEndX = getMin(currStartX + csmTotalBinSize, normalEnd.x); F32 currEndX = getMin(currStartX + csmTotalBinSize, normalEnd.x);

View file

@ -720,9 +720,9 @@ const char* SceneObject::_getRenderEnabled( void* object, const char* data )
{ {
SceneObject* obj = reinterpret_cast< SceneObject* >( object ); SceneObject* obj = reinterpret_cast< SceneObject* >( object );
if( obj->mObjectFlags.test( RenderEnabledFlag ) ) if( obj->mObjectFlags.test( RenderEnabledFlag ) )
return "true"; return "1";
else else
return "false"; return "0";
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -347,8 +347,16 @@ void ParallaxFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
Var *normalMap = getNormalMapTex(); Var *normalMap = getNormalMapTex();
// Call the library function to do the rest. // Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", if (fd.features.hasFeature(MFT_IsDXTnm, getProcessIndex()))
texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) ); {
meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @.xy, @, @ );\r\n",
texCoord, normalMap, texCoord, negViewTS, parallaxInfo));
}
else
{
meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @.xy, @, @ );\r\n",
texCoord, normalMap, texCoord, negViewTS, parallaxInfo));
}
// TODO: Fix second UV maybe? // TODO: Fix second UV maybe?

View file

@ -347,8 +347,16 @@ void ParallaxFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
Var *normalMap = getNormalMapTex(); Var *normalMap = getNormalMapTex();
// Call the library function to do the rest. // Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", if(fd.features.hasFeature( MFT_IsDXTnm, getProcessIndex() ))
texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) ); {
meta->addStatement( new GenOp( " @.xy += parallaxOffsetDxtnm( @, @.xy, @, @ );\r\n",
texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
}
else
{
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @ );\r\n",
texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
}
// TODO: Fix second UV maybe? // TODO: Fix second UV maybe?

View file

@ -215,7 +215,7 @@ U32 NetConnection::getSequence()
static U32 gPacketRateToServer = 32; static U32 gPacketRateToServer = 32;
static U32 gPacketUpdateDelayToServer = 32; static U32 gPacketUpdateDelayToServer = 32;
static U32 gPacketRateToClient = 10; static U32 gPacketRateToClient = 10;
static U32 gPacketSize = 200; static U32 gPacketSize = 508;
void NetConnection::consoleInit() void NetConnection::consoleInit()
{ {

View file

@ -818,7 +818,7 @@ public:
/// Some configuration values. /// Some configuration values.
enum GhostConstants enum GhostConstants
{ {
GhostIdBitSize = 12, GhostIdBitSize = 18, //262,144 ghosts
MaxGhostCount = 1 << GhostIdBitSize, //4096, MaxGhostCount = 1 << GhostIdBitSize, //4096,
GhostLookupTableSize = 1 << GhostIdBitSize, //4096 GhostLookupTableSize = 1 << GhostIdBitSize, //4096
GhostIndexBitSize = 4 // number of bits GhostIdBitSize-3 fits into GhostIndexBitSize = 4 // number of bits GhostIdBitSize-3 fits into

View file

@ -468,8 +468,16 @@ void TerrainDetailMapFeatGLSL::processPix( Vector<ShaderComponent*> &component
Var *normalMap = _getNormalMapTex(); Var *normalMap = _getNormalMapTex();
// Call the library function to do the rest. // Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", if (fd.features.hasFeature(MFT_IsDXTnm, detailIndex))
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) ); {
meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
}
else
{
meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n",
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
}
} }
// If this is a prepass then we skip color. // If this is a prepass then we skip color.
@ -812,12 +820,10 @@ void TerrainMacroMapFeatGLSL::processPix( Vector<ShaderComponent*> &componentL
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) ); detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" ); Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n", meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n",
outColor, outColor, outColor, detailColor, detailBlend ) ); outColor, outColor, outColor, detailColor, detailBlend ) );
//outColor, outColor, baseColor, detailColor, detailBlend ) );
meta->addStatement( new GenOp( " }\r\n" ) ); meta->addStatement( new GenOp( " }\r\n" ) );

View file

@ -468,8 +468,16 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
Var *normalMap = _getNormalMapTex(); Var *normalMap = _getNormalMapTex();
// Call the library function to do the rest. // Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", if(fd.features.hasFeature( MFT_IsDXTnm, detailIndex ) )
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) ); {
meta->addStatement( new GenOp( " @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
}
else
{
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n",
inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
}
} }
// If this is a prepass then we skip color. // If this is a prepass then we skip color.
@ -542,7 +550,6 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n",
detailColor, detailInfo, inDet ) ); detailColor, detailInfo, inDet ) );
Var *baseColor = (Var*)LangElement::find( "baseColor" );
Var *outColor = (Var*)LangElement::find( "col" ); Var *outColor = (Var*)LangElement::find( "col" );
meta->addStatement( new GenOp( " @ += @ * @;\r\n", meta->addStatement( new GenOp( " @ += @ * @;\r\n",

View file

@ -224,7 +224,7 @@ void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata,
if ( draw.matIndex & TSDrawPrimitive::NoMaterial ) if ( draw.matIndex & TSDrawPrimitive::NoMaterial )
continue; continue;
#ifdef TORQUE_DEBUG #ifdef TORQUE_DEBUG_BREAK_INSPECT
// for inspection if you happen to be running in a debugger and can't do bit // for inspection if you happen to be running in a debugger and can't do bit
// operations in your head. // operations in your head.
S32 triangles = draw.matIndex & TSDrawPrimitive::Triangles; S32 triangles = draw.matIndex & TSDrawPrimitive::Triangles;
@ -237,6 +237,7 @@ void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata,
TORQUE_UNUSED(fan); TORQUE_UNUSED(fan);
TORQUE_UNUSED(indexed); TORQUE_UNUSED(indexed);
TORQUE_UNUSED(type); TORQUE_UNUSED(type);
//define TORQUE_DEBUG_BREAK_INSPECT, and insert debug break here to inspect the above elements at runtime
#endif #endif
const U32 matIndex = draw.matIndex & TSDrawPrimitive::MaterialMask; const U32 matIndex = draw.matIndex & TSDrawPrimitive::MaterialMask;

View file

@ -28,9 +28,9 @@
#include "console/engineAPI.h" #include "console/engineAPI.h"
// define macros required for ConvexDecomp headers // define macros required for ConvexDecomp headers
#if defined( _WIN32 ) #if defined( _WIN32 ) && !defined( WIN32 )
#define WIN32 #define WIN32
#elif defined( __MACOSX__ ) #elif defined( __MACOSX__ ) && !defined( APPLE )
#define APPLE #define APPLE
#endif #endif

View file

@ -434,7 +434,8 @@ void PlatformWindowSDL::_triggerMouseLocationNotify(const SDL_Event& evt)
void PlatformWindowSDL::_triggerMouseWheelNotify(const SDL_Event& evt) void PlatformWindowSDL::_triggerMouseWheelNotify(const SDL_Event& evt)
{ {
wheelEvent.trigger(getWindowId(), 0, evt.wheel.x, evt.wheel.y); S32 wheelDelta = Con::getIntVariable("$pref::Input::MouseWheelSpeed", 120);
wheelEvent.trigger(getWindowId(), 0, evt.wheel.x * wheelDelta, evt.wheel.y * wheelDelta);
} }
void PlatformWindowSDL::_triggerMouseButtonNotify(const SDL_Event& event) void PlatformWindowSDL::_triggerMouseButtonNotify(const SDL_Event& event)
@ -483,12 +484,6 @@ void PlatformWindowSDL::_triggerKeyNotify(const SDL_Event& evt)
keyEvent.trigger(getWindowId(), torqueModifiers, inputAction, torqueKey); keyEvent.trigger(getWindowId(), torqueModifiers, inputAction, torqueKey);
//Con::printf("Key %d : %d", tKey.sym, inputAction); //Con::printf("Key %d : %d", tKey.sym, inputAction);
} }
// stop SDL_TEXTINPUT event when unwanted
if( inputAction == IA_MAKE && getKeyboardTranslation() && shouldNotTranslate( torqueModifiers, torqueKey ) )
SDL_StopTextInput();
else
SDL_StartTextInput();
} }
void PlatformWindowSDL::_triggerTextNotify(const SDL_Event& evt) void PlatformWindowSDL::_triggerTextNotify(const SDL_Event& evt)
@ -605,3 +600,12 @@ const UTF16 *PlatformWindowSDL::getCurtainWindowClassName()
static String str("CurtainWindowClassName"); static String str("CurtainWindowClassName");
return str.utf16(); return str.utf16();
} }
void PlatformWindowSDL::setKeyboardTranslation(const bool enabled)
{
mEnableKeyboardTranslation = enabled;
if (mEnableKeyboardTranslation)
SDL_StartTextInput();
else
SDL_StopTextInput();
}

View file

@ -160,6 +160,9 @@ public:
virtual bool isMouseLocked() const { return mMouseLocked; }; virtual bool isMouseLocked() const { return mMouseLocked; };
virtual bool shouldLockMouse() const { return mShouldLockMouse; }; virtual bool shouldLockMouse() const { return mShouldLockMouse; };
/// Set if relevant keypress events should be translated into character input events.
virtual void setKeyboardTranslation(const bool enabled);
virtual WindowId getWindowId(); virtual WindowId getWindowId();
SDL_Window* getSDLWindow() const { return mWindowHandle; } SDL_Window* getSDLWindow() const { return mWindowHandle; }

View file

@ -82,27 +82,32 @@ WindowInputGenerator::~WindowInputGenerator()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void WindowInputGenerator::generateInputEvent( InputEventInfo &inputEvent ) void WindowInputGenerator::generateInputEvent( InputEventInfo &inputEvent )
{ {
if( !mInputController || !mFocused ) if (!mInputController || !mFocused)
return; return;
if (inputEvent.action == SI_MAKE && inputEvent.deviceType == KeyboardDeviceType) if (inputEvent.action == SI_MAKE && inputEvent.deviceType == KeyboardDeviceType)
{ {
for( int i = 0; i < mAcceleratorMap.size(); ++i ) for (int i = 0; i < mAcceleratorMap.size(); ++i)
{ {
const AccKeyMap &acc = mAcceleratorMap[i]; const AccKeyMap &acc = mAcceleratorMap[i];
if( acc.modifier & inputEvent.modifier && acc.keyCode == inputEvent.objInst ) if (!mWindow->getKeyboardTranslation() &&
{ (acc.modifier & inputEvent.modifier || (acc.modifier == 0 && inputEvent.modifier == 0))
Con::evaluatef(acc.cmd); && acc.keyCode == inputEvent.objInst)
return; {
} Con::evaluatef(acc.cmd);
} return;
} }
}
}
// Give the ActionMap first shot. // Give the ActionMap first shot.
if (ActionMap::handleEventGlobal(&inputEvent)) if (ActionMap::handleEventGlobal(&inputEvent))
return; return;
if( mInputController->processInputEvent( inputEvent ) ) if (mInputController->processInputEvent(inputEvent))
return;
if (mWindow->getKeyboardTranslation())
return; return;
// If we get here we failed to process it with anything prior... so let // If we get here we failed to process it with anything prior... so let

View file

@ -41,6 +41,7 @@ $pref::Input::KeyboardEnabled = 1;
$pref::Input::MouseEnabled = 1; $pref::Input::MouseEnabled = 1;
$pref::Input::JoystickEnabled = 0; $pref::Input::JoystickEnabled = 0;
$pref::Input::KeyboardTurnSpeed = 0.1; $pref::Input::KeyboardTurnSpeed = 0.1;
$pref::Input::MouseWheelSpeed = 120;
$sceneLighting::cacheSize = 20000; $sceneLighting::cacheSize = 20000;
$sceneLighting::purgeMethod = "lastCreated"; $sceneLighting::purgeMethod = "lastCreated";

View file

@ -21,7 +21,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
if($GameCanvas == OculusCanvas) if($GameCanvas == OculusCanvas)
$GameCanvas = 0; $GameCanvas = Canvas;
// Cleanup Dialog created by 'core' // Cleanup Dialog created by 'core'
if( isObject( MessagePopupDlg ) ) if( isObject( MessagePopupDlg ) )

View file

@ -139,12 +139,27 @@ mat3x3 quatToMat( vec4 quat )
vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale )
{ {
float depth = texture( texMap, texCoord ).a; float depth = texture( texMap, texCoord ).a;
vec2 offset = negViewTS.xy * ( depth * depthScale ); vec2 offset = negViewTS.xy * vec2( depth * depthScale );
for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ )
{ {
depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5; depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5;
offset = negViewTS.xy * ( depth * depthScale ); offset = negViewTS.xy * vec2( depth * depthScale );
}
return offset;
}
/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha
vec2 parallaxOffsetDxtnm(sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale)
{
float depth = texture(texMap, texCoord).r;
vec2 offset = negViewTS.xy * vec2(depth * depthScale);
for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
{
depth = (depth + texture(texMap, texCoord + offset).r) * 0.5;
offset = negViewTS.xy * vec2(depth * depthScale);
} }
return offset; return offset;

View file

@ -151,6 +151,21 @@ float2 parallaxOffset( sampler2D texMap, float2 texCoord, float3 negViewTS, floa
return offset; return offset;
} }
/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha
float2 parallaxOffsetDxtnm(sampler2D texMap, float2 texCoord, float3 negViewTS, float depthScale)
{
float depth = tex2D(texMap, texCoord).r;
float2 offset = negViewTS.xy * (depth * depthScale);
for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
{
depth = (depth + tex2D(texMap, texCoord + offset).r) * 0.5;
offset = negViewTS.xy * (depth * depthScale);
}
return offset;
}
/// The maximum value for 16bit per component integer HDR encoding. /// The maximum value for 16bit per component integer HDR encoding.
static const float HDR_RGB16_MAX = 100.0; static const float HDR_RGB16_MAX = 100.0;

View file

@ -132,7 +132,7 @@ function MenuBuilder::addItem(%this, %pos, %item)
} }
else else
{ {
%this.insertItem(%pos, %name !$= "-" ? %name : "", %accel); %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel, %cmd);
} }
} }

View file

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 502 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 526 B

After

Width:  |  Height:  |  Size: 526 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 526 B

After

Width:  |  Height:  |  Size: 526 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 652 B

After

Width:  |  Height:  |  Size: 652 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 514 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 800 B

After

Width:  |  Height:  |  Size: 800 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 710 B

After

Width:  |  Height:  |  Size: 710 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 368 B

After

Width:  |  Height:  |  Size: 368 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 132 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 233 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 596 B

After

Width:  |  Height:  |  Size: 596 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 766 B

After

Width:  |  Height:  |  Size: 766 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 744 B

After

Width:  |  Height:  |  Size: 744 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 470 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 430 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 773 B

After

Width:  |  Height:  |  Size: 773 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 426 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 480 B

After

Width:  |  Height:  |  Size: 480 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 503 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 390 B

Before After
Before After

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