mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-27 16:44:00 +00:00
Rework bone selection logic
A skeleton no longer has a "selectedBone". It's all in the anim editor now.
This commit is contained in:
parent
8cb19e528f
commit
0e1283a4d7
4 changed files with 128 additions and 126 deletions
|
@ -436,6 +436,8 @@ void AnimationEditor::applyState()
|
|||
editMode = AE_SELECT;
|
||||
editingBone = 0;
|
||||
editingBoneSprite = 0;
|
||||
editingBonePage = -1;
|
||||
editingBoneIdx = -1;
|
||||
currentKey = 0;
|
||||
splinegrid = 0;
|
||||
assistedSplineEdit = true;
|
||||
|
@ -874,10 +876,9 @@ void AnimationEditor::toggleMouseSelection()
|
|||
{
|
||||
if (dsq->isNested()) return;
|
||||
|
||||
if (mouseSelection)
|
||||
if (editingBone)
|
||||
{
|
||||
for(size_t i = 0; i < NumPages; ++i)
|
||||
getPageSprite(i)->updateSelectedBoneColor();
|
||||
editingBone->color = Vector(1,1,1);
|
||||
}
|
||||
|
||||
mouseSelection = !mouseSelection;
|
||||
|
@ -908,26 +909,6 @@ void AnimationEditor::moveBoneStripPoint(const Vector &mov)
|
|||
}
|
||||
}
|
||||
|
||||
void AnimationEditor::selectPrevBone()
|
||||
{
|
||||
if (dsq->isNested()) return;
|
||||
|
||||
if (editMode == AE_SELECT)
|
||||
{
|
||||
getCurrentPageSprite()->selectPrevBone();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationEditor::selectNextBone()
|
||||
{
|
||||
if (dsq->isNested()) return;
|
||||
|
||||
if (editMode == AE_SELECT)
|
||||
{
|
||||
getCurrentPageSprite()->selectNextBone();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationEditor::update(float dt)
|
||||
{
|
||||
StateObject::update(dt);
|
||||
|
@ -1199,17 +1180,17 @@ void AnimationEditor::nextKey()
|
|||
{
|
||||
if (dsq->isNested()) return;
|
||||
|
||||
SkeletalSprite *editSprite = getCurrentPageSprite();
|
||||
|
||||
if (editMode == AE_STRIP)
|
||||
{
|
||||
selectedStripPoint++;
|
||||
if (selectedStripPoint >= editingBoneSprite->getSelectedBone(false)->changeStrip.size()
|
||||
if (selectedStripPoint >= editingBone->changeStrip.size()
|
||||
&& selectedStripPoint > 0)
|
||||
selectedStripPoint --;
|
||||
}
|
||||
else
|
||||
{
|
||||
SkeletalSprite *editSprite = getCurrentPageSprite();
|
||||
|
||||
if (core->getCtrlState())
|
||||
{
|
||||
const std::vector<KeyframeWidget*>& keyframeWidgets = pages[curPage].timeline->getKeyframes();
|
||||
|
@ -1236,8 +1217,6 @@ void AnimationEditor::prevKey()
|
|||
{
|
||||
if (dsq->isNested()) return;
|
||||
|
||||
SkeletalSprite *editSprite = getCurrentPageSprite();
|
||||
|
||||
if (editMode == AE_STRIP)
|
||||
{
|
||||
if(selectedStripPoint > 0)
|
||||
|
@ -1245,6 +1224,8 @@ void AnimationEditor::prevKey()
|
|||
}
|
||||
else
|
||||
{
|
||||
SkeletalSprite *editSprite = getCurrentPageSprite();
|
||||
|
||||
if (core->getCtrlState())
|
||||
{
|
||||
const std::vector<KeyframeWidget*>& keyframeWidgets = pages[curPage].timeline->getKeyframes();
|
||||
|
@ -1743,6 +1724,7 @@ void AnimationEditor::loadFile(size_t pg, const char* fn)
|
|||
{
|
||||
SkeletalSprite::clearCache();
|
||||
editingBone = 0;
|
||||
editingBoneIdx = -1;
|
||||
pages[pg].clearUndoHistory();
|
||||
//editSprite->position = Vector(0,0);
|
||||
pages[pg].load(fn);
|
||||
|
@ -1958,9 +1940,14 @@ void AnimationEditor::updateEditingBone()
|
|||
|
||||
if(!mouseSelection)
|
||||
{
|
||||
if(!editingBoneSprite)
|
||||
editingBoneSprite = getCurrentPageSprite();
|
||||
editingBone = editingBoneSprite->getSelectedBone(false);
|
||||
editingBonePage = curPage;
|
||||
Bone *b = (size_t)editingBoneIdx < editingBoneSprite->bones.size() ? editingBoneSprite->bones[editingBoneIdx] : NULL; // this uses underflow at -1
|
||||
if(b && b->selectable)
|
||||
_selectBone(b);
|
||||
else
|
||||
selectNextBone();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1968,30 +1955,34 @@ void AnimationEditor::updateEditingBone()
|
|||
float mind;
|
||||
Bone *nearest = NULL;
|
||||
SkeletalSprite *nearestSpr = NULL;
|
||||
const Vector p = core->mouse.position;
|
||||
int page = -1;
|
||||
const Vector& p = core->mouse.position;
|
||||
int page = -1, idx = -1;
|
||||
for(size_t i = 0; i < NumPages; ++i)
|
||||
{
|
||||
SkeletalSprite& spr = pages[i].editSprite;
|
||||
if(spr.isLoaded())
|
||||
{
|
||||
if(Bone *b = spr.getSelectedBone(true))
|
||||
int k = spr.findSelectableBoneIdxClosestTo(p, true);
|
||||
if(k >= 0)
|
||||
{
|
||||
const float d = (b->position - p).getSquaredLength2D();
|
||||
Bone *b = spr.bones[k];
|
||||
const float d = (b->getWorldPosition() - p).getSquaredLength2D();
|
||||
if(!nearest || d < mind)
|
||||
{
|
||||
mind = d;
|
||||
nearest = b;
|
||||
nearestSpr = &spr;
|
||||
page = i;
|
||||
idx = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editingBone = nearest;
|
||||
editingBoneSprite = nearestSpr;
|
||||
editingBonePage = page;
|
||||
editingBoneIdx = idx;
|
||||
_selectBone(nearest);
|
||||
}
|
||||
|
||||
void AnimationEditor::showAllBones()
|
||||
|
@ -2065,6 +2056,8 @@ void AnimationEditor::updateButtonLabels()
|
|||
|
||||
void AnimationEditor::toggleGradient()
|
||||
{
|
||||
if (dsq->isNested()) return;
|
||||
|
||||
bgGrad->alpha.x = float(bgGrad->alpha.x <= 0);
|
||||
}
|
||||
|
||||
|
@ -2137,6 +2130,12 @@ void AnimationEditor::selectPage(unsigned page)
|
|||
if(editMode != AE_SELECT)
|
||||
return;
|
||||
|
||||
if(!mouseSelection)
|
||||
{
|
||||
editingBoneSprite = &pages[page].editSprite;
|
||||
updateEditingBone();
|
||||
}
|
||||
|
||||
curPage = page;
|
||||
}
|
||||
|
||||
|
@ -2179,3 +2178,79 @@ void AnimationEditor::applySplineGridToBone()
|
|||
}
|
||||
}
|
||||
|
||||
void AnimationEditor::_selectBone(Bone *b)
|
||||
{
|
||||
if(editingBone)
|
||||
editingBone->color = Vector(1,1,1);
|
||||
|
||||
if (b)
|
||||
b->color = mouseSelection ? Vector(1,0,0) : Vector(0.5,0.5,1);
|
||||
else
|
||||
{
|
||||
editingBonePage = -1;
|
||||
editingBoneSprite = NULL;
|
||||
editingBoneIdx = -1;
|
||||
}
|
||||
|
||||
editingBone = b;
|
||||
}
|
||||
|
||||
void AnimationEditor::selectPrevBone()
|
||||
{
|
||||
if (dsq->isNested() || mouseSelection || editMode != AE_SELECT)
|
||||
return;
|
||||
|
||||
SkeletalSprite *spr = editingBoneSprite ? editingBoneSprite : getCurrentPageSprite();
|
||||
if(spr->bones.empty())
|
||||
return;
|
||||
|
||||
size_t idx = editingBoneIdx;
|
||||
Bone *b = NULL;
|
||||
do
|
||||
{
|
||||
idx++;
|
||||
if(idx == editingBoneIdx)
|
||||
{
|
||||
idx = -1;
|
||||
break;
|
||||
}
|
||||
if (idx >= spr->bones.size())
|
||||
idx = 0;
|
||||
b = spr->bones[idx];
|
||||
}
|
||||
while (!b->selectable);
|
||||
editingBoneIdx = idx;
|
||||
editingBonePage = curPage;
|
||||
editingBoneSprite = spr;
|
||||
_selectBone(b);
|
||||
}
|
||||
|
||||
void AnimationEditor::selectNextBone()
|
||||
{
|
||||
if (dsq->isNested() || mouseSelection || editMode != AE_SELECT)
|
||||
return;
|
||||
|
||||
SkeletalSprite *spr = editingBoneSprite ? editingBoneSprite : getCurrentPageSprite();
|
||||
if(spr->bones.empty())
|
||||
return;
|
||||
|
||||
size_t idx = editingBoneIdx;
|
||||
Bone *b = NULL;
|
||||
do
|
||||
{
|
||||
idx--;
|
||||
if(idx == editingBoneIdx)
|
||||
{
|
||||
idx = -1;
|
||||
break;
|
||||
}
|
||||
if (idx >= spr->bones.size())
|
||||
idx = spr->bones.size()-1;
|
||||
b = spr->bones[idx];
|
||||
}
|
||||
while (!b->selectable);
|
||||
editingBoneIdx = idx;
|
||||
editingBonePage = curPage;
|
||||
editingBoneSprite = spr;
|
||||
_selectBone(b);
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ public:
|
|||
Bone *editingBone; // only changed when editMode == AE_SELECT
|
||||
SkeletalSprite *editingBoneSprite; // updated together with editingBone
|
||||
int editingBonePage;
|
||||
int editingBoneIdx; // editingBoneSprite->bones[editingBoneIdx] == editingBone
|
||||
EditMode editMode;
|
||||
DebugFont *text, *text2, *toptext, *btmtext;
|
||||
|
||||
|
@ -195,6 +196,8 @@ private:
|
|||
void reloadAll();
|
||||
bool savePage(size_t pg);
|
||||
void reloadPage(size_t pg);
|
||||
|
||||
void _selectBone(Bone *b); // NULL to unselect
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -775,7 +775,6 @@ SkeletalSprite::SkeletalSprite() : RenderObject()
|
|||
animLayers.resize(10);
|
||||
for (size_t i = 0; i < animLayers.size(); i++)
|
||||
animLayers[i].setSkeletalSprite(this);
|
||||
selectedBone = -1;
|
||||
}
|
||||
|
||||
SkeletalSprite::~SkeletalSprite()
|
||||
|
@ -2113,94 +2112,28 @@ void SkeletalSprite::setTimeMultiplier(float t, int layer)
|
|||
animLayers[layer].timeMultiplier = t;
|
||||
}
|
||||
|
||||
Bone* SkeletalSprite::getSelectedBone(bool mouseBased)
|
||||
int SkeletalSprite::findSelectableBoneIdxClosestTo(const Vector& pos, bool mustBeInBox) const
|
||||
{
|
||||
if (!loaded) return 0;
|
||||
if (mouseBased)
|
||||
{
|
||||
float closestDist = HUGE_VALF;
|
||||
Bone *b = 0;
|
||||
Vector p = core->mouse.position;
|
||||
int idx = -1;
|
||||
for (size_t i = 0; i < bones.size(); i++)
|
||||
{
|
||||
if (bones[i]->renderQuad || core->getShiftState())
|
||||
Bone *b = bones[i];
|
||||
if (b->selectable && b->renderQuad && (!mustBeInBox || b->isCoordinateInsideWorld(pos)))
|
||||
{
|
||||
bones[i]->color = Vector(1,1,1);
|
||||
if (bones[i]->selectable && bones[i]->renderQuad && bones[i]->isCoordinateInsideWorld(p))
|
||||
{
|
||||
float dist = (bones[i]->getWorldPosition() - p).getSquaredLength2D();
|
||||
float dist = (b->getWorldPosition() - pos).getSquaredLength2D();
|
||||
if (dist <= closestDist)
|
||||
{
|
||||
closestDist = dist;
|
||||
b = bones[i];
|
||||
selectedBone = i;
|
||||
idx = (int)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (b)
|
||||
{
|
||||
b->color = Vector(1,0,0);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
// else
|
||||
if (!bones.empty() && selectedBone < bones.size())
|
||||
return bones[selectedBone];
|
||||
|
||||
return 0;
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void SkeletalSprite::updateSelectedBoneColor()
|
||||
{
|
||||
if(!bones.size())
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < bones.size(); i++)
|
||||
{
|
||||
bones[i]->color = Vector(1,1,1);
|
||||
}
|
||||
Bone *b = bones[selectedBone];
|
||||
if (b)
|
||||
b->color = Vector(0.5,0.5,1);
|
||||
}
|
||||
|
||||
void SkeletalSprite::setSelectedBone(int b)
|
||||
{
|
||||
selectedBone = b;
|
||||
updateSelectedBoneColor();
|
||||
}
|
||||
|
||||
void SkeletalSprite::selectPrevBone()
|
||||
{
|
||||
const size_t oldsel = selectedBone;
|
||||
do
|
||||
{
|
||||
selectedBone++;
|
||||
if(selectedBone == oldsel)
|
||||
break;
|
||||
if (selectedBone >= bones.size())
|
||||
selectedBone = 0;
|
||||
}
|
||||
while (!bones[selectedBone]->selectable);
|
||||
updateSelectedBoneColor();
|
||||
}
|
||||
|
||||
void SkeletalSprite::selectNextBone()
|
||||
{
|
||||
const size_t oldsel = selectedBone;
|
||||
do
|
||||
{
|
||||
selectedBone--;
|
||||
if(selectedBone == oldsel)
|
||||
break;
|
||||
if (selectedBone >= bones.size())
|
||||
selectedBone = bones.size()-1;
|
||||
}
|
||||
while (!bones[selectedBone]->selectable);
|
||||
updateSelectedBoneColor();
|
||||
}
|
||||
|
||||
void BoneGridInterpolator::updateGridOnly(BoneKeyframe& bk, const Bone *bone)
|
||||
{
|
||||
|
|
|
@ -274,7 +274,7 @@ public:
|
|||
|
||||
void setTimeMultiplier(float t, int layer=0);
|
||||
|
||||
Bone* getSelectedBone(bool mouseBased = true);
|
||||
int findSelectableBoneIdxClosestTo(const Vector& pos, bool mustBeInBox = true) const; // -1 if none found, otherwise bones[idx] to get the bone
|
||||
Animation *getCurrentAnimation(size_t layer=0);
|
||||
Animation *getCurrentAnimationOrNull(size_t layer=0);
|
||||
|
||||
|
@ -284,23 +284,15 @@ public:
|
|||
void lastAnimation();
|
||||
void firstAnimation();
|
||||
bool selectAnimation(const char *name);
|
||||
void updateSelectedBoneColor();
|
||||
|
||||
|
||||
void setFreeze(bool f);
|
||||
|
||||
|
||||
|
||||
Animation *getAnimation(const std::string& anim);
|
||||
|
||||
std::vector<Animation> animations;
|
||||
std::vector<Bone*> bones;
|
||||
|
||||
inline size_t getSelectedBoneIdx(void) { return selectedBone; }
|
||||
void setSelectedBone(int b);
|
||||
void selectPrevBone();
|
||||
void selectNextBone();
|
||||
|
||||
bool isLoaded();
|
||||
size_t getNumAnimLayers() const { return animLayers.size(); }
|
||||
|
||||
|
@ -319,7 +311,6 @@ protected:
|
|||
bool frozen;
|
||||
RenderObject *animKeyNotify;
|
||||
bool loaded;
|
||||
size_t selectedBone;
|
||||
friend class AnimationLayer;
|
||||
std::vector<AnimationLayer> animLayers;
|
||||
Bone* initBone(int idx, std::string gfx, int pidx, bool rbp=false, std::string name="", float cr=0, bool fh=false, bool fv=false);
|
||||
|
|
Loading…
Add table
Reference in a new issue