Merge pull request #13059 from geron-cn/3.7.1

fix bug: BoneNode 's debugdraw can not be controlled by ancestor's vi…
This commit is contained in:
pandamicro 2015-07-30 20:31:34 +08:00
commit 3524af1ad6
4 changed files with 121 additions and 18 deletions

View File

@ -34,7 +34,7 @@ THE SOFTWARE.
NS_TIMELINE_BEGIN NS_TIMELINE_BEGIN
BoneNode::BoneNode() BoneNode::BoneNode()
: _isRackShow(true) : _isRackShow(false)
, _rackColor(cocos2d::Color4F::WHITE) , _rackColor(cocos2d::Color4F::WHITE)
, _rackLength(50) , _rackLength(50)
, _rackWidth(20) , _rackWidth(20)
@ -112,6 +112,10 @@ void BoneNode::removeChild(Node* child, bool cleanup /* = true */)
void BoneNode::removeFromBoneList(BoneNode* bone) void BoneNode::removeFromBoneList(BoneNode* bone)
{ {
_childBones.eraseObject(bone); _childBones.eraseObject(bone);
auto skeletonNode = dynamic_cast<SkeletonNode*>(bone);
if (skeletonNode != nullptr) // nested skeleton
return;
bone->_rootSkeleton = nullptr; bone->_rootSkeleton = nullptr;
auto subBones = bone->getAllSubBones(); auto subBones = bone->getAllSubBones();
subBones.pushBack(bone); subBones.pushBack(bone);
@ -323,6 +327,7 @@ bool BoneNode::init()
_rackLength = 50; _rackLength = 50;
_rackWidth = 20; _rackWidth = 20;
updateVertices(); updateVertices();
updateColor();
setGLProgramState(cocos2d::GLProgramState::getOrCreateWithGLProgramName(cocos2d::GLProgram::SHADER_NAME_POSITION_COLOR_NO_MVP)); setGLProgramState(cocos2d::GLProgramState::getOrCreateWithGLProgramName(cocos2d::GLProgram::SHADER_NAME_POSITION_COLOR_NO_MVP));
return true; return true;
} }
@ -398,12 +403,9 @@ cocos2d::Vector<BoneNode*> BoneNode::getAllSubBones() const
allBones.pushBack(top); allBones.pushBack(top);
boneStack.pop(); boneStack.pop();
auto topchildren = top->getChildBones(); auto topchildren = top->getChildBones();
if (topchildren.size() > 0) for (const auto& childbone : topchildren)
{ {
for (const auto& childbone : topchildren) boneStack.push(childbone);
{
boneStack.push(childbone);
}
} }
} }
return allBones; return allBones;
@ -426,9 +428,12 @@ cocos2d::Vector<SkinNode*> BoneNode::getAllSubSkins() const
void BoneNode::sortAllChildren() void BoneNode::sortAllChildren()
{ {
Node::sortAllChildren(); if (_reorderChildDirty)
std::sort(_childBones.begin(), _childBones.end(), cocos2d::nodeComparisonLess); {
std::sort(_boneSkins.begin(), _boneSkins.end(), cocos2d::nodeComparisonLess); std::sort(_childBones.begin(), _childBones.end(), cocos2d::nodeComparisonLess);
std::sort(_boneSkins.begin(), _boneSkins.end(), cocos2d::nodeComparisonLess);
Node::sortAllChildren();
}
} }
SkeletonNode* BoneNode::getRootSkeletonNode() const SkeletonNode* BoneNode::getRootSkeletonNode() const
@ -566,7 +571,7 @@ void BoneNode::setVisible(bool visible)
return; return;
Node::setVisible(visible); Node::setVisible(visible);
if (_isRackShow) if (_isRackShow && _rootSkeleton != nullptr)
{ {
_rootSkeleton->_subDrawBonesDirty = true; _rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true; _rootSkeleton->_subDrawBonesOrderDirty = true;

View File

@ -335,11 +335,26 @@ void SkeletonNode::addSkinGroup(std::string groupName, std::map<std::string, std
void SkeletonNode::updateAllDrawBones() void SkeletonNode::updateAllDrawBones()
{ {
_subDrawBones.clear(); _subDrawBones.clear();
for (const auto& bonepair : _subBonesMap) // get All Visible SubBones
// get all sub bones as visit with visible
std::stack<BoneNode*> boneStack;
for (const auto& bone : _childBones)
{ {
auto bone = bonepair.second;
if (bone->isVisible() && bone->isDebugDrawEnabled()) if (bone->isVisible() && bone->isDebugDrawEnabled())
_subDrawBones.pushBack(bone); boneStack.push(bone);
}
while (boneStack.size() > 0)
{
auto top = boneStack.top();
_subDrawBones.pushBack(top);
boneStack.pop();
auto topChildren = top->getChildBones();
for (const auto& childbone : topChildren)
{
if (childbone->isVisible() && childbone->isDebugDrawEnabled())
boneStack.push(childbone);
}
} }
_subDrawBonesDirty = false; _subDrawBonesDirty = false;
} }

View File

@ -343,9 +343,14 @@ void TestActionTimelineSkeleton::onEnter()
boneDrawsBtn->setPosition(Vec2(VisibleRect::right().x - 30, VisibleRect::top().y - 30)); boneDrawsBtn->setPosition(Vec2(VisibleRect::right().x - 30, VisibleRect::top().y - 30));
boneDrawsBtn->setTitleText("Draw bone"); boneDrawsBtn->setTitleText("Draw bone");
boneDrawsBtn->addClickEventListener([skeletonNode](Ref* sender) _isAllBonesDraw = true;
skeletonNode->setDebugDrawEnabled(_isAllBonesDraw);
setAllSubBonesDebugDraw(skeletonNode, _isAllBonesDraw);
boneDrawsBtn->addClickEventListener([skeletonNode, this](Ref* sender)
{ {
skeletonNode->setDebugDrawEnabled(!skeletonNode->isDebugDrawEnabled()); _isAllBonesDraw = !_isAllBonesDraw;
skeletonNode->setDebugDrawEnabled(_isAllBonesDraw);
setAllSubBonesDebugDraw(skeletonNode, _isAllBonesDraw);
}); });
@ -402,9 +407,6 @@ void TestActionTimelineSkeleton::onEnter()
debugDrawNode->drawRect(leftbottom, righttop, cocos2d::Color4F::YELLOW); debugDrawNode->drawRect(leftbottom, righttop, cocos2d::Color4F::YELLOW);
// bone boundingbox // bone boundingbox
/* // debug draw contentsize
rect = cocos2d::Rect(Vec2(.0f, .0f), weaponHandeBone->getContentSize());
rect = RectApplyAffineTransform(rect, weaponHandeBone->getNodeToParentAffineTransform());*/
rect = weaponHandeBone->getBoundingBox(); rect = weaponHandeBone->getBoundingBox();
leftbottom.x = rect.getMinX(); leftbottom.y = rect.getMinY(); leftbottom.x = rect.getMinX(); leftbottom.y = rect.getMinY();
righttop.x = rect.getMaxX(); righttop.y = rect.getMaxY(); righttop.x = rect.getMaxX(); righttop.y = rect.getMaxY();
@ -477,6 +479,74 @@ void TestActionTimelineSkeleton::onEnter()
_changedDisplays = false; _changedDisplays = false;
} }
}); });
/*********** test cases for bugs **********/
// bug: #13060 https://github.com/cocos2d/cocos2d-x/issues/13060
// bug: bone draw at the other edge when move to outside right edge.
BoneNode* bugtestBoneNode = BoneNode::create(500);
bugtestBoneNode->setRotation(-10);
bugtestBoneNode->retain();
bugtestBoneNode->setDebugDrawEnabled(true);
bugtestBoneNode->setPosition(Vec2(1500, VisibleRect::top().y - 90));
auto bug13060Btn = cocos2d::ui::Button::create();
bug13060Btn->setPosition(Vec2(VisibleRect::right().x - 30, VisibleRect::top().y - 90));
bug13060Btn->setTitleText("bug #13060");
addChild(bug13060Btn);
bug13060Btn->addClickEventListener([bugtestBoneNode, skeletonNode](Ref* sender)
{
if (bugtestBoneNode->getParent() == nullptr)
skeletonNode->addChild(bugtestBoneNode);
else
bugtestBoneNode->removeFromParent();
// bug fixed while bugtestBoneNode not be drawn at the bottom edge
});
// bug: #13005 https://github.com/cocos2d/cocos2d-x/issues/#13005
// bug: BoneNode 's debugdraw can not be controlled by ancestor's visible
auto leftleg = skeletonNode->getBoneNode("Layer26");
auto bug13005Btn = cocos2d::ui::Button::create();
addChild(bug13005Btn);
bug13005Btn->setPosition(Vec2(VisibleRect::right().x - 30, VisibleRect::top().y - 105));
bug13005Btn->setTitleText("bug #13005");
bug13005Btn->addClickEventListener([leftleg](Ref* sender)
{
leftleg->setVisible(!leftleg->isVisible());
// bug fixed while leftleg's child hide with leftleg's visible
});
/************* Skeleton nest Skeleton test *************/
auto nestSkeletonBtn = cocos2d::ui::Button::create();
nestSkeletonBtn->setTitleText("Skeleton Nest");
nestSkeletonBtn->setPosition(Vec2(VisibleRect::right().x - 40, VisibleRect::top().y - 120));
addChild(nestSkeletonBtn);
auto nestSkeleton = static_cast<SkeletonNode*>(CSLoader::createNode("ActionTimeline/DemoPlayer_skeleton.csb"));
nestSkeleton->retain();
ActionTimeline* nestSkeletonAction = action->clone();
nestSkeletonAction->retain();
nestSkeleton->runAction(nestSkeletonAction);
nestSkeleton->setScale(0.2f);
nestSkeleton->setPosition(150, 300);
nestSkeletonAction->gotoFrameAndPlay(0);
// show debug draws, or comment this for hide bones draws
for (auto& nestbonechild : nestSkeleton->getAllSubBonesMap())
{
nestbonechild.second->setDebugDrawEnabled(true);
}
nestSkeletonBtn->addClickEventListener([leftleg, nestSkeleton, nestSkeletonAction](Ref* sender)
{
if (nestSkeleton->getParent() == nullptr)
{
leftleg->addChild(nestSkeleton);
}
else
{
nestSkeleton->removeFromParentAndCleanup(false);
}
// bug fixed while leftleg's child hide with leftleg's visible
});
} }
std::string TestActionTimelineSkeleton::title() const std::string TestActionTimelineSkeleton::title() const
@ -484,6 +554,15 @@ std::string TestActionTimelineSkeleton::title() const
return "Test ActionTimeline Skeleton"; return "Test ActionTimeline Skeleton";
} }
void TestActionTimelineSkeleton::setAllSubBonesDebugDraw(SkeletonNode* rootSkeleton, bool isShow)
{
auto boneMap = rootSkeleton->getAllSubBonesMap();
for (auto& bonePair : boneMap)
{
bonePair.second->setDebugDrawEnabled(isShow);
}
}
// TestTimelineExtensionData // TestTimelineExtensionData
void TestTimelineExtensionData::onEnter() void TestTimelineExtensionData::onEnter()

View File

@ -125,9 +125,13 @@ public:
virtual void onEnter() override; virtual void onEnter() override;
virtual std::string title() const override; virtual std::string title() const override;
private: private:
void setAllSubBonesDebugDraw(cocostudio::timeline::SkeletonNode* rootSkeleton, bool isShow);
bool _changedDisplay; bool _changedDisplay;
bool _changedDisplays; bool _changedDisplays;
bool _isAllBonesDraw;
}; };
class TestTimelineExtensionData : public ActionTimelineBaseTest class TestTimelineExtensionData : public ActionTimelineBaseTest