mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Merge pull request #1674 from Azaezel/guiAnimBitmapCtrl_simple
new: guiAnimBitmapCtrl
This commit is contained in:
commit
e4461f9751
294
Engine/source/gui/controls/guiAnimBitmapCtrl.cpp
Normal file
294
Engine/source/gui/controls/guiAnimBitmapCtrl.cpp
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "gui/controls/guiAnimBitmapCtrl.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT(guiAnimBitmapCtrl);
|
||||
|
||||
IMPLEMENT_CALLBACK(guiAnimBitmapCtrl, onLoop, void, (),
|
||||
(), "triggered when a loop completes");
|
||||
|
||||
IMPLEMENT_CALLBACK(guiAnimBitmapCtrl, onCompleted, void, (),
|
||||
(), "triggered when an animation completes");
|
||||
|
||||
IMPLEMENT_CALLBACK(guiAnimBitmapCtrl, onFrame, void, (S32 frameIndex, S32 frame),
|
||||
(frameIndex, frame), "triggered when a frame increments");
|
||||
|
||||
guiAnimBitmapCtrl::guiAnimBitmapCtrl(void)
|
||||
{
|
||||
mAnimTexTiling = Point2I::One;
|
||||
mAnimTexFramesString = NULL;
|
||||
mAnimTexFrames.clear();
|
||||
mNumFrames = 0;
|
||||
mCurFrameIndex = 0;
|
||||
mFramesPerSec = 60;
|
||||
mAnimateTexture = false;
|
||||
mFrameTime = PlatformTimer::create();
|
||||
mLoop = true;
|
||||
mPlay = true;
|
||||
mReverse = false;
|
||||
mFinished = false;
|
||||
}
|
||||
|
||||
guiAnimBitmapCtrl::~guiAnimBitmapCtrl(void)
|
||||
{
|
||||
mAnimTexFrames.clear();
|
||||
}
|
||||
void guiAnimBitmapCtrl::initPersistFields()
|
||||
{
|
||||
addField("AnimTexTiling", TYPEID< Point2I >(), Offset(mAnimTexTiling, guiAnimBitmapCtrl),
|
||||
"@brief The number of frames, in rows and columns stored in textureName "
|
||||
"(when animateTexture is true).\n\n"
|
||||
"A maximum of 256 frames can be stored in a single texture when using "
|
||||
"mAnimTexTiling. Value should be \"NumColumns NumRows\", for example \"4 4\".");
|
||||
addProtectedField("AnimTexFrames", TYPEID< StringTableEntry >(), Offset(mAnimTexFramesString, guiAnimBitmapCtrl), &ptSetFrameRanges, &defaultProtectedGetFn,
|
||||
"@brief A list of frames and/or frame ranges to use for particle "
|
||||
"animation if animateTexture is true.\n\n"
|
||||
"Each frame token must be separated by whitespace. A frame token must be "
|
||||
"a positive integer frame number or a range of frame numbers separated "
|
||||
"with a '-'. The range separator, '-', cannot have any whitspace around "
|
||||
"it.\n\n"
|
||||
"Ranges can be specified to move through the frames in reverse as well "
|
||||
"as forward (eg. 19-14). Frame numbers exceeding the number of tiles will "
|
||||
"wrap.\n"
|
||||
"@tsexample\n"
|
||||
"mAnimTexFrames = \"0-16 20 19 18 17 31-21\";\n"
|
||||
"@endtsexample\n");
|
||||
|
||||
addField("loop", TypeBool, Offset(mLoop, guiAnimBitmapCtrl), "loop?");
|
||||
addField("play", TypeBool, Offset(mPlay, guiAnimBitmapCtrl), "play?");
|
||||
addField("reverse", TypeBool, Offset(mReverse, guiAnimBitmapCtrl), "play reversed?");
|
||||
addField("fps", TypeS32, Offset(mFramesPerSec, guiAnimBitmapCtrl), "Frame Rate");
|
||||
|
||||
addProtectedField("curFrame", TypeS32, Offset(mCurFrameIndex, guiAnimBitmapCtrl), &ptSetFrame, &defaultProtectedGetFn, "Index of currently Displaying Frame ");
|
||||
|
||||
Parent::initPersistFields();
|
||||
removeField("wrap");
|
||||
}
|
||||
|
||||
bool guiAnimBitmapCtrl::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
if (!mAnimTexFramesString || !mAnimTexFramesString[0])
|
||||
{
|
||||
S32 n_tiles = mAnimTexTiling.x * mAnimTexTiling.y - 1;
|
||||
for (S32 i = 0; i <= n_tiles; i++)
|
||||
mAnimTexFrames.push_back(i);
|
||||
mNumFrames = mAnimTexFrames.size() - 1;
|
||||
if (mCurFrameIndex > mNumFrames)
|
||||
mCurFrameIndex = mNumFrames;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool guiAnimBitmapCtrl::ptSetFrame(void *object, const char *index, const char *data)
|
||||
{
|
||||
guiAnimBitmapCtrl *pData = static_cast<guiAnimBitmapCtrl*>(object);
|
||||
|
||||
if (!pData->mNumFrames)
|
||||
{
|
||||
pData->mCurFrameIndex = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 val = dAtoi(data);
|
||||
U32 i;
|
||||
|
||||
if (val < 0)
|
||||
{
|
||||
pData->mCurFrameIndex = pData->mNumFrames;
|
||||
return false;
|
||||
}
|
||||
else if (val > pData->mNumFrames)
|
||||
{
|
||||
pData->mCurFrameIndex = 0;
|
||||
return false;
|
||||
};
|
||||
|
||||
pData->mCurFrameIndex = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool guiAnimBitmapCtrl::ptSetFrameRanges(void *object, const char *index, const char *data)
|
||||
{
|
||||
guiAnimBitmapCtrl *pData = static_cast<guiAnimBitmapCtrl*>(object);
|
||||
|
||||
// Here we parse mAnimTexFramesString into byte-size frame numbers in mAnimTexFrames.
|
||||
// Each frame token must be separated by whitespace.
|
||||
// A frame token must be a positive integer frame number or a range of frame numbers
|
||||
// separated with a '-'.
|
||||
// The range separator, '-', cannot have any whitspace around it.
|
||||
// Ranges can be specified to move through the frames in reverse as well as forward.
|
||||
// Frame numbers exceeding the number of tiles will wrap.
|
||||
// example:
|
||||
// "0-16 20 19 18 17 31-21"
|
||||
|
||||
S32 n_tiles = pData->mAnimTexTiling.x * pData->mAnimTexTiling.y - 1;
|
||||
|
||||
pData->mAnimTexFrames.clear();
|
||||
|
||||
if (!data || !data[0])
|
||||
{
|
||||
for (S32 i = 0; i <= n_tiles; i++)
|
||||
pData->mAnimTexFrames.push_back(i);
|
||||
pData->mNumFrames = pData->mAnimTexFrames.size() - 1;
|
||||
if (pData->mCurFrameIndex > pData->mNumFrames)
|
||||
pData->mCurFrameIndex = pData->mNumFrames;
|
||||
return true;
|
||||
}
|
||||
char* tokCopy = new char[dStrlen(data) + 1];
|
||||
dStrcpy(tokCopy, data);
|
||||
|
||||
char* currTok = dStrtok(tokCopy, " \t");
|
||||
while (currTok != NULL)
|
||||
{
|
||||
char* minus = dStrchr(currTok, '-');
|
||||
if (minus)
|
||||
{
|
||||
// add a range of frames
|
||||
*minus = '\0';
|
||||
S32 range_a = dAtoi(currTok);
|
||||
S32 range_b = dAtoi(minus + 1);
|
||||
if (range_b < range_a)
|
||||
{
|
||||
// reverse frame range
|
||||
for (S32 i = range_a; i >= range_b; i--)
|
||||
pData->mAnimTexFrames.push_back(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward frame range
|
||||
for (S32 i = range_a; i <= range_b; i++)
|
||||
pData->mAnimTexFrames.push_back(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add one frame
|
||||
pData->mAnimTexFrames.push_back(dAtoi(currTok));
|
||||
}
|
||||
currTok = dStrtok(NULL, " \t");
|
||||
}
|
||||
|
||||
// cleanup
|
||||
delete[] tokCopy;
|
||||
pData->mNumFrames = pData->mAnimTexFrames.size() - 1;
|
||||
if (pData->mCurFrameIndex > pData->mNumFrames)
|
||||
pData->mCurFrameIndex = pData->mNumFrames;
|
||||
return true;
|
||||
}
|
||||
|
||||
void guiAnimBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
if (mTextureObject)
|
||||
{
|
||||
if (mFrameTime->getElapsedMs() > 1000 / mFramesPerSec) //fps to msfp conversion
|
||||
{
|
||||
mFrameTime->reset();
|
||||
|
||||
if (mPlay)
|
||||
{
|
||||
if (mReverse) //play backward
|
||||
{
|
||||
mCurFrameIndex--;
|
||||
if (mCurFrameIndex < 0)
|
||||
{
|
||||
if (mLoop)
|
||||
{
|
||||
mCurFrameIndex = mNumFrames;
|
||||
onLoop_callback();
|
||||
mFinished = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurFrameIndex = 0;
|
||||
if (!mFinished)
|
||||
onCompleted_callback();
|
||||
mFinished = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
onFrame_callback(mCurFrameIndex, mAnimTexFrames[mCurFrameIndex]);
|
||||
}
|
||||
else // play forward
|
||||
{
|
||||
mCurFrameIndex++;
|
||||
|
||||
if (mCurFrameIndex > mNumFrames)
|
||||
{
|
||||
if (mLoop)
|
||||
{
|
||||
mCurFrameIndex = 0;
|
||||
onLoop_callback();
|
||||
mFinished = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurFrameIndex = mNumFrames;
|
||||
if (!mFinished)
|
||||
onCompleted_callback();
|
||||
mFinished = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
onFrame_callback(mCurFrameIndex, mAnimTexFrames[mCurFrameIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GFX->getDrawUtil()->clearBitmapModulation();
|
||||
|
||||
GFXTextureObject* texture = mTextureObject;
|
||||
|
||||
Point2I modifiedSRC = Point2I(texture->mBitmapSize.x / mAnimTexTiling.x, texture->mBitmapSize.y / mAnimTexTiling.y);
|
||||
RectI srcRegion;
|
||||
Point2I offsetSRC = Point2I::Zero;
|
||||
|
||||
offsetSRC.x = (texture->mBitmapSize.x / mAnimTexTiling.x) * (mAnimTexFrames[mCurFrameIndex] % mAnimTexTiling.x);
|
||||
offsetSRC.y = (texture->mBitmapSize.y / mAnimTexTiling.y) * (mAnimTexFrames[mCurFrameIndex] / mAnimTexTiling.x);
|
||||
|
||||
srcRegion.set(offsetSRC, modifiedSRC);
|
||||
|
||||
GFX->getDrawUtil()->drawBitmapStretchSR(texture, updateRect, srcRegion, GFXBitmapFlip_None, GFXTextureFilterLinear, false);
|
||||
}
|
||||
|
||||
if (mProfile->mBorder || !mTextureObject)
|
||||
{
|
||||
RectI rect(offset, getExtent());
|
||||
GFX->getDrawUtil()->drawRect(rect, mProfile->mBorderColor);
|
||||
}
|
||||
|
||||
renderChildControls(offset, updateRect);
|
||||
}
|
||||
70
Engine/source/gui/controls/guiAnimBitmapCtrl.h
Normal file
70
Engine/source/gui/controls/guiAnimBitmapCtrl.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUIANIMBITMAPCTRL_H_
|
||||
#define _GUIANIMBITMAPCTRL_H_
|
||||
|
||||
#ifndef _GUIBITMAPCTRL_H_
|
||||
#include "gui/controls/guiBitmapCtrl.h"
|
||||
#endif
|
||||
|
||||
class guiAnimBitmapCtrl : public GuiBitmapCtrl
|
||||
{
|
||||
public:
|
||||
typedef GuiBitmapCtrl Parent;
|
||||
|
||||
protected:
|
||||
/// max frames (x,y)
|
||||
Point2I mAnimTexTiling;
|
||||
/// frames to use
|
||||
StringTableEntry mAnimTexFramesString;
|
||||
/// frames to use (internal)
|
||||
Vector<S32> mAnimTexFrames;
|
||||
U32 mNumFrames;
|
||||
S32 mCurFrameIndex;
|
||||
|
||||
bool mLoop;
|
||||
bool mPlay;
|
||||
bool mReverse;
|
||||
S32 mFramesPerSec;
|
||||
bool mAnimateTexture;
|
||||
PlatformTimer * mFrameTime;
|
||||
bool mFinished;
|
||||
static bool ptSetFrame(void *object, const char *index, const char *data);
|
||||
static bool ptSetFrameRanges(void *object, const char *index, const char *data);
|
||||
public:
|
||||
guiAnimBitmapCtrl();
|
||||
~guiAnimBitmapCtrl();
|
||||
bool onAdd();
|
||||
|
||||
static void initPersistFields();
|
||||
void onRender(Point2I offset, const RectI &updateRect);
|
||||
DECLARE_CONOBJECT(guiAnimBitmapCtrl);
|
||||
DECLARE_CATEGORY("Gui Images");
|
||||
DECLARE_DESCRIPTION("A control that clips a bitmap based on %.");
|
||||
|
||||
DECLARE_CALLBACK(void, onLoop, ());
|
||||
DECLARE_CALLBACK(void, onCompleted, ());
|
||||
DECLARE_CALLBACK(void, onFrame, (S32 frameIndex, S32 frame));
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue