Bläddra i källkod

Named Cell/Frame improvements

- consistent naming scheme for functions and variables across classes
- additional TorqueScript get... methods for ImageAsset explicit cells
- CompositeSprite can now used named frames
- couple bug fixes
Mike Lilligreen 11 år sedan
förälder
incheckning
a7d89b8041

+ 76 - 7
engine/source/2d/assets/ImageAsset.cc

@@ -555,9 +555,25 @@ void ImageAsset::setCellHeight( const S32 cellheight )
 
 //------------------------------------------------------------------------------
 
+Vector2 ImageAsset::getExplicitCellOffset(const S32 cellIndex)
+{
+    if ( !getExplicitMode() )
+    {
+        // No, so warn.
+        Con::warnf( "ImageAsset() - Cannot perform explicit cell operation when not in explicit mode." );
+        return NULL;
+    }
+    
+    ImageAsset::FrameArea::PixelArea thisCell = mExplicitFrames.at(cellIndex);
+    return(thisCell.mPixelOffset);
+
+}
+
+//------------------------------------------------------------------------------
+
 S32 ImageAsset::getExplicitCellWidth(const S32 cellIndex)
 {
-	if ( !getExplicitMode() )
+    if ( !getExplicitMode() )
     {
         // No, so warn.
         Con::warnf( "ImageAsset() - Cannot perform explicit cell operation when not in explicit mode." );
@@ -573,13 +589,13 @@ S32 ImageAsset::getExplicitCellWidth(const S32 cellIndex)
 
 S32 ImageAsset::getExplicitCellHeight(const S32 cellIndex)
 {
-	if ( !getExplicitMode() )
+    if ( !getExplicitMode() )
     {
         // No, so warn.
         Con::warnf( "ImageAsset() - Cannot perform explicit cell operation when not in explicit mode." );
         return (0);
-	}
-	
+    }
+    
     ImageAsset::FrameArea::PixelArea thisCell = mExplicitFrames.at(cellIndex);
     return(thisCell.mPixelHeight);
 
@@ -587,6 +603,60 @@ S32 ImageAsset::getExplicitCellHeight(const S32 cellIndex)
 
 //------------------------------------------------------------------------------
 
+StringTableEntry ImageAsset::getExplicitCellName(const S32 cellIndex)
+{
+    if ( !getExplicitMode() )
+    {
+        // No, so warn.
+        Con::warnf( "ImageAsset() - Cannot perform explicit cell operation when not in explicit mode." );
+        return NULL;
+    }
+    
+    ImageAsset::FrameArea::PixelArea thisCell = mExplicitFrames.at(cellIndex);
+    return(thisCell.mRegionName);
+
+}
+
+//------------------------------------------------------------------------------
+
+S32 ImageAsset::getExplicitCellIndex(const char* regionName)
+{
+    if ( !getExplicitMode() )
+    {
+        // No, so warn.
+        Con::warnf( "ImageAsset() - Cannot perform explicit cell operation when not in explicit mode." );
+        return NULL;
+    }
+    
+    // Set up a frame counter
+    S32 frameCounter = 0;
+    
+    // Interate through the vector
+    for( typeExplicitFrameAreaVector::iterator frameItr = mExplicitFrames.begin(); frameItr != mExplicitFrames.end(); ++frameItr )
+    {
+        // Grab the current pixelArea
+        const FrameArea::PixelArea& pixelArea = *frameItr;
+        
+        // Check to see if the name matches the argument
+        if (!dStrcmp(pixelArea.mRegionName, regionName))
+        {
+            // Found it, so return the frame
+            return frameCounter;
+        }
+        else
+        {
+            ++frameCounter;
+        }
+    }
+    
+    // Didn't find it, so warn
+    Con::warnf( "ImageAsset::getExplicitCellIndex() - Cannot find %s cell.", regionName );
+    return NULL;
+    
+}
+
+//------------------------------------------------------------------------------
+
 bool ImageAsset::containsNamedRegion(const char* regionName)
 {
     for( typeFrameAreaVector::iterator frameItr = mFrames.begin(); frameItr != mFrames.end(); ++frameItr )
@@ -910,7 +980,7 @@ bool ImageAsset::removeExplicitCell( const char* regionName )
         const FrameArea::PixelArea& pixelArea = *frameItr;
         
         // Check to see if the name matches the argument
-        if (pixelArea.mRegionName == regionName)
+        if (!dStrcmp(pixelArea.mRegionName, regionName))
         {
             // Found it, so erase it and return success
             mExplicitFrames.erase(frameItr);
@@ -935,14 +1005,13 @@ ImageAsset::FrameArea& ImageAsset::getCellByName( const char* cellName)
         return BadFrameArea;
     }
     
-    // Interate through the vector
     for( typeFrameAreaVector::iterator frameItr = mFrames.begin(); frameItr != mFrames.end(); ++frameItr )
     {
         // Grab the current pixelArea
         const FrameArea::PixelArea& pixelArea = frameItr->mPixelArea;
         
         // Check to see if the name matches the argument
-        if (pixelArea.mRegionName == cellName)
+        if (!dStrcmp(pixelArea.mRegionName, cellName))
         {
             // Found it, so erase it and return success
             return *frameItr;

+ 8 - 4
engine/source/2d/assets/ImageAsset.h

@@ -163,7 +163,7 @@ private:
 
     /// Configuration.
     StringTableEntry            mImageFile;
-    bool						mForce16Bit;
+    bool                        mForce16Bit;
     TextureFilterMode           mLocalFilterMode;
     bool                        mExplicitMode;
     bool                        mCellRowOrder;
@@ -225,12 +225,16 @@ public:
     inline S32              getCellCountY( void ) const                     { return mCellCountY; }
 
     void                    setCellWidth( const S32 cellWidth );
-    inline S32              getCellWidth( void ) const						{ return mCellWidth; }
-    S32                     getExplicitCellWidth(const S32 cellIndex);
+    inline S32              getCellWidth( void ) const                      { return mCellWidth; }
 
     void                    setCellHeight( const S32 cellheight );
-    S32                     getCellHeight( void) const						{ return mCellHeight; }
+    inline S32              getCellHeight( void) const                      { return mCellHeight; }
+    
+    Vector2                 getExplicitCellOffset(const S32 cellIndex);
+    S32                     getExplicitCellWidth(const S32 cellIndex);
     S32                     getExplicitCellHeight(const S32 cellIndex);
+    StringTableEntry        getExplicitCellName(const S32 cellIndex);
+    S32                     getExplicitCellIndex(const char* regionName);
     
     bool                    containsNamedRegion(const char* regionName);
 

+ 107 - 27
engine/source/2d/assets/ImageAsset_ScriptBinding.h

@@ -255,32 +255,6 @@ ConsoleMethodWithDocs(ImageAsset, getCellWidth, ConsoleInt, 2, 2, ())
 
 //-----------------------------------------------------------------------------
 
-/*! Gets the CELL width in Explicit Mode.
-    @return the specified CELL width.
-*/
-ConsoleMethodWithDocs(ImageAsset, getExplicitCellWidth, ConsoleInt, 3,3, (CellIndex))
-{
-    // Fetch cell index.
-    const S32 cellIndex = dAtoi( argv[2] );
-
-    return(object->getExplicitCellWidth(cellIndex));
-}
-
-//-----------------------------------------------------------------------------
-
-/*! Gets the CELL height in Explicit Mode.
-    @return the specified CELL height.
-*/
-ConsoleMethodWithDocs(ImageAsset, getExplicitCellHeight, ConsoleInt, 3,3, (CellIndex))
-{
-    // Fetch cell index.
-    const S32 cellIndex = dAtoi( argv[2] );
-
-    return(object->getExplicitCellHeight(cellIndex));
-}
-
-//-----------------------------------------------------------------------------
-
 /*! Sets the CELL height.
     @return No return value.
 */
@@ -470,7 +444,7 @@ ConsoleMethodWithDocs(ImageAsset, removeExplicitCell, ConsoleBool, 7, 7, (int ce
 //-----------------------------------------------------------------------------
 
 /*! Set an explicit cell at the specified index.
-    @param cellIndex The zero-based index to insert the cell.  This will work when no cells are present.  If the index is beyond the cell count then the cell is simply added.
+    @param cellIndex The zero-based index to set the cell.
     @param cellOffsetX The offset in the X axis to the top-left of the cell.
     @param cellOffsetY The offset in the Y axis to the top-left of the cell.
     @param cellWidth The width of the cell.
@@ -505,4 +479,110 @@ ConsoleMethodWithDocs(ImageAsset, getExplicitCellCount, ConsoleInt, 2, 2, ())
     return object->getExplicitCellCount();
 }
 
+//-----------------------------------------------------------------------------
+
+/*! Gets the CELL offset in Explicit Mode.
+    @param cell The cell index or cell name to use to find the specific offset.
+    @return The specified CELL width.
+*/
+ConsoleMethodWithDocs(ImageAsset, getExplicitCellOffset, ConsoleString, 3, 3, (cell))
+{
+    // Was it a number or a string?
+    if (!dIsalpha(*argv[2]))
+    {
+        // Using cell index.
+        const S32 cellIndex = dAtoi(argv[2]);
+        
+        return object->getExplicitCellOffset(cellIndex).scriptThis();
+    }
+    else
+    {
+        // Using cell name.
+        ImageAsset::FrameArea& frameRegion = object->getCellByName(argv[2]);
+        
+        const Vector2 offset = frameRegion.mPixelArea.mPixelOffset;
+        
+        return offset.scriptThis();
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the CELL width in Explicit Mode.
+    @param cell The cell index or cell name to use to find the specific width.
+    @return The specified CELL width.
+*/
+ConsoleMethodWithDocs(ImageAsset, getExplicitCellWidth, ConsoleInt, 3, 3, (cell))
+{
+    S32 cellIndex;
+    
+    // Was it a number or a string?
+    if (!dIsalpha(*argv[2]))
+    {
+        // Using cell index.
+        cellIndex = dAtoi(argv[2]);
+        
+        return object->getExplicitCellWidth(cellIndex);
+    }
+    else
+    {
+        // Using cell name.
+        ImageAsset::FrameArea& frameRegion = object->getCellByName(argv[2]);
+        
+        return frameRegion.mPixelArea.mPixelWidth;
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the CELL height in Explicit Mode.
+    @param cell The cell index or cell name to use to find the specific height.
+    @return The specified CELL height.
+*/
+ConsoleMethodWithDocs(ImageAsset, getExplicitCellHeight, ConsoleInt, 3, 3, (cell))
+{
+    S32 cellIndex;
+    
+    // Was it a number or a string?
+    if (!dIsalpha(*argv[2]))
+    {
+        // Using cell index.
+        cellIndex = dAtoi(argv[2]);
+        
+        return object->getExplicitCellHeight(cellIndex);
+    }
+    else
+    {
+        // Using cell name.
+        ImageAsset::FrameArea& frameRegion = object->getCellByName(argv[2]);
+        
+        return frameRegion.mPixelArea.mPixelHeight;
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the CELL region name in Explicit Mode.
+    @param cell The cell index to use to find the specific name.
+    @return The specified CELL region name.
+*/
+ConsoleMethodWithDocs(ImageAsset, getExplicitCellName, ConsoleString, 3, 3, (cell))
+{
+    // Fetch cell index.
+    const S32 cellIndex = dAtoi(argv[2]);
+
+    return object->getExplicitCellName(cellIndex);
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the CELL index number in Explicit Mode.
+    @param cellName The cell name to use to find the specific index.
+    @return The specified CELL index number.
+*/
+ConsoleMethodWithDocs(ImageAsset, getExplicitCellIndex, ConsoleInt, 3, 3, (cellName))
+{
+    return object->getExplicitCellIndex( argv[2] );
+}
+
 ConsoleMethodGroupEndWithDocs(ImageAsset)

+ 14 - 14
engine/source/2d/assets/ParticleAssetEmitter.cc

@@ -204,7 +204,7 @@ ParticleAssetEmitter::ParticleAssetEmitter() :
     mImageAsset.registerRefreshNotify( this );
     mAnimationAsset.registerRefreshNotify( this );
     
-    mImageFrameName = "";
+    mNamedImageFrame = "";
 }
 
 //------------------------------------------------------------------------------
@@ -248,7 +248,7 @@ void ParticleAssetEmitter::initPersistFields()
 
     addProtectedField("Image", TypeImageAssetPtr, Offset(mImageAsset, ParticleAssetEmitter), &setImage, &getImage, &writeImage, "");
     addProtectedField("Frame", TypeS32, Offset(mImageFrame, ParticleAssetEmitter), &setImageFrame, &defaultProtectedGetFn, &writeImageFrame, "");
-    addProtectedField("FrameName", TypeString, Offset(mImageFrameName, ParticleAssetEmitter), &setImageFrameName, &defaultProtectedGetFn, &writeImageFrameName, "");
+    addProtectedField("NamedFrame", TypeString, Offset(mNamedImageFrame, ParticleAssetEmitter), &setNamedImageFrame, &defaultProtectedGetFn, &writeNamedImageFrame, "");
     addProtectedField("RandomImageFrame", TypeBool, Offset(mRandomImageFrame, ParticleAssetEmitter), &setRandomImageFrame, &defaultProtectedGetFn, &writeRandomImageFrame, "");
     addProtectedField("Animation", TypeAnimationAssetPtr, Offset(mAnimationAsset, ParticleAssetEmitter), &setAnimation, &getAnimation, &writeAnimation, "");
 }
@@ -300,7 +300,7 @@ void ParticleAssetEmitter::copyTo(SimObject* object)
    {
         // Named image frame?
         if ( pParticleAssetEmitter->isUsingNamedImageFrame() )
-            pParticleAssetEmitter->setImage( getImage(), getImageFrameName() );
+            pParticleAssetEmitter->setImage( getImage(), getNamedImageFrame() );
         else
             pParticleAssetEmitter->setImage( getImage(), getImageFrame() );
    }
@@ -409,7 +409,7 @@ bool ParticleAssetEmitter::setImage( const char* pAssetId, U32 frame )
     }
 
     // Using a numerical frame index
-    mUsingFrameName = false;
+    mUsingNamedFrame = false;
 
     // Refresh the asset.
     refreshAsset();
@@ -446,17 +446,17 @@ bool ParticleAssetEmitter::setImage( const char* pAssetId, const char* frameName
         else
         {
         // Yes, so set the frame.
-        mImageFrameName = StringTable->insert(frameName);
+        mNamedImageFrame = StringTable->insert(frameName);
         }
     }
     else
     {
         // No, so reset the image frame.
-        mImageFrameName = StringTable->insert(StringTable->EmptyString);
+        mNamedImageFrame = StringTable->insert(StringTable->EmptyString);
     }
 
     // Using a named frame index
-    mUsingFrameName = true;
+    mUsingNamedFrame = true;
     
     // Refresh the asset.
     refreshAsset();
@@ -492,7 +492,7 @@ bool ParticleAssetEmitter::setImageFrame( const U32 frame )
     mImageFrame = frame;
 
     // Using a numerical frame index.
-    mUsingFrameName = false;
+    mUsingNamedFrame = false;
 
     // Refresh the asset.
     refreshAsset();
@@ -503,33 +503,33 @@ bool ParticleAssetEmitter::setImageFrame( const U32 frame )
 
 //------------------------------------------------------------------------------
 
-bool ParticleAssetEmitter::setImageFrameName( const char* nameFrame )
+bool ParticleAssetEmitter::setNamedImageFrame( const char* frameName )
 {
     // Check Existing Image.
     if ( mImageAsset.isNull() )
     {
         // Warn.
-        Con::warnf("ParticleAssetEmitter::setImageNameFrame() - Cannot set Frame without existing asset Id.");
+        Con::warnf("ParticleAssetEmitter::setNamedImageFrame() - Cannot set Frame without existing asset Id.");
         
         // Return Here.
         return false;
     }
     
     // Check Frame Validity.
-    if ( !mImageAsset->containsFrame(nameFrame) )
+    if ( !mImageAsset->containsFrame(frameName) )
     {
         // Warn.
-        Con::warnf( "ParticleAssetEmitter::setImageFrameName() - Invalid Frame %s for asset Id '%s'.", nameFrame, mImageAsset.getAssetId() );
+        Con::warnf( "ParticleAssetEmitter::setNamedImageFrame() - Invalid Frame %s for asset Id '%s'.", frameName, mImageAsset.getAssetId() );
         
         // Return Here.
         return false;
     }
     
     // Set frame.
-    mImageFrameName = StringTable->insert(nameFrame);
+    mNamedImageFrame = StringTable->insert(frameName);
 
     // Using a named frame index
-    mUsingFrameName = true;
+    mUsingNamedFrame = true;
     
     // Refresh the asset.
     refreshAsset();

+ 7 - 7
engine/source/2d/assets/ParticleAssetEmitter.h

@@ -107,10 +107,10 @@ private:
     bool                                    mStaticMode;
     AssetPtr<ImageAsset>                    mImageAsset;
     U32                                     mImageFrame;
-    StringTableEntry                        mImageFrameName;
+    StringTableEntry                        mNamedImageFrame;
     bool                                    mRandomImageFrame;
     AssetPtr<AnimationAsset>                mAnimationAsset;
-    bool                                    mUsingFrameName;
+    bool                                    mUsingNamedFrame;
 
     /// Particle fields.
     ParticleAssetFieldCollection            mParticleFields;
@@ -184,14 +184,14 @@ public:
     inline bool getOldestInFront( void ) const { return mOldestInFront; }
    
     inline bool isStaticFrameProvider( void ) const { return mStaticMode; }
-    inline bool isUsingNamedImageFrame( void ) const { return mUsingFrameName; }
+    inline bool isUsingNamedImageFrame( void ) const { return mUsingNamedFrame; }
     bool setImage( const char* pAssetId, const U32 frame = 0 );
     bool setImage( const char* pAssetId, const char* frameName);
     inline StringTableEntry getImage( void ) const { return mImageAsset.getAssetId(); }
     bool setImageFrame( const U32 frame );
     inline U32 getImageFrame( void ) const { return mImageFrame; }
-    bool setImageFrameName( const char* frameName);
-    inline const char* getImageFrameName( void ) const { return mImageFrameName; }
+    bool setNamedImageFrame( const char* frameName);
+    inline const char* getNamedImageFrame( void ) const { return mNamedImageFrame; }
     inline void setRandomImageFrame( const bool randomImageFrame ) { mRandomImageFrame = randomImageFrame; }
     inline bool getRandomImageFrame( void ) const { return mRandomImageFrame; }
     bool setAnimation( const char* animationName );
@@ -310,8 +310,8 @@ protected:
     static bool     writeImage( void* obj, StringTableEntry pFieldName )                { ParticleAssetEmitter* pCastObject = static_cast<ParticleAssetEmitter*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAsset.notNull(); }
     static bool     setImageFrame(void* obj, const char* data)                          { static_cast<ParticleAssetEmitter*>(obj)->setImageFrame(dAtoi(data)); return false; };
     static bool     writeImageFrame( void* obj, StringTableEntry pFieldName )           { ParticleAssetEmitter* pCastObject = static_cast<ParticleAssetEmitter*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAsset.notNull() && !pCastObject->getRandomImageFrame(); }
-    static bool     setImageFrameName(void* obj, const char* data)                      { static_cast<ParticleAssetEmitter*>(obj)->setImageFrameName(data); return false; };
-    static bool     writeImageFrameName( void* obj, StringTableEntry pFieldName )       { ParticleAssetEmitter* pCastObject = static_cast<ParticleAssetEmitter*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAsset.notNull() && !pCastObject->getRandomImageFrame(); }
+    static bool     setNamedImageFrame(void* obj, const char* data)                     { static_cast<ParticleAssetEmitter*>(obj)->setNamedImageFrame(data); return false; };
+    static bool     writeNamedImageFrame( void* obj, StringTableEntry pFieldName )      { ParticleAssetEmitter* pCastObject = static_cast<ParticleAssetEmitter*>(obj); if ( !pCastObject->isStaticFrameProvider() || !pCastObject->isUsingNamedImageFrame() ) return false; return pCastObject->mImageAsset.notNull() && !pCastObject->getRandomImageFrame(); }
     static bool     setRandomImageFrame(void* obj, const char* data)                    { static_cast<ParticleAssetEmitter*>(obj)->setRandomImageFrame(dAtob(data)); return false; };
     static bool     writeRandomImageFrame( void* obj, StringTableEntry pFieldName )     { ParticleAssetEmitter* pCastObject = static_cast<ParticleAssetEmitter*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->getRandomImageFrame(); }
     static bool     setAnimation(void* obj, const char* data)                           { static_cast<ParticleAssetEmitter*>(obj)->setAnimation(data); return false; };

+ 84 - 10
engine/source/2d/assets/ParticleAssetEmitter_ScriptBinding.h

@@ -553,28 +553,60 @@ ConsoleMethodWithDocs(ParticleAssetEmitter, getImage, ConsoleString, 2, 2, ())
 
 //------------------------------------------------------------------------------
 
-/*! Sets the emitter to use the specified image frame.
-    @param frame The frame of the image to use..
+/*! Sets the emitter to use the specified numerical image frame.
+    @param frame The frame index of the image to use..
     @return Whether the operation was successful or not.
 */
 ConsoleMethodWithDocs(ParticleAssetEmitter, setImageFrame, ConsoleBool, 3, 3, (frame))
 {
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf( "ParticleAssetEmitter::setImageFrame() - Method invalid, not in static mode." );
+        return false;
+    }
+
+    // Are we using named frames?
+    if ( object->isUsingNamedImageFrame() )
+    {
+        // Yes, so warn.
+        Con::warnf( "ParticleAssetEmitter::setImageFrame() - Method invalid, using named frames." );
+        return false;
+    }
+
     return object->setImageFrame( dAtoi(argv[2]) );
 }
 
 //------------------------------------------------------------------------------
 
-/*! Gets the asset Id of the image asset assigned to the emitter.
-    @return The asset Id of the image asset assigned to the emitter or nothing if no image is assigned.
+/*! Gets the frame index of the image asset assigned to the emitter.
+    @return The frame index of the image asset assigned to the emitter or nothing if no image is assigned.
 */
 ConsoleMethodWithDocs(ParticleAssetEmitter, getImageFrame, ConsoleInt, 2, 2, ())
 {
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf( "ParticleAssetEmitter::getImageFrame() - Method invalid, not in static mode." );
+        return -1;
+    }
+
+    // Are we using named frames?
+    if ( object->isUsingNamedImageFrame() )
+    {
+        // Yes, so warn.
+        Con::warnf( "ParticleAssetEmitter::getImageFrame() - Method invalid, using named frames." );
+        return -1;
+    }
+
     return object->getImageFrame();
 }
 
 //------------------------------------------------------------------------------
 
-/*! Disables the Frame field and uses a random frame from the specified ImageAsset.
+/*! Disables the Frame and NamedFrame fields and uses a random frame from the specified ImageAsset.
     @param randomImageFrame Whether to use a random image frame or not.
     @return No return value.
 */
@@ -599,9 +631,25 @@ ConsoleMethodWithDocs(ParticleAssetEmitter, getRandomImageFrame, ConsoleBool, 2,
     @param frame String containing the name of the frame in the image to use.
     @return Whether the operation was successful or not.
 */
-ConsoleMethodWithDocs(ParticleAssetEmitter, setImageFrameName, ConsoleBool, 3, 3,  (frame))
+ConsoleMethodWithDocs(ParticleAssetEmitter, setNamedImageFrame, ConsoleBool, 3, 3,  (frame))
 {
-    return object->setImageFrameName( argv[2] );
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf( "ParticleAssetEmitter::setNamedImageFrame() - Method invalid, not in static mode." );
+        return false;
+    }
+
+    // Are we using named frames?
+    if ( !object->isUsingNamedImageFrame() )
+    {
+        // No, so warn.
+        Con::warnf( "ParticleAssetEmitter::setNamedImageFrame() - Method invalid, not using named frames." );
+        return false;
+    }
+
+    return object->setNamedImageFrame( argv[2] );
 }
 
 //------------------------------------------------------------------------------
@@ -609,9 +657,35 @@ ConsoleMethodWithDocs(ParticleAssetEmitter, setImageFrameName, ConsoleBool, 3, 3
 /*! Gets the asset Id of the image asset assigned to the emitter.
     @return The asset Id of the image asset assigned to the emitter or nothing if no image is assigned.
 */
-ConsoleMethodWithDocs(ParticleAssetEmitter, getImageFrameName, ConsoleString, 2, 2, ())
+ConsoleMethodWithDocs(ParticleAssetEmitter, getNamedImageFrame, ConsoleString, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf( "ParticleAssetEmitter::getNamedImageFrame() - Method invalid, not in static mode." );
+        return NULL;
+    }
+
+    // Are we using named frames?
+    if ( !object->isUsingNamedImageFrame() )
+    {
+        // No, so warn.
+        Con::warnf( "ParticleAssetEmitter::getNamedImageFrame() - Method invalid, not using named frames." );
+        return NULL;
+    }
+
+    return object->getNamedImageFrame();
+}
+
+//------------------------------------------------------------------------------
+
+/*! Gets whether the emitter is using a numerical or named image frame.
+    @return Returns true when using a named frame, false when using a numerical index.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, isUsingNamedImageFrame, ConsoleBool, 2, 2, ())
 {
-    return object->getImageFrameName();
+    return object->isUsingNamedImageFrame();
 }
 
 //------------------------------------------------------------------------------
@@ -996,4 +1070,4 @@ ConsoleMethodWithDocs(ParticleAssetEmitter, getValueScale, ConsoleFloat, 2, 2, (
    return object->getParticleFields().getValueScale();
 }
 
-ConsoleMethodGroupEndWithDocs(ParticleAssetEmitter)
+ConsoleMethodGroupEndWithDocs(ParticleAssetEmitter)

+ 16 - 28
engine/source/2d/core/ImageFrameProviderCore.cc

@@ -119,7 +119,7 @@ void ImageFrameProviderCore::copyTo( ImageFrameProviderCore* pImageFrameProvider
             if ( !isUsingNamedImageFrame() )
                 pImageFrameProviderCore->setImage( getImage(), getImageFrame() );
             else
-                pImageFrameProviderCore->setImage( getImage(), getImageFrameByName() );
+                pImageFrameProviderCore->setImage( getImage(), getNamedImageFrame() );
         }
     }
     else if ( mpAnimationAsset->notNull() )
@@ -187,7 +187,7 @@ bool ImageFrameProviderCore::validRender( void ) const
         if (!isUsingNamedImageFrame())
             return mpImageAsset->notNull() && ( getImageFrame() < (*mpImageAsset)->getFrameCount() );
         else
-            return mpImageAsset->notNull() && getImageFrameByName() != StringTable->EmptyString && ( (*mpImageAsset)->containsFrame(getImageFrameByName()) );
+            return mpImageAsset->notNull() && getNamedImageFrame() != StringTable->EmptyString && ( (*mpImageAsset)->containsFrame(getNamedImageFrame()) );
     }
 
     // No, so if the animation must be valid.
@@ -206,10 +206,10 @@ const ImageAsset::FrameArea& ImageFrameProviderCore::getProviderImageFrameArea(
     // If it is a static frame and it's using named frames, get the image area based on mImageNameFrame
     // Otherwise, get the current animation frame
     if (isStaticFrameProvider())
-        return !isUsingNamedImageFrame() ? (*mpImageAsset)->getImageFrameArea(mImageFrame) : (*mpImageAsset)->getImageFrameArea(mImageNameFrame);
+        return !isUsingNamedImageFrame() ? (*mpImageAsset)->getImageFrameArea(mImageFrame) : (*mpImageAsset)->getImageFrameArea(mNamedImageFrame);
     else
         return !(*mpAnimationAsset)->getNamedCellsMode() ? (*mpAnimationAsset)->getImage()->getImageFrameArea(getCurrentAnimationFrame()) :
-                                                           (*mpAnimationAsset)->getImage()->getImageFrameArea(getCurrentAnimationFrameName());
+                                                           (*mpAnimationAsset)->getImage()->getImageFrameArea(getCurrentNamedAnimationFrame());
     
     // If we got here for some reason, that's bad. So return a bad area frame
     return BadFrameArea;
@@ -308,14 +308,8 @@ bool ImageFrameProviderCore::setImage( const char* pImageAssetId, const U32 fram
     if ( mpImageAsset->notNull() )
         setImageFrame( frame );
 
-    // Set Frame.
-    mImageFrame = frame;
-
     // Set as static provider.
     mStaticProvider = true;
-    
-    // Using a numerical frame index.
-    mUsingNameFrame = false;
 
     // Turn-off tick processing.
     setProcessTicks( false );
@@ -326,7 +320,7 @@ bool ImageFrameProviderCore::setImage( const char* pImageAssetId, const U32 fram
 
 //------------------------------------------------------------------------------
 
-bool ImageFrameProviderCore::setImage( const char* pImageAssetId, const char* pNameFrame )
+bool ImageFrameProviderCore::setImage( const char* pImageAssetId, const char* pNamedFrame )
 {
     // Finish if invalid image asset.
     if ( pImageAssetId == NULL )
@@ -337,17 +331,11 @@ bool ImageFrameProviderCore::setImage( const char* pImageAssetId, const char* pN
     
     // Set the image frame if the image asset was set.
     if ( mpImageAsset->notNull() )
-        setImageFrameByName( pNameFrame );
-    
-    // Set Frame.
-    mImageNameFrame = StringTable->insert(pNameFrame);
+        setNamedImageFrame( pNamedFrame );
     
     // Set as static provider.
     mStaticProvider = true;
     
-    // Using a named frame index.
-    mUsingNameFrame = true;
-    
     // Turn-off tick processing.
     setProcessTicks( false );
     
@@ -382,7 +370,7 @@ bool ImageFrameProviderCore::setImageFrame( const U32 frame )
     mImageFrame = frame;
 
     // Using a numerical frame index.
-    mUsingNameFrame = false;
+    mUsingNamedFrame = false;
 
     // Return Okay.
     return true;
@@ -390,30 +378,30 @@ bool ImageFrameProviderCore::setImageFrame( const U32 frame )
 
 //-----------------------------------------------------------------------------
 
-bool ImageFrameProviderCore::setImageFrameByName(const char* frame)
+bool ImageFrameProviderCore::setNamedImageFrame(const char* pNamedFrame)
 {
     // Check Existing Image.
     if ( mpImageAsset->isNull() )
     {
         // Warn.
-        Con::warnf("ImageFrameProviderCore::setImageNameFrame() - Cannot set Frame without existing asset Id.");
+        Con::warnf("ImageFrameProviderCore::setNamedImageFrame() - Cannot set Frame without existing asset Id.");
         
         // Return Here.
         return false;
     }
     
     // Check Frame Validity.
-    if ( frame == StringTable->EmptyString )
+    if ( pNamedFrame == StringTable->EmptyString )
     {
         // Warn.
-        Con::warnf( "ImageFrameProviderCore::setImageNameFrame() - Invalid Frame %s for asset Id '%s'.", frame, mpImageAsset->getAssetId() );
+        Con::warnf( "ImageFrameProviderCore::setNamedImageFrame() - Invalid Frame %s for asset Id '%s'.", pNamedFrame, mpImageAsset->getAssetId() );
         // Return Here.
         return false;
     }
     
     // Set Frame.
-    mImageNameFrame = StringTable->insert(frame);
-    mUsingNameFrame = true;
+    mNamedImageFrame = StringTable->insert(pNamedFrame);
+    mUsingNamedFrame = true;
     
     // Return Okay.
     return true;
@@ -437,7 +425,7 @@ const U32 ImageFrameProviderCore::getCurrentAnimationFrame( void ) const
 
 //-----------------------------------------------------------------------------
 
-const char* ImageFrameProviderCore::getCurrentAnimationFrameName( void ) const
+const char* ImageFrameProviderCore::getCurrentNamedAnimationFrame( void ) const
 {
     // Sanity!
     AssertFatal( mpAnimationAsset->notNull(), "Animation controller requested current image frame but no animation asset assigned." );
@@ -489,7 +477,7 @@ bool ImageFrameProviderCore::isAnimationValid( void ) const
     else
     {
         // Fetch the current name frame.
-        const char* frameName = getCurrentAnimationFrameName();
+        const char* frameName = getCurrentNamedAnimationFrame();
 
         if (!imageAsset->containsFrame(frameName))
             return false;
@@ -704,7 +692,7 @@ void ImageFrameProviderCore::clearAssets( void )
 
     // Reset remaining state.
     mImageFrame = 0;
-    mImageNameFrame = StringTable->EmptyString;
+    mNamedImageFrame = StringTable->EmptyString;
     mStaticProvider = true;
     setProcessTicks( false );
 }

+ 8 - 7
engine/source/2d/core/ImageFrameProviderCore.h

@@ -63,10 +63,10 @@ protected:
 
     bool                                    mStaticProvider;
     
-    bool                                    mUsingNameFrame;
+    bool                                    mUsingNamedFrame;
 
     U32                                     mImageFrame;
-    StringTableEntry                        mImageNameFrame;
+    StringTableEntry                        mNamedImageFrame;
     AssetPtr<ImageAsset>*                   mpImageAsset;
     AssetPtr<AnimationAsset>*               mpAnimationAsset;
 
@@ -115,17 +115,18 @@ public:
     /// Static-Image Frame.
     inline bool setImage( const char* pImageAssetId ) { return setImage( pImageAssetId, mImageFrame ); }
     virtual bool setImage( const char* pImageAssetId, const U32 frame );
-    virtual bool setImage( const char* pImageAssetId, const char* pNameFrame );
+    virtual bool setImage( const char* pImageAssetId, const char* pNamedFrame );
     inline StringTableEntry getImage( void ) const{ return mpImageAsset->getAssetId(); }
     virtual bool setImageFrame( const U32 frame );
     inline U32 getImageFrame( void ) const { return mImageFrame; }
-    virtual bool setImageFrameByName( const char* frame );
-    inline StringTableEntry getImageFrameByName( void ) const { return mImageNameFrame; }
+    virtual bool setNamedImageFrame( const char* frame );
+    inline StringTableEntry getNamedImageFrame( void ) const { return mNamedImageFrame; }
 
     /// Animated-Image Frame.
     virtual bool setAnimation( const char* pAnimationAssetId );
     inline StringTableEntry getAnimation( void ) const { return mpAnimationAsset->getAssetId(); }
     void setAnimationFrame( const U32 frameIndex );
+    inline S32 getAnimationFrame( void ) const { return mCurrentFrameIndex; }
     void setAnimationTimeScale( const F32 scale ) { mAnimationTimeScale = scale; }
     inline F32 getAnimationTimeScale( void ) const { return mAnimationTimeScale; }
     bool playAnimation( const AssetPtr<AnimationAsset>& animationAsset);
@@ -138,13 +139,13 @@ public:
 
     /// Frame provision.
     inline bool isStaticFrameProvider( void ) const { return mStaticProvider; }
-    inline bool isUsingNamedImageFrame( void ) const { return mUsingNameFrame; }
+    inline bool isUsingNamedImageFrame( void ) const { return mUsingNamedFrame; }
     inline TextureHandle& getProviderTexture( void ) const { return !validRender() ? BadTextureHandle : isStaticFrameProvider() ? (*mpImageAsset)->getImageTexture() : (*mpAnimationAsset)->getImage()->getImageTexture(); };
     const ImageAsset::FrameArea& getProviderImageFrameArea( void ) const;
     inline const AnimationAsset* getCurrentAnimation( void ) const { return mpAnimationAsset->notNull() ? *mpAnimationAsset : NULL; };
     inline const StringTableEntry getCurrentAnimationAssetId( void ) const { return mpAnimationAsset->getAssetId(); };
     const U32 getCurrentAnimationFrame( void ) const;
-    const char* getCurrentAnimationFrameName( void ) const;
+    const char* getCurrentNamedAnimationFrame( void ) const;
     inline const F32 getCurrentAnimationTime( void ) const { return mCurrentTime; };
 
     void clearAssets( void );

+ 1 - 1
engine/source/2d/core/SpriteBase.cc

@@ -56,7 +56,7 @@ void SpriteBase::initPersistFields()
 
     addProtectedField("Image", TypeImageAssetPtr, Offset(mImageAsset, SpriteBase), &setImage, &getImage, &writeImage, "");
     addProtectedField("Frame", TypeS32, Offset(mImageFrame, SpriteBase), &setImageFrame, &defaultProtectedGetFn, &writeImageFrame, "");
-    addProtectedField("FrameName", TypeString, Offset(mImageFrame, SpriteBase), &setImageNameFrame, &defaultProtectedGetFn, &writeImageNameFrame, "");
+    addProtectedField("NamedFrame", TypeString, Offset(mNamedImageFrame, SpriteBase), &setNamedImageFrame, &defaultProtectedGetFn, &writeNamedImageFrame, "");
     addProtectedField("Animation", TypeAnimationAssetPtr, Offset(mAnimationAsset, SpriteBase), &setAnimation, &getAnimation, &writeAnimation, "");
 }
 

+ 3 - 3
engine/source/2d/core/SpriteBase.h

@@ -61,9 +61,9 @@ protected:
     static const char* getImage(void* obj, const char* data)                    { return DYNAMIC_VOID_CAST_TO(SpriteBase, ImageFrameProvider, obj)->getImage(); }
     static bool writeImage( void* obj, StringTableEntry pFieldName )            { SpriteBase* pCastObject = static_cast<SpriteBase*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAsset.notNull(); }
     static bool setImageFrame(void* obj, const char* data)                      { DYNAMIC_VOID_CAST_TO(SpriteBase, ImageFrameProvider, obj)->setImageFrame(dAtoi(data)); return false; };
-    static bool setImageNameFrame(void* obj, const char* data)                  { DYNAMIC_VOID_CAST_TO(SpriteBase, ImageFrameProvider, obj)->setImageFrameByName(data); return false; };
-    static bool writeImageFrame( void* obj, StringTableEntry pFieldName )       { SpriteBase* pCastObject = static_cast<SpriteBase*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAsset.notNull(); }
-    static bool writeImageNameFrame( void* obj, StringTableEntry pFieldName )   { SpriteBase* pCastObject = static_cast<SpriteBase*>(obj); if ( !pCastObject->isUsingNamedImageFrame() ) return false; return pCastObject->mImageAsset.notNull(); }
+    static bool setNamedImageFrame(void* obj, const char* data)                 { DYNAMIC_VOID_CAST_TO(SpriteBase, ImageFrameProvider, obj)->setNamedImageFrame(data); return false; };
+    static bool writeImageFrame( void* obj, StringTableEntry pFieldName )       { SpriteBase* pCastObject = static_cast<SpriteBase*>(obj); if ( !pCastObject->isStaticFrameProvider() || pCastObject->isUsingNamedImageFrame() ) return false; return pCastObject->mImageAsset.notNull(); }
+    static bool writeNamedImageFrame( void* obj, StringTableEntry pFieldName )  { SpriteBase* pCastObject = static_cast<SpriteBase*>(obj); if ( !pCastObject->isStaticFrameProvider() || !pCastObject->isUsingNamedImageFrame() ) return false; return pCastObject->mImageAsset.notNull(); }
     static bool setAnimation(void* obj, const char* data)                       { DYNAMIC_VOID_CAST_TO(SpriteBase, ImageFrameProvider, obj)->setAnimation(data); return false; };
     static const char* getAnimation(void* obj, const char* data)                { return DYNAMIC_VOID_CAST_TO(SpriteBase, ImageFrameProvider, obj)->getAnimation(); }
     static bool writeAnimation( void* obj, StringTableEntry pFieldName )        { SpriteBase* pCastObject = static_cast<SpriteBase*>(obj); if ( pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mAnimationAsset.notNull(); }

+ 108 - 24
engine/source/2d/core/SpriteBase_ScriptBinding.h

@@ -32,6 +32,16 @@ ConsoleMethodWithDocs(SpriteBase, isStaticFrameProvider, ConsoleBool, 2, 2, ())
 
 //------------------------------------------------------------------------------
 
+/*! Gets whether the sprite is using a numerical or named image frame.
+    @return Returns true when using a named frame, false when using a numerical index.
+*/
+ConsoleMethodWithDocs(SpriteBase, isUsingNamedImageFrame, ConsoleBool, 2, 2, ())
+{
+    return object->isUsingNamedImageFrame();
+}
+
+//------------------------------------------------------------------------------
+
 /*! Sets the sprite image and optionally frame.
     @param imageAssetId The image asset Id to display
     @param frame The numerical or named frame of the image to display
@@ -84,8 +94,8 @@ ConsoleMethodWithDocs(SpriteBase, getImage, ConsoleString, 2, 2, ())
 
 //------------------------------------------------------------------------------
 
-/*! Sets the image frame.
-    @param frame The frame to display
+/*! Sets the image frame using a numerical index.
+    @param frame The numerical frame to display
     @return Returns true on success.
 */
 ConsoleMethodWithDocs(SpriteBase, setImageFrame, ConsoleBool, 3, 3, (frame))
@@ -98,14 +108,14 @@ ConsoleMethodWithDocs(SpriteBase, setImageFrame, ConsoleBool, 3, 3, (frame))
         return false;
     }
 
-    // Set image Frame.
+    // Set the numerical frame
     return static_cast<ImageFrameProvider*>(object)->setImageFrame( dAtoi(argv[2]) );
 }
 
 //------------------------------------------------------------------------------
 
-/*! Gets the current image Frame.
-    @return The current image frame.
+/*! Gets the current numerical or named image frame.
+    @return The current numerical or named image frame.
 */
 ConsoleMethodWithDocs(SpriteBase, getImageFrame, ConsoleInt, 2, 2, ())
 {
@@ -117,47 +127,61 @@ ConsoleMethodWithDocs(SpriteBase, getImageFrame, ConsoleInt, 2, 2, ())
         return -1;
     }
 
-    // Get image Frame.
+    // Are we using a named image frame?
+    if ( object->isUsingNamedImageFrame() )
+    {
+        // Yes, so warn.
+        Con::warnf( "SpriteBase::getImageFrame() - Method invalid, using a named image frame." );
+        return -1;
+    }
+
     return static_cast<ImageFrameProvider*>(object)->getImageFrame();
 }
 
 //------------------------------------------------------------------------------
 
-/*! Sets the image frame using a string.
-    @param frame - The name of the frame.
-    @return True on success.
+/*! Sets the image frame using a named string.
+    @param frame The named frame to display
+    @return Returns true on success.
 */
-ConsoleMethodWithDocs(SpriteBase, setImageFrameName, ConsoleBool, 3, 3,  (frame))
+ConsoleMethodWithDocs(SpriteBase, setNamedImageFrame, ConsoleBool, 3, 3, (frame))
 {
     // Are we in static mode?
     if ( !object->isStaticFrameProvider() )
     {
         // No, so warn.
-        Con::warnf( "SpriteBase::setImageFrameName() - Method invalid, not in static mode." );
+        Con::warnf( "SpriteBase::setNamedImageFrame() - Method invalid, not in static mode." );
         return false;
     }
-    
-    // Set image Frame.
-    return static_cast<ImageFrameProvider*>(object)->setImageFrameByName( argv[2] );
+
+    // Set the numerical frame
+    return static_cast<ImageFrameProvider*>(object)->setNamedImageFrame( argv[2] );
 }
 
 //------------------------------------------------------------------------------
 
-/*! Gets the current image frame name.
-    @return The current image frame name.
+/*! Gets the current named image frame.
+    @return The current named image frame.
 */
-ConsoleMethodWithDocs(SpriteBase, getImageFrameName, ConsoleString, 2, 2, ())
+ConsoleMethodWithDocs(SpriteBase, getNamedImageFrame, ConsoleString, 2, 2, ())
 {
     // Are we in static mode?
     if ( !object->isStaticFrameProvider() )
     {
         // No, so warn.
-        Con::warnf( "SpriteBase::getImageFrameName() - Method invalid, not in static mode." );
+        Con::warnf( "SpriteBase::getNamedImageFrame() - Method invalid, not in static mode." );
         return NULL;
     }
-    
-    // Get image Frame.
-    return static_cast<ImageFrameProvider*>(object)->getImageFrameByName();
+
+    // Are we using a named image frame?
+    if ( !object->isUsingNamedImageFrame() )
+    {
+        // No, so warn.
+        Con::warnf( "SpriteBase::getNamedImageFrame() - Method invalid, not using a named image frame." );
+        return NULL;
+    }
+
+    return static_cast<ImageFrameProvider*>(object)->getNamedImageFrame();
 }
 
 //------------------------------------------------------------------------------
@@ -211,7 +235,7 @@ ConsoleMethodWithDocs(SpriteBase, stopAnimation, ConsoleVoid, 2, 2, ())
 
 //-----------------------------------------------------------------------------
 
-/*! Sets the current animation frame.
+/*! Sets the current animation frame. IMPORTANT: this is not the image frame number used in the animation!
     @param frame Which frame of the animation to display
     @return No return value.
 */
@@ -231,8 +255,8 @@ ConsoleMethodWithDocs(SpriteBase, setAnimationFrame, ConsoleVoid, 3, 3, (int fra
 
 //-----------------------------------------------------------------------------
 
-/*! Gets current animation frame.
-    @return (int frame) The current animation frame
+/*! Gets current frame index used in the animation. IMPORTANT: this is not the image frame number!
+    @return The current numerical animation frame
 */
 ConsoleMethodWithDocs(SpriteBase, getAnimationFrame, ConsoleInt, 2, 2, ())
 {
@@ -245,11 +269,71 @@ ConsoleMethodWithDocs(SpriteBase, getAnimationFrame, ConsoleInt, 2, 2, ())
     }
 
     // Get Animation Frame.
+    return object->getAnimationFrame();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current numerical image frame used in the animation.
+    @return The current numerical animation frame
+*/
+ConsoleMethodWithDocs(SpriteBase, getAnimationImageFrame, ConsoleInt, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf( "SpriteBase::getAnimationImageFrame() - Method invalid, not in dynamic (animated) mode." );
+        return -1;
+    }
+
+    // Get the current animation asset
+    const AnimationAsset* asset = object->getCurrentAnimation();
+    
+    // Are we using named animation frames?
+    if (asset->getNamedCellsMode())
+    {
+        // Yes, so warn.
+        Con::warnf( "SpriteBase::getAnimationImageFrame() - Method invalid, animation is in named cells mode." );
+        return -1;
+    }
+
+    // Get Image Frame.
     return object->getCurrentAnimationFrame();
 }
 
 //-----------------------------------------------------------------------------
 
+/*! Gets current named image frame used in the animation.
+    @return The current named animation frame
+*/
+ConsoleMethodWithDocs(SpriteBase, getAnimationNamedImageFrame, ConsoleString, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf( "SpriteBase::getAnimationNamedImageFrame() - Method invalid, not in dynamic (animated) mode." );
+        return NULL;
+    }
+    
+    // Get the current animation asset
+    const AnimationAsset* asset = object->getCurrentAnimation();
+
+    // Are we using named animation frames?
+    if (!asset->getNamedCellsMode())
+    {
+        // No, so warn.
+        Con::warnf( "SpriteBase::getAnimationNamedImageFrame() - Method invalid, animation not in named cells mode." );
+        return NULL;
+    }
+
+    // Get Image Frame.
+    return object->getCurrentNamedAnimationFrame();
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Gets current animation asset Id.
     @return (string AnimationAssetId) The current animation asset Id.
 */

+ 43 - 1
engine/source/2d/core/SpriteBatch.cc

@@ -475,6 +475,24 @@ void SpriteBatch::setSpriteImage( const char* pAssetId, const U32 imageFrame )
 
 //------------------------------------------------------------------------------
 
+void SpriteBatch::setSpriteImage( const char* pAssetId, const char* namedFrame )
+{
+    // Debug Profiling.
+    PROFILE_SCOPE(SpriteBatch_SetSpriteImage);
+
+    // Sanity!
+    AssertFatal( pAssetId, "Cannot set sprite image using a NULL asset Id." );
+
+    // Finish if a sprite is not selected.
+    if ( !checkSpriteSelected() )
+        return;
+
+    // Set image and frame.
+    mSelectedSprite->setImage( pAssetId, namedFrame );
+}
+
+//------------------------------------------------------------------------------
+
 StringTableEntry SpriteBatch::getSpriteImage( void ) const
 {
     // Finish if a sprite is not selected.
@@ -503,7 +521,7 @@ U32 SpriteBatch::getSpriteImageFrame( void ) const
 {
     // Finish if a sprite is not selected.
     if ( !checkSpriteSelected() )
-        return 0;
+        return NULL;
 
     // Get image frame.
     return mSelectedSprite->getImageFrame();
@@ -511,6 +529,30 @@ U32 SpriteBatch::getSpriteImageFrame( void ) const
 
 //------------------------------------------------------------------------------
 
+void SpriteBatch::setSpriteNamedImageFrame( const char* namedFrame )
+{
+    // Finish if a sprite is not selected.
+    if ( !checkSpriteSelected() )
+        return;
+
+    // Set image frame.
+    mSelectedSprite->setNamedImageFrame( namedFrame );
+}
+
+//------------------------------------------------------------------------------
+
+StringTableEntry SpriteBatch::getSpriteNamedImageFrame( void ) const
+{
+    // Finish if a sprite is not selected.
+    if ( !checkSpriteSelected() )
+        return NULL;
+
+    // Get image frame.
+    return mSelectedSprite->getNamedImageFrame();
+}
+
+//------------------------------------------------------------------------------
+
 void SpriteBatch::setSpriteAnimation( const char* pAssetId )
 {
     // Debug Profiling.

+ 4 - 1
engine/source/2d/core/SpriteBatch.h

@@ -121,10 +121,13 @@ public:
     inline void deselectSprite( void ) { mSelectedSprite = NULL; }
     bool isSpriteSelected( void ) const { return mSelectedSprite != NULL; }
 
-    void setSpriteImage( const char* pAssetId, const U32 imageFrame = 0 );
+    void setSpriteImage( const char* pAssetId, const U32 imageFrame );
+    void setSpriteImage( const char* pAssetId, const char* namedFrame );
     StringTableEntry getSpriteImage( void ) const;
     void setSpriteImageFrame( const U32 imageFrame );
     U32 getSpriteImageFrame( void ) const;
+    void setSpriteNamedImageFrame( const char* namedFrame );
+    StringTableEntry getSpriteNamedImageFrame( void ) const;
     void setSpriteAnimation( const char* pAssetId );
     StringTableEntry getSpriteAnimation( void ) const;
     void clearSpriteAsset( void );

+ 11 - 2
engine/source/2d/core/SpriteBatchItem.cc

@@ -54,6 +54,7 @@ static StringTableEntry spriteBlendColorName        = StringTable->insert("Blend
 static StringTableEntry spriteAlphaTestName         = StringTable->insert("AlphaTest");
 static StringTableEntry spriteImageName             = StringTable->insert("Image");
 static StringTableEntry spriteImageFrameName        = StringTable->insert("Frame");
+static StringTableEntry spriteNamedImageFrameName   = StringTable->insert("NamedFrame");
 static StringTableEntry spriteAnimationName         = StringTable->insert("Animation");
 static StringTableEntry spriteDataObjectName        = StringTable->insert("DataObject");
 
@@ -350,8 +351,11 @@ void SpriteBatchItem::onTamlCustomWrite( TamlCustomNode* pParentNode )
             // Yes, so write image asset Id.
             pSpriteNode->addField( spriteImageName, assetId );
 
-            // Write image frame.
-            pSpriteNode->addField( spriteImageFrameName, getImageFrame() );
+            // Write the image frame.
+            if ( isUsingNamedImageFrame() )
+                pSpriteNode->addField( spriteNamedImageFrameName, getNamedImageFrame() );
+            else
+                pSpriteNode->addField( spriteImageFrameName, getImageFrame() );
         }
     }
     else
@@ -474,6 +478,11 @@ void SpriteBatchItem::onTamlCustomRead( const TamlCustomNode* pSpriteNode )
             if ( getImage() != StringTable->EmptyString )
                 setImageFrame( imageFrame );
         }
+        else if ( fieldName == spriteNamedImageFrameName )
+        {
+            if ( getImage() != StringTable->EmptyString )
+                setNamedImageFrame( pSpriteField->getFieldValue() );
+        }
         else if ( fieldName == spriteAnimationName )
         {
             setAnimation( pSpriteField->getFieldValue() );

+ 47 - 8
engine/source/2d/sceneobject/CompositeSprite_ScriptBinding.h

@@ -367,12 +367,30 @@ ConsoleMethodWithDocs(CompositeSprite, isSpriteSelected, ConsoleBool, 2, 2, ())
     @param imageFrame The image frame of the imageAssetId to set the sprite to.
     @return No return value.
 */
-ConsoleMethodWithDocs(CompositeSprite, setSpriteImage, ConsoleVoid, 3, 4, (imageAssetId, [int imageFrame]))
+ConsoleMethodWithDocs(CompositeSprite, setSpriteImage, ConsoleVoid, 3, 4, (imageAssetId, [imageFrame]))
 {
-    // Fetch frame.
-    const U32 frame = argc >=4 ? dAtoi(argv[3]) : 0;
-
-    object->setSpriteImage( argv[2], frame );
+    // Was a frame specified?
+    if (argc >= 4)
+    {
+        // Was it a number or a string?
+        if (!dIsalpha(*argv[3]))
+        {
+            // Fetch the numerical frame and set the image
+            const U32 frame = argc >= 4 ? dAtoi(argv[3]) : 0;
+            object->setSpriteImage( argv[2], frame );
+        }
+        else
+        {
+            // Set the image and pass the named frame string
+            object->setSpriteImage( argv[2], argv[3] );
+        }
+    }
+    else
+    {
+        // Frame was not specified, use default 0 and set the image
+        const U32 frame = 0;
+        object->setSpriteImage( argv[2], frame );
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -411,6 +429,27 @@ ConsoleMethodWithDocs(CompositeSprite, getSpriteImageFrame, ConsoleInt, 2, 2, ()
 
 //-----------------------------------------------------------------------------
 
+/*! Sets the sprite named image frame.
+    @param namedFrame The named image frame to set the sprite to.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(CompositeSprite, setSpriteNamedImageFrame, ConsoleVoid, 3, 3, (namedFrame))
+{
+    object->setSpriteNamedImageFrame( argv[2] );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the sprite named image frame.
+    @return The sprite named image frame.
+*/
+ConsoleMethodWithDocs(CompositeSprite, getSpriteNamedImageFrame, ConsoleString, 2, 2, ())
+{
+    return object->getSpriteNamedImageFrame();
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Sets the sprite animation.
     @param imageAssetId The animation to set the sprite to.
     @return No return value.
@@ -1172,16 +1211,16 @@ ConsoleMethodWithDocs(CompositeSprite, pickArea, ConsoleString, 4, 6, (startx/y,
     aabb.upperBound.x = getMax( v1.x, v2.x );
     aabb.upperBound.y = getMax( v1.y, v2.y );
 
-	// Calculate local OOBB.
+    // Calculate local OOBB.
     b2Vec2 localOOBB[4];
     CoreMath::mAABBtoOOBB( aabb, localOOBB );
     CoreMath::mCalculateInverseOOBB( localOOBB, object->getRenderTransform(), localOOBB );
 
-	// Calculate local AABB.
+    // Calculate local AABB.
     b2AABB localAABB;
     CoreMath::mOOBBtoAABB( localOOBB, localAABB );
   
-	// Convert OOBB to a PolygonShape
+    // Convert OOBB to a PolygonShape
     b2PolygonShape oobb_polygon;
     oobb_polygon.Set(localOOBB, 4);
 

+ 4 - 4
engine/source/2d/sceneobject/ParticlePlayer.cc

@@ -404,7 +404,7 @@ void ParticlePlayer::integrateObject( const F32 totalTime, const F32 elapsedTime
     // Are we waiting for particles and there are non left?
     if ( mWaitingForParticles )
     {
-		// Yes, so are there any particles left?
+        // Yes, so are there any particles left?
         if ( activeParticleCount == 0 )
         {
             // No, so stop the player immediately.
@@ -414,7 +414,7 @@ void ParticlePlayer::integrateObject( const F32 totalTime, const F32 elapsedTime
         return;
     }
 
-	// Finish if the particle player is in "infinite" mode.
+    // Finish if the particle player is in "infinite" mode.
     if ( lifeMode == ParticleAsset::INFINITE )
         return;
 
@@ -793,7 +793,7 @@ bool ParticlePlayer::play( const bool resetParticles )
     {
         // Fetch the emitter node.
         EmitterNode* pEmitterNode = *emitterItr;
-		pEmitterNode->setPaused(false);
+        pEmitterNode->setPaused(false);
         
         // Reset the time since last generation.
         pEmitterNode->setTimeSinceLastGeneration( 0.0f );
@@ -1274,7 +1274,7 @@ void ParticlePlayer::configureParticle( EmitterNode* pEmitterNode, ParticleSyste
         {
             // No, so set the emitter image frame.
             if (pParticleAssetEmitter->isUsingNamedImageFrame())
-                frameProvider.setImageFrameByName( pParticleAssetEmitter->getImageFrameName() );
+                frameProvider.setNamedImageFrame( pParticleAssetEmitter->getNamedImageFrame() );
             else
                 frameProvider.setImageFrame( pParticleAssetEmitter->getImageFrame() );
         }

+ 1 - 1
engine/source/2d/sceneobject/SkeletonObject.cc

@@ -447,7 +447,7 @@ void SkeletonObject::updateComposition( const F32 time )
         pSprite->setExplicitVertices(vertices);
         
         pSprite->setImage(assetId);
-        pSprite->setImageFrameByName(attachment->name);
+        pSprite->setNamedImageFrame(attachment->name);
     }
     
     if (mLastFrameTime >= mTotalAnimationTime)