mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-01-24 17:26:41 +00:00
more tweaks to anim editor, allow seeking via timeline when RMB is held
This commit is contained in:
parent
8369a7168f
commit
d2040adbd5
6 changed files with 156 additions and 37 deletions
|
@ -42,6 +42,8 @@ const float TIMELINE_CENTER_Y = 535;
|
|||
|
||||
enum { NumPages = 9 }; // one for each number key 1-9
|
||||
|
||||
const Vector ScreenMsgPos(210, 55);
|
||||
|
||||
|
||||
class TimelineRender;
|
||||
|
||||
|
@ -65,6 +67,11 @@ AnimationEditor *ae = 0;
|
|||
|
||||
KeyframeWidget *KeyframeWidget::movingWidget = 0;
|
||||
|
||||
static void notify(const std::string& s)
|
||||
{
|
||||
dsq->screenMessage(s, ScreenMsgPos);
|
||||
}
|
||||
|
||||
class TimelineTickRender : public RenderObject
|
||||
{
|
||||
public:
|
||||
|
@ -154,9 +161,9 @@ private:
|
|||
return;
|
||||
|
||||
if(ae->curPage == page)
|
||||
glColor4f(0.8, 0.8, 1, 0.5f);
|
||||
glColor4f(0.6f, 0.8f, 1, 0.5f);
|
||||
else
|
||||
glColor4f(0.5, 0.3, 0.3, 0.5f);
|
||||
glColor4f(0.5f, 0.3f, 0.3f, 0.5f);
|
||||
|
||||
const float h2 = height * 0.5f;
|
||||
glPushMatrix();
|
||||
|
@ -353,7 +360,7 @@ void AnimationEditor::cycleLerpType()
|
|||
{
|
||||
k2->copyAllButTime(k1);
|
||||
}
|
||||
dsq->screenMessage("Copied Loop Key");
|
||||
notify("Copied Loop Key");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -388,7 +395,7 @@ void AnimationEditor::resetScaleOrSave()
|
|||
std::ostringstream os;
|
||||
os << scale.x;
|
||||
if(!SDL_SetClipboardText(os.str().c_str()))
|
||||
dsq->screenMessage("Scale copied to clipboard");
|
||||
notify("Scale copied to clipboard");
|
||||
}
|
||||
else
|
||||
getCurrentPageSprite()->scale = Vector(1,1);
|
||||
|
@ -503,6 +510,8 @@ void AnimationEditor::applyState()
|
|||
addAction(ACTION_SWIMDOWN, KEY_DOWN, -1);
|
||||
|
||||
const float yoffs = -55;
|
||||
const float smallw = 50;
|
||||
const float gap = 5;
|
||||
|
||||
Quad *back = new Quad;
|
||||
{
|
||||
|
@ -639,18 +648,30 @@ void AnimationEditor::applyState()
|
|||
gridup->event.set(MakeFunctionEvent(AnimationEditor, incrTimelineGrid));
|
||||
addRenderObject(gridup, LR_MENU);
|
||||
|
||||
DebugButton *save = new DebugButton(0, 0, 150);
|
||||
DebugButton *save = new DebugButton(0, 0, 150 - smallw - gap);
|
||||
save->label->setText("Save");
|
||||
save->position = Vector(640, 100+yoffs);
|
||||
save->event.set(MakeFunctionEvent(AnimationEditor, saveFile));
|
||||
addRenderObject(save, LR_MENU);
|
||||
|
||||
DebugButton *load = new DebugButton(0, 0, 150);
|
||||
DebugButton *saveall = new DebugButton(0, 0, smallw);
|
||||
saveall->label->setText("All");
|
||||
saveall->position = save->position + 150/2 + smallw/2 + gap;
|
||||
saveall->event.set(MakeFunctionEvent(AnimationEditor, saveAll));
|
||||
addRenderObject(saveall, LR_MENU);
|
||||
|
||||
DebugButton *load = new DebugButton(0, 0, 150 - smallw - gap);
|
||||
load->label->setText("Reload");
|
||||
load->position = Vector(640, 70+yoffs);
|
||||
load->event.set(MakeFunctionEvent(AnimationEditor, reloadFile));
|
||||
addRenderObject(load, LR_MENU);
|
||||
|
||||
DebugButton *loadall = new DebugButton(0, 0, smallw);
|
||||
loadall->label->setText("All");
|
||||
loadall->position = load->position + 150/2 + smallw/2 + gap;
|
||||
loadall->event.set(MakeFunctionEvent(AnimationEditor, reloadAll));
|
||||
addRenderObject(loadall, LR_MENU);
|
||||
|
||||
DebugButton *reverseAnim = new DebugButton(0, 0, 150);
|
||||
reverseAnim->label->setText("reverseAnim");
|
||||
reverseAnim->position = Vector(10, 480+yoffs);
|
||||
|
@ -675,7 +696,7 @@ void AnimationEditor::applyState()
|
|||
addRenderObject(text, LR_HUD);
|
||||
|
||||
text2 = new DebugFont();
|
||||
text2->position = Vector(200,510+yoffs);
|
||||
text2->position = Vector(200,505+yoffs);
|
||||
text2->setFontSize(6);
|
||||
addRenderObject(text2, LR_HUD);
|
||||
|
||||
|
@ -684,6 +705,11 @@ void AnimationEditor::applyState()
|
|||
toptext->setFontSize(6);
|
||||
addRenderObject(toptext, LR_HUD);
|
||||
|
||||
btmtext = new DebugFont();
|
||||
btmtext->position = Vector(200,515+yoffs);
|
||||
btmtext->setFontSize(6);
|
||||
addRenderObject(btmtext, LR_HUD);
|
||||
|
||||
dsq->overlay->alpha.interpolateTo(0, 0.5f);
|
||||
|
||||
rebuildKeyframeWidgets();
|
||||
|
@ -878,6 +904,8 @@ void AnimationEditor::update(float dt)
|
|||
|
||||
SkeletalSprite *editSprite = getCurrentPageSprite();
|
||||
|
||||
const float tltime = getMouseTimelineTime();
|
||||
|
||||
{
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
@ -930,6 +958,14 @@ void AnimationEditor::update(float dt)
|
|||
char t2buf[128];
|
||||
sprintf(t2buf, "Bone x: %.3f, y: %.3f, rot: %.3f strip: %u pass: %d (%d)", ebdata.x, ebdata.y, ebdata.z, (unsigned)selectedStripPoint, pass, origpass);
|
||||
text2->setText(t2buf);
|
||||
|
||||
|
||||
const float t = getAnimTime();
|
||||
if(tltime >= 0)
|
||||
sprintf(t2buf, "t: %.4f, mouse at %.4f", t, tltime);
|
||||
else
|
||||
sprintf(t2buf, "t: %.4f", t);
|
||||
btmtext->setText(t2buf);
|
||||
}
|
||||
|
||||
if (editMode == AE_STRIP)
|
||||
|
@ -1037,19 +1073,45 @@ void AnimationEditor::update(float dt)
|
|||
}
|
||||
if (editMode == AE_SELECT)
|
||||
{
|
||||
if (!isAnimating())
|
||||
float t = 0;
|
||||
bool hastime = false;
|
||||
bool mod = false;
|
||||
if(core->mouse.buttons.right)
|
||||
{
|
||||
t = tltime;
|
||||
hastime = t >= 0;
|
||||
mod = true;
|
||||
}
|
||||
if (!hastime && !isAnimating())
|
||||
{
|
||||
if(Animation *a = editSprite->getCurrentAnimationOrNull())
|
||||
{
|
||||
SkeletalKeyframe *k = a->getKeyframe(currentKey);
|
||||
if (k)
|
||||
{
|
||||
t = k->t;
|
||||
hastime = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(hastime)
|
||||
{
|
||||
for(size_t i = 0; i < NumPages; ++i)
|
||||
getPageSprite(i)->setTime(k->t);
|
||||
{
|
||||
SkeletalSprite *spr = getPageSprite(i);
|
||||
if(Animation *a = spr->getCurrentAnimationOrNull())
|
||||
{
|
||||
float len = a->getAnimationLength();
|
||||
if(len && mod)
|
||||
t = fmodf(t, len);
|
||||
spr->setTime(t);
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; i < NumPages; ++i)
|
||||
getPageSprite(i)->updateBones();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(splinegrid && editingBone && editMode == AE_SPLINE && splinegrid->wasModified)
|
||||
{
|
||||
|
@ -1406,7 +1468,7 @@ void AnimationEditor::rmbd()
|
|||
pushUndo();
|
||||
cursorOffset = core->mouse.position;
|
||||
rotOffset = editingBone->rotation.z;
|
||||
editMode == AE_EDITING_ROT;
|
||||
editMode = AE_EDITING_ROT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1596,22 +1658,55 @@ void AnimationEditor::cloneBoneAhead()
|
|||
}
|
||||
}
|
||||
|
||||
bool AnimationEditor::savePage(size_t pg)
|
||||
{
|
||||
return getPageSprite(pg)->saveSkeletal(pages[pg].editingFile);
|
||||
}
|
||||
|
||||
void AnimationEditor::saveFile()
|
||||
{
|
||||
const std::string& editingFile = pages[curPage].editingFile;
|
||||
if(getCurrentPageSprite()->saveSkeletal(editingFile))
|
||||
dsq->screenMessage("Saved anim: " + editingFile);
|
||||
if(!getPageSprite(curPage)->isLoaded())
|
||||
{
|
||||
notify("Nothing to save");
|
||||
return;
|
||||
}
|
||||
|
||||
if(savePage(curPage))
|
||||
notify("Saved anim: " + pages[curPage].editingFile);
|
||||
else
|
||||
notify("FAILED TO SAVE: " + pages[curPage].editingFile);
|
||||
}
|
||||
|
||||
void AnimationEditor::saveAll()
|
||||
{
|
||||
bool ok = true;
|
||||
std::ostringstream os;
|
||||
for(size_t i = 0; i < NumPages; ++i)
|
||||
if(getPageSprite(i)->isLoaded())
|
||||
if(!savePage(i))
|
||||
{
|
||||
ok = false;
|
||||
os << pages[i].editingFile << " ";
|
||||
}
|
||||
|
||||
if(ok)
|
||||
notify("All saved");
|
||||
else
|
||||
dsq->screenMessage("FAILED TO SAVE: " + editingFile);
|
||||
notify("Failed to save: " + os.str());
|
||||
}
|
||||
|
||||
void AnimationEditor::loadFile(const char* fn)
|
||||
void AnimationEditor::reloadPage(size_t pg)
|
||||
{
|
||||
loadFile(pg, pages[pg].editingFile.c_str());
|
||||
}
|
||||
|
||||
void AnimationEditor::loadFile(size_t pg, const char* fn)
|
||||
{
|
||||
SkeletalSprite::clearCache();
|
||||
editingBone = 0;
|
||||
pages[curPage].clearUndoHistory();
|
||||
pages[pg].clearUndoHistory();
|
||||
//editSprite->position = Vector(0,0);
|
||||
pages[curPage].load(fn);
|
||||
pages[pg].load(fn);
|
||||
currentKey = 0;
|
||||
rebuildKeyframeWidgets();
|
||||
|
||||
|
@ -1623,11 +1718,16 @@ void AnimationEditor::loadFile(const char* fn)
|
|||
|
||||
void AnimationEditor::reloadFile()
|
||||
{
|
||||
const std::string& fn = pages[curPage].editingFile;
|
||||
if(fn.empty())
|
||||
load();
|
||||
if(getPageSprite(curPage)->isLoaded())
|
||||
reloadPage(curPage);
|
||||
else
|
||||
loadFile(fn.c_str());
|
||||
load(); // prompt what to load here
|
||||
}
|
||||
|
||||
void AnimationEditor::reloadAll()
|
||||
{
|
||||
for(size_t i = 0; i < NumPages; ++i)
|
||||
reloadPage(i);
|
||||
}
|
||||
|
||||
void AnimationEditor::goToTitle()
|
||||
|
@ -1685,7 +1785,7 @@ void AnimationEditor::selectAnim()
|
|||
rebuildKeyframeWidgets();
|
||||
}
|
||||
else
|
||||
dsq->screenMessage("No such anim name");
|
||||
notify("No such anim name");
|
||||
}
|
||||
|
||||
void AnimationEditor::reverseAnim()
|
||||
|
@ -1707,7 +1807,7 @@ void AnimationEditor::load()
|
|||
|
||||
std::string file = dsq->getUserInputString("Enter anim file to load:");
|
||||
if (file.empty()) return;
|
||||
loadFile(file.c_str());
|
||||
loadFile(curPage, file.c_str());
|
||||
}
|
||||
|
||||
void AnimationEditor::loadSkin()
|
||||
|
@ -1914,6 +2014,19 @@ void AnimationEditor::toggleGradient()
|
|||
bgGrad->alpha.x = float(bgGrad->alpha.x <= 0);
|
||||
}
|
||||
|
||||
float AnimationEditor::getMouseTimelineTime() const
|
||||
{
|
||||
Vector m = core->mouse.position;
|
||||
if(m.x > 0 && m.x < 800 && m.y > TIMELINE_CENTER_Y-TIMELINE_HEIGHT/2 && m.y < TIMELINE_CENTER_Y+TIMELINE_HEIGHT/2)
|
||||
{
|
||||
float t = (m.x - TIMELINE_X_OFFS) * TIMELINE_UNIT / TIMELINE_GRIDSIZE;
|
||||
t = std::max(t, 0.0f);
|
||||
return t;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Animation* AnimationEditor::getPageAnimation(size_t page) const
|
||||
{
|
||||
return pages[page].editSprite.getCurrentAnimation();
|
||||
|
@ -1951,7 +2064,7 @@ float AnimationEditor::getAnimTime() const
|
|||
for(size_t i = 0; i < NumPages; ++i)
|
||||
{
|
||||
SkeletalSprite *spr = getPageSprite(i);
|
||||
if(spr->isAnimating())
|
||||
if(spr->isLoaded() && spr->isAnimating())
|
||||
return spr->getAnimationLayer(0)->timer;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
void reorderKeys();
|
||||
|
||||
void saveFile();
|
||||
void loadFile(const char *fn);
|
||||
void loadFile(size_t pg, const char *fn);
|
||||
void reloadFile();
|
||||
|
||||
void nextAnim();
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
SkeletalSprite *editingBoneSprite; // updated together with editingBone
|
||||
int editingBonePage;
|
||||
EditMode editMode;
|
||||
DebugFont *text, *text2, *toptext;
|
||||
DebugFont *text, *text2, *toptext, *btmtext;
|
||||
|
||||
void goToTitle();
|
||||
|
||||
|
@ -157,6 +157,7 @@ public:
|
|||
DebugButton *bSplineAssist;
|
||||
void updateButtonLabels();
|
||||
void toggleGradient();
|
||||
float getMouseTimelineTime() const; // <0 when not in timeline area
|
||||
|
||||
Gradient *bgGrad;
|
||||
|
||||
|
@ -186,6 +187,11 @@ private:
|
|||
void selectPage8() { selectPage(8); }
|
||||
|
||||
void _stopExtraEditModes();
|
||||
|
||||
void saveAll();
|
||||
void reloadAll();
|
||||
bool savePage(size_t pg);
|
||||
void reloadPage(size_t pg);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2288,12 +2288,12 @@ void DSQ::clearMenu(float t)
|
|||
menu.clear();
|
||||
}
|
||||
|
||||
void DSQ::screenMessage(const std::string &msg)
|
||||
void DSQ::screenMessage(const std::string &msg, const Vector& pos)
|
||||
{
|
||||
debugLog(msg);
|
||||
|
||||
DebugFont *b = new DebugFont();
|
||||
b->position = Vector(16,300);
|
||||
b->position = pos;
|
||||
b->setFontSize(10);
|
||||
b->setText(msg);
|
||||
b->alpha = 0;
|
||||
|
|
|
@ -230,7 +230,7 @@ public:
|
|||
void spawnAllIngredients(const Vector &position);
|
||||
|
||||
int getEntityTypeIndexByName(std::string s);
|
||||
void screenMessage(const std::string &msg);
|
||||
void screenMessage(const std::string &msg, const Vector& pos = Vector(16,300));
|
||||
void _debugLog(const std::string &s) OVERRIDE;
|
||||
void toggleConsole();
|
||||
void toggleEffects();
|
||||
|
|
|
@ -602,7 +602,7 @@ void AnimationLayer::stopAnimation()
|
|||
}
|
||||
}
|
||||
|
||||
bool AnimationLayer::isAnimating()
|
||||
bool AnimationLayer::isAnimating() const
|
||||
{
|
||||
return animating;
|
||||
}
|
||||
|
@ -2103,9 +2103,9 @@ void SkeletalSprite::updateBones()
|
|||
|
||||
}
|
||||
|
||||
bool SkeletalSprite::isAnimating(int layer)
|
||||
bool SkeletalSprite::isAnimating(size_t layer) const
|
||||
{
|
||||
return animLayers[layer].animating;
|
||||
return layer < animLayers.size() && animLayers[layer].animating;
|
||||
}
|
||||
|
||||
void SkeletalSprite::setTimeMultiplier(float t, int layer)
|
||||
|
|
|
@ -214,7 +214,7 @@ public:
|
|||
void enqueueAnimation(const std::string& anim, int loop);
|
||||
float transitionAnimate(std::string anim, float time, int loop);
|
||||
void setTimeMultiplier(float t);
|
||||
bool isAnimating();
|
||||
bool isAnimating() const;
|
||||
bool contains(const Bone *b) const;
|
||||
void resetPass();
|
||||
|
||||
|
@ -270,7 +270,7 @@ public:
|
|||
|
||||
float transitionAnimate(const std::string& anim, float time, int loop=0, int layer=0);
|
||||
|
||||
bool isAnimating(int layer=0);
|
||||
bool isAnimating(size_t layer=0) const;
|
||||
|
||||
void setTimeMultiplier(float t, int layer=0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue