Browse Source

Fixes for CollisionGroups and CollisionLayers

- setCollisionLayers TorqueScript method now works properly with individual element input (n1, n2, n3, ...)
- directly assigning space separated strings to CollisionGroups and CollisionLayers fields in TorqueScript now works properly
- Taml now outputs both fields as space separated strings instead of a bit mask integer
Mike Lilligreen 11 years ago
parent
commit
ce62ed54d9

+ 67 - 0
engine/source/2d/core/Utility.cc

@@ -327,4 +327,71 @@ U32 mGetStringElementCount( const char* inString )
     return wordCount;
 }
 
+//-----------------------------------------------------------------------------
+
+U32 mConvertStringToMask( const char* string )
+{
+    // Grab the element count of the first parameter.
+    const U32 elementCount = Utility::mGetStringElementCount(string);
+
+    // Make sure we get at least one number.
+    if (elementCount < 1)
+        return MASK_ALL;
+    else if ( elementCount == 1 )
+    {
+        if ( dStricmp( string, "all" ) == 0 )
+            return MASK_ALL;
+        else if ( dStricmp( string, "none" ) == 0 || dStricmp( string, "off" ) == 0 )
+            return 0;
+    }
+
+    // The mask.
+    U32 mask = 0;
+
+    // Convert the string to a mask.
+    for (U32 i = 0; i < elementCount; i++)
+    {
+        S32 bit = dAtoi(Utility::mGetStringElement(string, i));
+         
+        // Make sure the group is valid.
+        if ((bit < 0) || (bit >= MASK_BITCOUNT))
+        {
+            Con::warnf("Utility::mConvertStringToMask() - Invalid group specified (%d); skipped!", bit);
+            continue;
+        }
+         
+        mask |= (1 << bit);
+    }
+
+    return mask;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* mConvertMaskToString( const U32 mask )
+{
+    bool first = true;
+    static char bits[128];
+    bits[0] = '\0';
+
+    if (!mask)
+    {
+        dSprintf(bits, 8, "none");
+        return bits;
+    }
+    
+    for (S32 i = 0; i < MASK_BITCOUNT; i++)
+    {
+        if (mask & BIT(i))
+        {
+            char bit[4];
+            dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
+            first = false;
+            dStrcat(bits, bit);
+        }
+    }
+
+    return bits;
+}
+
 } // Namespace Utility

+ 2 - 0
engine/source/2d/core/Utility.h

@@ -80,6 +80,8 @@ Vector2 mGetStringElementVector( const char* inString, const U32 index = 0 );
 VectorF mGetStringElementVector3D( const char* inString, const U32 index = 0 );
 const char* mGetStringElement( const char* inString, const U32 index, const bool copyBuffer = true );
 U32 mGetStringElementCount( const char *string );
+U32 mConvertStringToMask( const char* string );
+const char* mConvertMaskToString( const U32 mask );
 
 } // Namespace Utility.
 

+ 2 - 2
engine/source/2d/sceneobject/SceneObject.cc

@@ -282,8 +282,8 @@ void SceneObject::initPersistFields()
     addProtectedField("SleepingAllowed", TypeBool, NULL, &setSleepingAllowed, &getSleepingAllowed, &writeSleepingAllowed, "" );
 
     /// Collision control.
-    addProtectedField("CollisionGroups", TypeS32, Offset(mCollisionGroupMask, SceneObject), &setCollisionGroups, &defaultProtectedGetFn, &writeCollisionGroups, "");
-    addProtectedField("CollisionLayers", TypeS32, Offset(mCollisionLayerMask, SceneObject), &setCollisionLayers, &defaultProtectedGetFn, &writeCollisionLayers, "");
+    addProtectedField("CollisionGroups", TypeS32, Offset(mCollisionGroupMask, SceneObject), &setCollisionGroups, &getCollisionGroups, &writeCollisionGroups, "");
+    addProtectedField("CollisionLayers", TypeS32, Offset(mCollisionLayerMask, SceneObject), &setCollisionLayers, &getCollisionLayers, &writeCollisionLayers, "");
     addField("CollisionSuppress", TypeBool, Offset(mCollisionSuppress, SceneObject), &writeCollisionSuppress, "");
     addProtectedField("GatherContacts", TypeBool, NULL, &setGatherContacts, &defaultProtectedGetFn, &writeGatherContacts, "");
     addProtectedField("DefaultDensity", TypeF32, Offset( mDefaultFixture.density, SceneObject), &setDefaultDensity, &defaultProtectedGetFn, &writeDefaultDensity, "");

+ 4 - 2
engine/source/2d/sceneobject/SceneObject.h

@@ -658,9 +658,11 @@ protected:
     static bool             writeDefaultFriction( void* obj, StringTableEntry pFieldName ) {return mNotEqual(static_cast<SceneObject*>(obj)->getDefaultFriction(), 0.2f); }
     static bool             setDefaultRestitution(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setDefaultRestitution(dAtof(data)); return false; }
     static bool             writeDefaultRestitution( void* obj, StringTableEntry pFieldName ) { return mNotEqual(static_cast<SceneObject*>(obj)->getDefaultRestitution(), 0.0f); }
-    static bool             setCollisionGroups(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionGroupMask(dAtoi(data)); return false; }
+    static bool             setCollisionGroups(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionGroupMask(Utility::mConvertStringToMask(data)); return false; }
+    static const char*      getCollisionGroups(void* obj, const char* data) { return Utility::mConvertMaskToString( static_cast<SceneObject*>(obj)->getCollisionGroupMask() ); }
     static bool             writeCollisionGroups( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionGroupMask() != MASK_ALL; }
-    static bool             setCollisionLayers(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionLayerMask(dAtoi(data)); return false; }
+    static bool             setCollisionLayers(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionLayerMask(Utility::mConvertStringToMask(data)); return false; }
+    static const char*      getCollisionLayers(void* obj, const char* data) { return Utility::mConvertMaskToString( static_cast<SceneObject*>(obj)->getCollisionLayerMask() ); }
     static bool             writeCollisionLayers( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionLayerMask() != MASK_ALL; }
     static bool             writeCollisionSuppress( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionSuppress() == true; }
     static bool             setGatherContacts(void* obj, const char* data)  { static_cast<SceneObject*>(obj)->setGatherContacts(dAtoi(data)); return false; }

+ 0 - 2
engine/source/2d/sceneobject/SceneObject_ScriptBinding.h

@@ -1287,8 +1287,6 @@ ConsoleMethodWithDocs(SceneObject, setCollisionLayers, ConsoleVoid, 2, 2 + MASK_
             object->setCollisionLayerMask(0);
             return;
         }
-
-        return;
     }
 
     // The mask.