From 339490e3e91ea2162ae46e3bfef5d32263d85bfb Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sun, 17 Apr 2016 14:33:23 +0200 Subject: [PATCH] Implemnt AC_SET_PASS and AC_RESET_PASS bone commands --- Aquaria/AnimationEditor.cpp | 6 ++- BBGE/SkeletalSprite.cpp | 89 +++++++++++++++++++++++++------------ BBGE/SkeletalSprite.h | 10 ++++- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 904e028..d519f01 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -746,6 +746,8 @@ void AnimationEditor::update(float dt) } Vector ebdata; + int pass = 0; + int origpass = 0; if (editingBone) { @@ -753,11 +755,13 @@ void AnimationEditor::update(float dt) ebdata.x = editingBone->position.x; ebdata.y = editingBone->position.y; ebdata.z = editingBone->rotation.z; + pass = editingBone->getRenderPass(); + origpass = editingBone->originalRenderPass; } text->setText(os.str()); char t2buf[128]; - sprintf(t2buf, "Bone x: %.3f, y: %.3f, rot: %.3f strip: %d", ebdata.x, ebdata.y, ebdata.z, selectedStripPoint); + sprintf(t2buf, "Bone x: %.3f, y: %.3f, rot: %.3f strip: %d pass: %d (%d)", ebdata.x, ebdata.y, ebdata.z, selectedStripPoint, pass, origpass); text2->setText(t2buf); if (core->mouse.buttons.middle) diff --git a/BBGE/SkeletalSprite.cpp b/BBGE/SkeletalSprite.cpp index 8666bf4..144542c 100644 --- a/BBGE/SkeletalSprite.cpp +++ b/BBGE/SkeletalSprite.cpp @@ -78,6 +78,7 @@ Bone::Bone() : Quad() minDist = maxDist = 128; reverse = false; + originalRenderPass = 0; } /* void Bone::createStrip(bool vert, int num) @@ -358,6 +359,13 @@ void BoneCommand::parse(Bone *b, SimpleIStringStream &is) command = AC_SEGS_START; else if (type=="AC_SEGS_STOP") command = AC_SEGS_STOP; + else if (type == "AC_SET_PASS") + { + command = AC_SET_PASS; + is >> slot; + } + else if(type == "AC_RESET_PASS") + command = AC_RESET_PASS; } void BoneCommand::run() @@ -398,6 +406,12 @@ void BoneCommand::run() e->stop(); } break; + case AC_SET_PASS: + b->setRenderPass(slot); + break; + case AC_RESET_PASS: + b->setRenderPass(b->originalRenderPass); + break; } } @@ -558,6 +572,8 @@ bool AnimationLayer::createTransitionAnimation(const std::string& anim, float ti void AnimationLayer::stopAnimation() { + if(s->loaded && getCurrentAnimation()->resetPassOnEnd) + resetPass(); animating = false; if (!enqueuedAnimation.empty()) { @@ -577,6 +593,11 @@ float AnimationLayer::getAnimationLength() return animationLength; } +Animation::Animation() +: resetPassOnEnd(false) +{ +} + int Animation::getNumKeyframes() { return keyframes.size(); @@ -940,8 +961,8 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn) bone->SetAttribute("cp", os.str().c_str()); if (this->bones[i]->rbp) bone->SetAttribute("rbp", this->bones[i]->rbp); - if (this->bones[i]->getRenderPass()) - bone->SetAttribute("pass", this->bones[i]->getRenderPass()); + if (this->bones[i]->originalRenderPass) + bone->SetAttribute("pass", this->bones[i]->originalRenderPass); if (this->bones[i]->offset.x) bone->SetAttribute("offx", this->bones[i]->offset.x); if (this->bones[i]->offset.y) @@ -1005,6 +1026,8 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn) Animation *a = &this->animations[i]; XMLElement *animation = xml->NewElement("Animation"); animation->SetAttribute("name", a->name.c_str()); + if(a->resetPassOnEnd) + animation->SetAttribute("resetPassOnEnd", a->resetPassOnEnd); for (int j = 0; j < a->keyframes.size(); j++) { XMLElement *key = xml->NewElement("Key"); @@ -1438,7 +1461,9 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) } if (bone->Attribute("pass")) { - newb->setRenderPass(atoi(bone->Attribute("pass"))); + int pass = atoi(bone->Attribute("pass")); + newb->originalRenderPass = pass; + newb->setRenderPass(pass); } if (bone->Attribute("gc")) { @@ -1582,6 +1607,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) { Animation newAnimation; newAnimation.name = animation->Attribute("name"); + newAnimation.resetPassOnEnd = animation->BoolAttribute("resetPassOnEnd"); stringToLower(newAnimation.name); XMLElement *key = animation->FirstChildElement("Key"); @@ -1713,6 +1739,35 @@ void SkeletalSprite::setTime(float time, int layer) animLayers[layer].timer = time; } +void AnimationLayer::resetPass() +{ + for (int i = 0; i < s->bones.size(); i++) + { + Bone *b = s->bones[i]; + if (contains(b)) + b->setRenderPass(b->originalRenderPass); + } +} + +bool AnimationLayer::contains(const Bone *b) const +{ + const int idx = b->boneIdx; + if (!ignoreBones.empty()) + { + for (int j = 0; j < ignoreBones.size(); j++) + if (idx == ignoreBones[j]) + return false; + } + else if (!includeBones.empty()) + { + for (int j = 0; j < includeBones.size(); j++) + if (idx == includeBones[j]) + return true; + } + + return true; +} + void AnimationLayer::updateBones() { if (!animating && !(&s->animLayers[0] == this) && fallThru == 0) return; @@ -1755,10 +1810,8 @@ void AnimationLayer::updateBones() } lastNewKey = key2; - bool c = 0; for (int i = 0; i < s->bones.size(); i++) { - int idx = s->bones[i]->boneIdx; Bone *b = s->bones[i]; if (b->segmentChain == 1) @@ -1767,31 +1820,9 @@ void AnimationLayer::updateBones() } if (b->segmentChain < 2) { - c=0; - if (!ignoreBones.empty()) + if (b->animated != Bone::ANIM_NONE && contains(b)) { - for (int j = 0; j < ignoreBones.size(); j++) - { - if (idx == ignoreBones[j]) - { c=1; break; } - } - } - else if (!includeBones.empty()) - { - c = 1; - for (int j = 0; j < includeBones.size(); j++) - { - if (idx == includeBones[j]) - { c=0; break; } - } - } - if (b->animated==Bone::ANIM_NONE) - { - c = 1; - } - if (!c) - { - + int idx = b->boneIdx; BoneKeyframe *bkey1 = key1->getBoneKeyframe(idx); BoneKeyframe *bkey2 = key2->getBoneKeyframe(idx); if (bkey1 && bkey2) diff --git a/BBGE/SkeletalSprite.h b/BBGE/SkeletalSprite.h index 8e66a64..2aac9e6 100644 --- a/BBGE/SkeletalSprite.h +++ b/BBGE/SkeletalSprite.h @@ -33,7 +33,9 @@ enum AnimationCommand AC_SEGS_START , AC_FRM_SHOW , AC_SND_PLAY , - AC_SEGS_STOP + AC_SEGS_STOP, + AC_SET_PASS, + AC_RESET_PASS, }; class ParticleEffect; @@ -80,7 +82,7 @@ public: Vector segmentOffset; bool fileRenderQuad; - + int originalRenderPass; // stores the render pass originally set in the XML file. For AC_RESET_PASS. protected: int minDist, maxDist, reverse; @@ -131,6 +133,7 @@ public: class Animation { public: + Animation(); std::string name; typedef std::vector Keyframes; Keyframes keyframes; @@ -146,6 +149,7 @@ public: int getSkeletalKeyframeIndex(SkeletalKeyframe *skey); int getNumKeyframes(); void reverse(); + bool resetPassOnEnd; }; class SkeletalSprite; @@ -170,6 +174,8 @@ public: float transitionAnimate(std::string anim, float time, int loop); void setTimeMultiplier(float t); bool isAnimating(); + bool contains(const Bone *b) const; + void resetPass(); //float lerp(float v1, float v2, float dt, int lerpType); //----