mirror of https://github.com/axmolengine/axmol.git
Merge branch 'develop' of https://github.com/2youyouo2/cocos2d-x into develop
Conflicts: extensions/CocoStudio/Armature/CCArmature.cpp extensions/CocoStudio/Armature/CCBone.cpp extensions/CocoStudio/Armature/CCBone.h extensions/CocoStudio/Armature/display/CCDisplayManager.cpp extensions/CocoStudio/Armature/display/CCSkin.cpp extensions/CocoStudio/Armature/utils/CCDataReaderHelper.cpp
This commit is contained in:
commit
dfc40d354e
|
@ -0,0 +1,785 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "CCArmature.h"
|
||||
#include "utils/CCArmatureDataManager.h"
|
||||
#include "utils/CCArmatureDefine.h"
|
||||
#include "utils/CCDataReaderHelper.h"
|
||||
#include "datas/CCDatas.h"
|
||||
#include "display/CCSkin.h"
|
||||
|
||||
#if ENABLE_PHYSICS_BOX2D_DETECT
|
||||
#include "Box2D/Box2D.h"
|
||||
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT
|
||||
#include "chipmunk.h"
|
||||
#endif
|
||||
|
||||
|
||||
NS_CC_EXT_ARMATURE_BEGIN
|
||||
|
||||
Armature *Armature::create()
|
||||
{
|
||||
Armature *armature = new Armature();
|
||||
if (armature && armature->init())
|
||||
{
|
||||
armature->autorelease();
|
||||
return armature;
|
||||
}
|
||||
CC_SAFE_DELETE(armature);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Armature *Armature::create(const char *name)
|
||||
{
|
||||
Armature *armature = new Armature();
|
||||
if (armature && armature->init(name))
|
||||
{
|
||||
armature->autorelease();
|
||||
return armature;
|
||||
}
|
||||
CC_SAFE_DELETE(armature);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Armature *Armature::create(const char *name, Bone *parentBone)
|
||||
{
|
||||
Armature *armature = new Armature();
|
||||
if (armature && armature->init(name, parentBone))
|
||||
{
|
||||
armature->autorelease();
|
||||
return armature;
|
||||
}
|
||||
CC_SAFE_DELETE(armature);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Armature::Armature()
|
||||
: _armatureData(NULL)
|
||||
, _batchNode(NULL)
|
||||
, _atlas(NULL)
|
||||
, _parentBone(NULL)
|
||||
, _armatureTransformDirty(true)
|
||||
, _boneDic(NULL)
|
||||
, _topBoneList(NULL)
|
||||
, _animation(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Armature::~Armature(void)
|
||||
{
|
||||
if(NULL != _boneDic)
|
||||
{
|
||||
_boneDic->removeAllObjects();
|
||||
CC_SAFE_DELETE(_boneDic);
|
||||
}
|
||||
if (NULL != _topBoneList)
|
||||
{
|
||||
_topBoneList->removeAllObjects();
|
||||
CC_SAFE_DELETE(_topBoneList);
|
||||
}
|
||||
CC_SAFE_DELETE(_animation);
|
||||
}
|
||||
|
||||
|
||||
bool Armature::init()
|
||||
{
|
||||
return init(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool Armature::init(const char *name)
|
||||
{
|
||||
bool bRet = false;
|
||||
do
|
||||
{
|
||||
removeAllChildren();
|
||||
|
||||
CC_SAFE_DELETE(_animation);
|
||||
_animation = new ArmatureAnimation();
|
||||
_animation->init(this);
|
||||
|
||||
CC_SAFE_DELETE(_boneDic);
|
||||
_boneDic = new Dictionary();
|
||||
|
||||
CC_SAFE_DELETE(_topBoneList);
|
||||
_topBoneList = new Array();
|
||||
_topBoneList->init();
|
||||
|
||||
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
|
||||
|
||||
|
||||
_name = name == NULL ? "" : name;
|
||||
|
||||
ArmatureDataManager *armatureDataManager = ArmatureDataManager::getInstance();
|
||||
|
||||
if(_name.length() != 0)
|
||||
{
|
||||
_name = name;
|
||||
|
||||
AnimationData *animationData = armatureDataManager->getAnimationData(name);
|
||||
CCASSERT(animationData, "AnimationData not exist! ");
|
||||
|
||||
_animation->setAnimationData(animationData);
|
||||
|
||||
|
||||
ArmatureData *armatureData = armatureDataManager->getArmatureData(name);
|
||||
CCASSERT(armatureData, "");
|
||||
|
||||
_armatureData = armatureData;
|
||||
|
||||
|
||||
DictElement *_element = NULL;
|
||||
Dictionary *boneDataDic = &armatureData->boneDataDic;
|
||||
CCDICT_FOREACH(boneDataDic, _element)
|
||||
{
|
||||
Bone *bone = createBone(_element->getStrKey());
|
||||
|
||||
//! init bone's Tween to 1st movement's 1st frame
|
||||
do
|
||||
{
|
||||
|
||||
MovementData *movData = animationData->getMovement(animationData->movementNames.at(0).c_str());
|
||||
CC_BREAK_IF(!movData);
|
||||
|
||||
MovementBoneData *movBoneData = movData->getMovementBoneData(bone->getName().c_str());
|
||||
CC_BREAK_IF(!movBoneData || movBoneData->frameList.count() <= 0);
|
||||
|
||||
FrameData *frameData = movBoneData->getFrameData(0);
|
||||
CC_BREAK_IF(!frameData);
|
||||
|
||||
bone->getTweenData()->copy(frameData);
|
||||
bone->changeDisplayByIndex(frameData->displayIndex, false);
|
||||
}
|
||||
while (0);
|
||||
}
|
||||
|
||||
update(0);
|
||||
updateOffsetPoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
_name = "new_armature";
|
||||
_armatureData = ArmatureData::create();
|
||||
_armatureData->name = _name;
|
||||
|
||||
AnimationData *animationData = AnimationData::create();
|
||||
animationData->name = _name;
|
||||
|
||||
armatureDataManager->addArmatureData(_name.c_str(), _armatureData);
|
||||
armatureDataManager->addAnimationData(_name.c_str(), animationData);
|
||||
|
||||
_animation->setAnimationData(animationData);
|
||||
|
||||
}
|
||||
|
||||
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
|
||||
|
||||
unscheduleUpdate();
|
||||
scheduleUpdate();
|
||||
|
||||
setCascadeOpacityEnabled(true);
|
||||
setCascadeColorEnabled(true);
|
||||
|
||||
bRet = true;
|
||||
}
|
||||
while (0);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool Armature::init(const char *name, Bone *parentBone)
|
||||
{
|
||||
_parentBone = parentBone;
|
||||
return init(name);
|
||||
}
|
||||
|
||||
|
||||
Bone *Armature::createBone(const char *boneName)
|
||||
{
|
||||
Bone *existedBone = getBone(boneName);
|
||||
if(existedBone != NULL)
|
||||
return existedBone;
|
||||
|
||||
BoneData *boneData = (BoneData *)_armatureData->getBoneData(boneName);
|
||||
std::string parentName = boneData->parentName;
|
||||
|
||||
Bone *bone = NULL;
|
||||
|
||||
if( parentName.length() != 0 )
|
||||
{
|
||||
createBone(parentName.c_str());
|
||||
bone = Bone::create(boneName);
|
||||
addBone(bone, parentName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
bone = Bone::create(boneName);
|
||||
addBone(bone, "");
|
||||
}
|
||||
|
||||
bone->setBoneData(boneData);
|
||||
bone->getDisplayManager()->changeDisplayByIndex(-1, false);
|
||||
|
||||
return bone;
|
||||
}
|
||||
|
||||
|
||||
void Armature::addBone(Bone *bone, const char *parentName)
|
||||
{
|
||||
CCASSERT( bone != NULL, "Argument must be non-nil");
|
||||
CCASSERT(_boneDic->objectForKey(bone->getName()) == NULL, "bone already added. It can't be added again");
|
||||
|
||||
if (NULL != parentName)
|
||||
{
|
||||
Bone *boneParent = (Bone *)_boneDic->objectForKey(parentName);
|
||||
if (boneParent)
|
||||
{
|
||||
boneParent->addChildBone(bone);
|
||||
}
|
||||
else
|
||||
{
|
||||
_topBoneList->addObject(bone);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_topBoneList->addObject(bone);
|
||||
}
|
||||
|
||||
bone->setArmature(this);
|
||||
|
||||
_boneDic->setObject(bone, bone->getName());
|
||||
addChild(bone);
|
||||
}
|
||||
|
||||
|
||||
void Armature::removeBone(Bone *bone, bool recursion)
|
||||
{
|
||||
CCASSERT(bone != NULL, "bone must be added to the bone dictionary!");
|
||||
|
||||
bone->setArmature(NULL);
|
||||
bone->removeFromParent(recursion);
|
||||
|
||||
if (_topBoneList->containsObject(bone))
|
||||
{
|
||||
_topBoneList->removeObject(bone);
|
||||
}
|
||||
_boneDic->removeObjectForKey(bone->getName());
|
||||
removeChild(bone, true);
|
||||
}
|
||||
|
||||
|
||||
Bone *Armature::getBone(const char *name) const
|
||||
{
|
||||
return (Bone *)_boneDic->objectForKey(name);
|
||||
}
|
||||
|
||||
|
||||
void Armature::changeBoneParent(Bone *bone, const char *parentName)
|
||||
{
|
||||
CCASSERT(bone != NULL, "bone must be added to the bone dictionary!");
|
||||
|
||||
if(bone->getParentBone())
|
||||
{
|
||||
bone->getParentBone()->getChildren()->removeObject(bone);
|
||||
bone->setParentBone(NULL);
|
||||
}
|
||||
|
||||
if (parentName != NULL)
|
||||
{
|
||||
Bone *boneParent = (Bone *)_boneDic->objectForKey(parentName);
|
||||
|
||||
if (boneParent)
|
||||
{
|
||||
boneParent->addChildBone(bone);
|
||||
if (_topBoneList->containsObject(bone))
|
||||
{
|
||||
_topBoneList->removeObject(bone);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_topBoneList->addObject(bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary *Armature::getBoneDic()
|
||||
{
|
||||
return _boneDic;
|
||||
}
|
||||
|
||||
const AffineTransform &Armature::getNodeToParentTransform() const
|
||||
{
|
||||
if (_transformDirty)
|
||||
{
|
||||
_armatureTransformDirty = true;
|
||||
|
||||
// Translate values
|
||||
float x = _position.x;
|
||||
float y = _position.y;
|
||||
|
||||
if (_ignoreAnchorPointForPosition)
|
||||
{
|
||||
x += _anchorPointInPoints.x;
|
||||
y += _anchorPointInPoints.y;
|
||||
}
|
||||
|
||||
// Rotation values
|
||||
// Change rotation code to handle X and Y
|
||||
// If we skew with the exact same value for both x and y then we're simply just rotating
|
||||
float cx = 1, sx = 0, cy = 1, sy = 0;
|
||||
if (_rotationX || _rotationY)
|
||||
{
|
||||
float radiansX = -CC_DEGREES_TO_RADIANS(_rotationX);
|
||||
float radiansY = -CC_DEGREES_TO_RADIANS(_rotationY);
|
||||
cx = cosf(radiansX);
|
||||
sx = sinf(radiansX);
|
||||
cy = cosf(radiansY);
|
||||
sy = sinf(radiansY);
|
||||
}
|
||||
|
||||
// Add offset point
|
||||
x += cy * _offsetPoint.x * _scaleX + -sx * _offsetPoint.y * _scaleY;
|
||||
y += sy * _offsetPoint.x * _scaleX + cx * _offsetPoint.y * _scaleY;
|
||||
|
||||
bool needsSkewMatrix = ( _skewX || _skewY );
|
||||
|
||||
// optimization:
|
||||
// inline anchor point calculation if skew is not needed
|
||||
// Adjusted transform calculation for rotational skew
|
||||
if (! needsSkewMatrix && !_anchorPointInPoints.equals(Point::ZERO))
|
||||
{
|
||||
x += cy * -_anchorPointInPoints.x * _scaleX + -sx * -_anchorPointInPoints.y * _scaleY;
|
||||
y += sy * -_anchorPointInPoints.x * _scaleX + cx * -_anchorPointInPoints.y * _scaleY;
|
||||
}
|
||||
|
||||
|
||||
// Build Transform Matrix
|
||||
// Adjusted transform calculation for rotational skew
|
||||
_transform = AffineTransformMake( cy * _scaleX, sy * _scaleX,
|
||||
-sx * _scaleY, cx * _scaleY,
|
||||
x, y );
|
||||
|
||||
// XXX: Try to inline skew
|
||||
// If skew is needed, apply skew and then anchor point
|
||||
if (needsSkewMatrix)
|
||||
{
|
||||
AffineTransform skewMatrix = AffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(_skewY)),
|
||||
tanf(CC_DEGREES_TO_RADIANS(_skewX)), 1.0f,
|
||||
0.0f, 0.0f );
|
||||
_transform = AffineTransformConcat(skewMatrix, _transform);
|
||||
|
||||
// adjust anchor point
|
||||
if (!_anchorPointInPoints.equals(Point::ZERO))
|
||||
{
|
||||
_transform = AffineTransformTranslate(_transform, -_anchorPointInPoints.x, -_anchorPointInPoints.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (_additionalTransformDirty)
|
||||
{
|
||||
_transform = AffineTransformConcat(_transform, _additionalTransform);
|
||||
_additionalTransformDirty = false;
|
||||
}
|
||||
|
||||
_transformDirty = false;
|
||||
}
|
||||
|
||||
return _transform;
|
||||
}
|
||||
|
||||
void Armature::updateOffsetPoint()
|
||||
{
|
||||
// Set contentsize and Calculate anchor point.
|
||||
Rect rect = getBoundingBox();
|
||||
setContentSize(rect.size);
|
||||
_offsetPoint = Point(-rect.origin.x, -rect.origin.y);
|
||||
if (rect.size.width != 0 && rect.size.height != 0)
|
||||
{
|
||||
setAnchorPoint(Point(_offsetPoint.x / rect.size.width, _offsetPoint.y / rect.size.height));
|
||||
}
|
||||
}
|
||||
|
||||
void Armature::setAnimation(ArmatureAnimation *animation)
|
||||
{
|
||||
_animation = animation;
|
||||
}
|
||||
|
||||
ArmatureAnimation *Armature::getAnimation()
|
||||
{
|
||||
return _animation;
|
||||
}
|
||||
|
||||
bool Armature::getArmatureTransformDirty()
|
||||
{
|
||||
return _armatureTransformDirty;
|
||||
}
|
||||
|
||||
void Armature::update(float dt)
|
||||
{
|
||||
_animation->update(dt);
|
||||
|
||||
Object *object = NULL;
|
||||
CCARRAY_FOREACH(_topBoneList, object)
|
||||
{
|
||||
static_cast<Bone *>(object)->update(dt);
|
||||
}
|
||||
|
||||
_armatureTransformDirty = false;
|
||||
}
|
||||
|
||||
void Armature::draw()
|
||||
{
|
||||
if (_parentBone == NULL)
|
||||
{
|
||||
CC_NODE_DRAW_SETUP();
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
}
|
||||
|
||||
Object *object = NULL;
|
||||
CCARRAY_FOREACH(_children, object)
|
||||
{
|
||||
if (Bone *bone = dynamic_cast<Bone *>(object))
|
||||
{
|
||||
DisplayManager *displayManager = bone->getDisplayManager();
|
||||
Node *node = displayManager->getDisplayRenderNode();
|
||||
|
||||
if (NULL == node)
|
||||
continue;
|
||||
|
||||
switch (displayManager->getCurrentDecorativeDisplay()->getDisplayData()->displayType)
|
||||
{
|
||||
case CS_DISPLAY_SPRITE:
|
||||
{
|
||||
Skin *skin = static_cast<Skin *>(node);
|
||||
|
||||
TextureAtlas *textureAtlas = skin->getTextureAtlas();
|
||||
BlendType blendType = bone->getBlendType();
|
||||
if(_atlas != textureAtlas || blendType != BLEND_NORMAL)
|
||||
{
|
||||
if (_atlas)
|
||||
{
|
||||
_atlas->drawQuads();
|
||||
_atlas->removeAllQuads();
|
||||
}
|
||||
}
|
||||
|
||||
_atlas = textureAtlas;
|
||||
if (_atlas->getCapacity() == _atlas->getTotalQuads() && !_atlas->resizeCapacity(_atlas->getCapacity() * 2))
|
||||
return;
|
||||
|
||||
skin->updateTransform();
|
||||
|
||||
if (blendType != BLEND_NORMAL)
|
||||
{
|
||||
updateBlendType(blendType);
|
||||
_atlas->drawQuads();
|
||||
_atlas->removeAllQuads();
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CS_DISPLAY_ARMATURE:
|
||||
{
|
||||
Armature *armature = static_cast<Armature *>(node);
|
||||
|
||||
TextureAtlas *textureAtlas = armature->getTextureAtlas();
|
||||
if(_atlas != textureAtlas)
|
||||
{
|
||||
if (_atlas)
|
||||
{
|
||||
_atlas->drawQuads();
|
||||
_atlas->removeAllQuads();
|
||||
}
|
||||
}
|
||||
armature->draw();
|
||||
|
||||
_atlas = armature->getTextureAtlas();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (_atlas)
|
||||
{
|
||||
_atlas->drawQuads();
|
||||
_atlas->removeAllQuads();
|
||||
}
|
||||
node->visit();
|
||||
|
||||
CC_NODE_DRAW_SETUP();
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Node *node = dynamic_cast<Node *>(object))
|
||||
{
|
||||
if (_atlas)
|
||||
{
|
||||
_atlas->drawQuads();
|
||||
_atlas->removeAllQuads();
|
||||
}
|
||||
node->visit();
|
||||
|
||||
CC_NODE_DRAW_SETUP();
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
}
|
||||
}
|
||||
|
||||
if(_atlas && !_batchNode && _parentBone == NULL)
|
||||
{
|
||||
_atlas->drawQuads();
|
||||
_atlas->removeAllQuads();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Armature::updateBlendType(BlendType blendType)
|
||||
{
|
||||
BlendFunc blendFunc;
|
||||
switch (blendType)
|
||||
{
|
||||
case BLEND_NORMAL:
|
||||
{
|
||||
blendFunc.src = CC_BLEND_SRC;
|
||||
blendFunc.dst = CC_BLEND_DST;
|
||||
}
|
||||
break;
|
||||
case BLEND_ADD:
|
||||
{
|
||||
blendFunc.src = GL_SRC_ALPHA;
|
||||
blendFunc.dst = GL_ONE;
|
||||
}
|
||||
break;
|
||||
case BLEND_MULTIPLY:
|
||||
{
|
||||
blendFunc.src = GL_DST_COLOR;
|
||||
blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
break;
|
||||
case BLEND_SCREEN:
|
||||
{
|
||||
blendFunc.src = GL_ONE;
|
||||
blendFunc.dst = GL_ONE_MINUS_SRC_COLOR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
blendFunc.src = CC_BLEND_SRC;
|
||||
blendFunc.dst = CC_BLEND_DST;
|
||||
}
|
||||
break;
|
||||
}
|
||||
GL::blendFunc(blendFunc.src, blendFunc.dst);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Armature::visit()
|
||||
{
|
||||
// quick return if not visible. children won't be drawn.
|
||||
if (!_visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
kmGLPushMatrix();
|
||||
|
||||
if (_grid && _grid->isActive())
|
||||
{
|
||||
_grid->beforeDraw();
|
||||
}
|
||||
|
||||
transform();
|
||||
sortAllChildren();
|
||||
draw();
|
||||
updateEventPriorityIndex();
|
||||
|
||||
// reset for next frame
|
||||
_orderOfArrival = 0;
|
||||
|
||||
if (_grid && _grid->isActive())
|
||||
{
|
||||
_grid->afterDraw(this);
|
||||
}
|
||||
|
||||
kmGLPopMatrix();
|
||||
}
|
||||
|
||||
Rect Armature::getBoundingBox() const
|
||||
{
|
||||
float minx, miny, maxx, maxy = 0;
|
||||
|
||||
bool first = true;
|
||||
|
||||
Rect boundingBox = Rect(0, 0, 0, 0);
|
||||
|
||||
Object *object = NULL;
|
||||
CCARRAY_FOREACH(_children, object)
|
||||
{
|
||||
if (Bone *bone = dynamic_cast<Bone *>(object))
|
||||
{
|
||||
Rect r = bone->getDisplayManager()->getBoundingBox();
|
||||
|
||||
if(first)
|
||||
{
|
||||
minx = r.getMinX();
|
||||
miny = r.getMinY();
|
||||
maxx = r.getMaxX();
|
||||
maxy = r.getMaxY();
|
||||
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
minx = r.getMinX() < boundingBox.getMinX() ? r.getMinX() : boundingBox.getMinX();
|
||||
miny = r.getMinY() < boundingBox.getMinY() ? r.getMinY() : boundingBox.getMinY();
|
||||
maxx = r.getMaxX() > boundingBox.getMaxX() ? r.getMaxX() : boundingBox.getMaxX();
|
||||
maxy = r.getMaxY() > boundingBox.getMaxY() ? r.getMaxY() : boundingBox.getMaxY();
|
||||
}
|
||||
|
||||
boundingBox.setRect(minx, miny, maxx - minx, maxy - miny);
|
||||
}
|
||||
}
|
||||
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
Bone *Armature::getBoneAtPoint(float x, float y)
|
||||
{
|
||||
int length = _children->count();
|
||||
Bone *bs;
|
||||
|
||||
for(int i = length - 1; i >= 0; i--)
|
||||
{
|
||||
bs = static_cast<Bone *>( _children->getObjectAtIndex(i) );
|
||||
if(bs->getDisplayManager()->containPoint(x, y))
|
||||
{
|
||||
return bs;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if ENABLE_PHYSICS_BOX2D_DETECT
|
||||
b2Body *Armature::getBody()
|
||||
{
|
||||
return _body;
|
||||
}
|
||||
|
||||
void Armature::setBody(b2Body *body)
|
||||
{
|
||||
if (_body == body)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_body = body;
|
||||
_body->SetUserData(this);
|
||||
|
||||
Object *object = NULL;
|
||||
CCARRAY_FOREACH(_children, object)
|
||||
{
|
||||
if (Bone *bone = dynamic_cast<Bone *>(object))
|
||||
{
|
||||
Array *displayList = bone->getDisplayManager()->getDecorativeDisplayList();
|
||||
|
||||
Object *displayObject = NULL;
|
||||
CCARRAY_FOREACH(displayList, displayObject)
|
||||
{
|
||||
ColliderDetector *detector = ((DecorativeDisplay *)displayObject)->getColliderDetector();
|
||||
if (detector != NULL)
|
||||
{
|
||||
detector->setBody(_body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b2Fixture *Armature::getShapeList()
|
||||
{
|
||||
if (_body)
|
||||
{
|
||||
return _body->GetFixtureList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT
|
||||
cpBody *Armature::getBody()
|
||||
{
|
||||
return _body;
|
||||
}
|
||||
|
||||
void Armature::setBody(cpBody *body)
|
||||
{
|
||||
if (_body == body)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_body = body;
|
||||
_body->data = this;
|
||||
|
||||
Object *object = NULL;
|
||||
CCARRAY_FOREACH(_children, object)
|
||||
{
|
||||
if (Bone *bone = dynamic_cast<Bone *>(object))
|
||||
{
|
||||
Array *displayList = bone->getDisplayManager()->getDecorativeDisplayList();
|
||||
|
||||
Object *displayObject = NULL;
|
||||
CCARRAY_FOREACH(displayList, displayObject)
|
||||
{
|
||||
ColliderDetector *detector = ((DecorativeDisplay *)displayObject)->getColliderDetector();
|
||||
if (detector != NULL)
|
||||
{
|
||||
detector->setBody(_body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpShape *Armature::getShapeList()
|
||||
{
|
||||
if (_body)
|
||||
{
|
||||
return _body->shapeList_private;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
NS_CC_EXT_ARMATURE_END
|
|
@ -0,0 +1,401 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "CCBone.h"
|
||||
#include "CCArmature.h"
|
||||
#include "utils/CCUtilMath.h"
|
||||
#include "utils/CCArmatureDataManager.h"
|
||||
#include "utils/CCTransformHelp.h"
|
||||
#include "display/CCDisplayManager.h"
|
||||
|
||||
NS_CC_EXT_ARMATURE_BEGIN
|
||||
|
||||
Bone *Bone::create()
|
||||
{
|
||||
|
||||
Bone *pBone = new Bone();
|
||||
if (pBone && pBone->init())
|
||||
{
|
||||
pBone->autorelease();
|
||||
return pBone;
|
||||
}
|
||||
CC_SAFE_DELETE(pBone);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
Bone *Bone::create(const char *name)
|
||||
{
|
||||
|
||||
Bone *pBone = new Bone();
|
||||
if (pBone && pBone->init(name))
|
||||
{
|
||||
pBone->autorelease();
|
||||
return pBone;
|
||||
}
|
||||
CC_SAFE_DELETE(pBone);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bone::Bone()
|
||||
{
|
||||
_tweenData = NULL;
|
||||
_parentBone = NULL;
|
||||
_armature = NULL;
|
||||
_childArmature = NULL;
|
||||
_boneData = NULL;
|
||||
_tween = NULL;
|
||||
_tween = NULL;
|
||||
_children = NULL;
|
||||
_displayManager = NULL;
|
||||
_ignoreMovementBoneData = false;
|
||||
_worldTransform = AffineTransformMake(1, 0, 0, 1, 0, 0);
|
||||
_boneTransformDirty = true;
|
||||
_blendType = BLEND_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
Bone::~Bone(void)
|
||||
{
|
||||
CC_SAFE_DELETE(_tweenData);
|
||||
CC_SAFE_DELETE(_children);
|
||||
CC_SAFE_DELETE(_tween);
|
||||
CC_SAFE_DELETE(_displayManager);
|
||||
|
||||
if(_boneData)
|
||||
{
|
||||
_boneData->release();
|
||||
}
|
||||
|
||||
CC_SAFE_RELEASE(_childArmature);
|
||||
}
|
||||
|
||||
bool Bone::init()
|
||||
{
|
||||
return Bone::init(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool Bone::init(const char *name)
|
||||
{
|
||||
bool bRet = false;
|
||||
do
|
||||
{
|
||||
|
||||
if(NULL != name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
CC_SAFE_DELETE(_tweenData);
|
||||
_tweenData = new FrameData();
|
||||
|
||||
CC_SAFE_DELETE(_tween);
|
||||
_tween = new Tween();
|
||||
_tween->init(this);
|
||||
|
||||
CC_SAFE_DELETE(_displayManager);
|
||||
_displayManager = new DisplayManager();
|
||||
_displayManager->init(this);
|
||||
|
||||
|
||||
bRet = true;
|
||||
}
|
||||
while (0);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void Bone::setBoneData(BoneData *boneData)
|
||||
{
|
||||
CCASSERT(NULL != boneData, "_boneData must not be NULL");
|
||||
|
||||
_boneData = boneData;
|
||||
_boneData->retain();
|
||||
|
||||
_name = _boneData->name;
|
||||
_ZOrder = _boneData->zOrder;
|
||||
|
||||
_displayManager->initDisplayList(boneData);
|
||||
}
|
||||
|
||||
BoneData *Bone::getBoneData()
|
||||
{
|
||||
return _boneData;
|
||||
}
|
||||
|
||||
void Bone::setArmature(Armature *armature)
|
||||
{
|
||||
_armature = armature;
|
||||
if (_armature)
|
||||
{
|
||||
_tween->setAnimation(_armature->getAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Armature *Bone::getArmature()
|
||||
{
|
||||
return _armature;
|
||||
}
|
||||
|
||||
void Bone::update(float delta)
|
||||
{
|
||||
if (_parentBone)
|
||||
_boneTransformDirty = _boneTransformDirty || _parentBone->isTransformDirty();
|
||||
|
||||
CCBone *armatureParentBone = _armature->getParentBone();
|
||||
if (armatureParentBone && !_boneTransformDirty)
|
||||
{
|
||||
_boneTransformDirty = armatureParentBone->isTransformDirty();
|
||||
}
|
||||
|
||||
|
||||
if (_boneTransformDirty)
|
||||
{
|
||||
if (_armature->getArmatureData()->dataVersion >= VERSION_COMBINED)
|
||||
{
|
||||
TransformHelp::nodeConcat(*_tweenData, *_boneData);
|
||||
_tweenData->scaleX -= 1;
|
||||
_tweenData->scaleY -= 1;
|
||||
}
|
||||
|
||||
TransformHelp::nodeToMatrix(*_tweenData, _worldTransform);
|
||||
|
||||
_worldTransform = AffineTransformConcat(getNodeToParentTransform(), _worldTransform);
|
||||
|
||||
if(_parentBone)
|
||||
{
|
||||
_worldTransform = AffineTransformConcat(_worldTransform, _parentBone->_worldTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (armatureParentBone)
|
||||
{
|
||||
_worldTransform = CCAffineTransformConcat(_worldTransform, armatureParentBone->getNodeToArmatureTransform());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisplayFactory::updateDisplay(this, _displayManager->getCurrentDecorativeDisplay(), delta, _boneTransformDirty || _armature->getArmatureTransformDirty());
|
||||
|
||||
Object *object = NULL;
|
||||
CCARRAY_FOREACH(_children, object)
|
||||
{
|
||||
Bone *childBone = (Bone *)object;
|
||||
childBone->update(delta);
|
||||
}
|
||||
|
||||
_boneTransformDirty = false;
|
||||
}
|
||||
|
||||
|
||||
void Bone::updateDisplayedColor(const Color3B &parentColor)
|
||||
{
|
||||
_realColor = Color3B(255, 255, 255);
|
||||
NodeRGBA::updateDisplayedColor(parentColor);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
void Bone::updateDisplayedOpacity(GLubyte parentOpacity)
|
||||
{
|
||||
_realOpacity = 255;
|
||||
NodeRGBA::updateDisplayedOpacity(parentOpacity);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
void Bone::setColor(const Color3B &color)
|
||||
{
|
||||
CCNodeRGBA::setColor(color);
|
||||
updateColor();
|
||||
}
|
||||
void Bone::setOpacity(GLubyte opacity)
|
||||
{
|
||||
CCNodeRGBA::setOpacity(opacity);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
void Bone::updateColor()
|
||||
{
|
||||
Node *display = _displayManager->getDisplayRenderNode();
|
||||
RGBAProtocol *protocol = dynamic_cast<RGBAProtocol *>(display);
|
||||
if(protocol != NULL)
|
||||
{
|
||||
protocol->setColor(Color3B(_displayedColor.r * _tweenData->r / 255, _displayedColor.g * _tweenData->g / 255, _displayedColor.b * _tweenData->b / 255));
|
||||
protocol->setOpacity(_displayedOpacity * _tweenData->a / 255);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::updateZOrder()
|
||||
{
|
||||
if (_armature->getArmatureData()->dataVersion >= VERSION_COMBINED)
|
||||
{
|
||||
int zorder = _tweenData->zOrder + _boneData->zOrder;
|
||||
setZOrder(zorder);
|
||||
}
|
||||
else
|
||||
{
|
||||
setZOrder(_tweenData->zOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::addChildBone(Bone *child)
|
||||
{
|
||||
CCASSERT( NULL != child, "Argument must be non-nil");
|
||||
CCASSERT( NULL == child->_parentBone, "child already added. It can't be added again");
|
||||
|
||||
if(!_children)
|
||||
{
|
||||
_children = Array::createWithCapacity(4);
|
||||
_children->retain();
|
||||
}
|
||||
|
||||
if (_children->getIndexOfObject(child) == UINT_MAX)
|
||||
{
|
||||
_children->addObject(child);
|
||||
child->setParentBone(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::removeChildBone(Bone *bone, bool recursion)
|
||||
{
|
||||
if ( _children->getIndexOfObject(bone) != UINT_MAX )
|
||||
{
|
||||
if(recursion)
|
||||
{
|
||||
Array *_ccbones = bone->_children;
|
||||
Object *_object = NULL;
|
||||
CCARRAY_FOREACH(_ccbones, _object)
|
||||
{
|
||||
Bone *_ccBone = (Bone *)_object;
|
||||
bone->removeChildBone(_ccBone, recursion);
|
||||
}
|
||||
}
|
||||
|
||||
bone->setParentBone(NULL);
|
||||
|
||||
bone->getDisplayManager()->setCurrentDecorativeDisplay(NULL);
|
||||
|
||||
_children->removeObject(bone);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::removeFromParent(bool recursion)
|
||||
{
|
||||
if (NULL != _parentBone)
|
||||
{
|
||||
_parentBone->removeChildBone(this, recursion);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::setParentBone(Bone *parent)
|
||||
{
|
||||
_parentBone = parent;
|
||||
}
|
||||
|
||||
Bone *Bone::getParentBone()
|
||||
{
|
||||
return _parentBone;
|
||||
}
|
||||
|
||||
void Bone::setChildArmature(Armature *armature)
|
||||
{
|
||||
if (_childArmature != armature)
|
||||
{
|
||||
CC_SAFE_RETAIN(armature);
|
||||
CC_SAFE_RELEASE(_childArmature);
|
||||
_childArmature = armature;
|
||||
}
|
||||
}
|
||||
|
||||
Armature *Bone::getChildArmature()
|
||||
{
|
||||
return _childArmature;
|
||||
}
|
||||
|
||||
Tween *Bone::getTween()
|
||||
{
|
||||
return _tween;
|
||||
}
|
||||
|
||||
void Bone::setZOrder(int zOrder)
|
||||
{
|
||||
if (_ZOrder != zOrder)
|
||||
Node::setZOrder(zOrder);
|
||||
}
|
||||
|
||||
void Bone::setTransformDirty(bool dirty)
|
||||
{
|
||||
_boneTransformDirty = dirty;
|
||||
}
|
||||
|
||||
bool Bone::isTransformDirty()
|
||||
{
|
||||
return _boneTransformDirty;
|
||||
}
|
||||
|
||||
AffineTransform Bone::getNodeToArmatureTransform() const
|
||||
{
|
||||
return _worldTransform;
|
||||
}
|
||||
|
||||
AffineTransform Bone::getNodeToWorldTransform() const
|
||||
{
|
||||
return AffineTransformConcat(_worldTransform, _armature->getNodeToWorldTransform());
|
||||
}
|
||||
|
||||
Node *Bone::getDisplayRenderNode()
|
||||
{
|
||||
return _displayManager->getDisplayRenderNode();
|
||||
}
|
||||
|
||||
void Bone::addDisplay(DisplayData *displayData, int index)
|
||||
{
|
||||
_displayManager->addDisplay(displayData, index);
|
||||
}
|
||||
|
||||
void Bone::addDisplay(Node *display, int index)
|
||||
{
|
||||
_displayManager->addDisplay(display, index);
|
||||
}
|
||||
|
||||
void Bone::changeDisplayByIndex(int index, bool force)
|
||||
{
|
||||
_displayManager->changeDisplayByIndex(index, force);
|
||||
}
|
||||
|
||||
Array *Bone::getColliderBodyList()
|
||||
{
|
||||
if (DecorativeDisplay *decoDisplay = _displayManager->getCurrentDecorativeDisplay())
|
||||
{
|
||||
if (ColliderDetector *detector = decoDisplay->getColliderDetector())
|
||||
{
|
||||
return detector->getColliderBodyList();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
NS_CC_EXT_ARMATURE_END
|
|
@ -0,0 +1,199 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 __CCBONE_H__
|
||||
#define __CCBONE_H__
|
||||
|
||||
#include "utils/CCArmatureDefine.h"
|
||||
#include "datas/CCDatas.h"
|
||||
#include "animation/CCTween.h"
|
||||
#include "display/CCDecorativeDisplay.h"
|
||||
#include "display/CCDisplayManager.h"
|
||||
|
||||
NS_CC_EXT_ARMATURE_BEGIN
|
||||
|
||||
|
||||
class Armature;
|
||||
|
||||
class Bone : public NodeRGBA
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Allocates and initializes a bone.
|
||||
* @return A initialized bone which is marked as "autorelease".
|
||||
*/
|
||||
static Bone *create();
|
||||
/**
|
||||
* Allocates and initializes a bone.
|
||||
*
|
||||
* @param name If name is not null, then set name to the bone's name
|
||||
* @return A initialized bone which is marked as "autorelease".
|
||||
*/
|
||||
static Bone *create(const char *name);
|
||||
|
||||
public:
|
||||
Bone();
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
virtual ~Bone(void);
|
||||
|
||||
/**
|
||||
* Initializes an empty Bone with nothing init.
|
||||
*/
|
||||
virtual bool init();
|
||||
|
||||
/**
|
||||
* Initializes a Bone with the specified name
|
||||
* @param name Bone's name.
|
||||
*/
|
||||
virtual bool init(const char *name);
|
||||
|
||||
/**
|
||||
* Add display and use displayData to init the display.
|
||||
* If index already have a display, then replace it.
|
||||
* If index is current display index, then also change display to _index
|
||||
*
|
||||
* @param displayData it include the display information, like DisplayType.
|
||||
* If you want to create a sprite display, then create a SpriteDisplayData param
|
||||
*
|
||||
* @param index the index of the display you want to replace or add to
|
||||
* -1 : append display from back
|
||||
*/
|
||||
void addDisplay(DisplayData *displayData, int index);
|
||||
|
||||
void addDisplay(Node *display, int index);
|
||||
|
||||
void changeDisplayByIndex(int index, bool force);
|
||||
|
||||
/**
|
||||
* Add a child to this bone, and it will let this child call setParent(Bone *parent) function to set self to it's parent
|
||||
* @param child the child you want to add
|
||||
*/
|
||||
void addChildBone(Bone *child);
|
||||
|
||||
/**
|
||||
* Set parent bone.
|
||||
* If parent is NUll, then also remove this bone from armature.
|
||||
* It will not set the Armature, if you want to add the bone to a Armature, you should use Armature::addBone(Bone *bone, const char* parentName).
|
||||
*
|
||||
* @param parent the parent bone.
|
||||
* NULL : remove this bone from armature
|
||||
*/
|
||||
void setParentBone(Bone *parent);
|
||||
|
||||
/**
|
||||
* Get parent bone
|
||||
* @return parent bone
|
||||
*/
|
||||
Bone *getParentBone();
|
||||
|
||||
/**
|
||||
* Remove itself from its parent.
|
||||
* @param recursion whether or not to remove childBone's display
|
||||
*/
|
||||
void removeFromParent(bool recursion);
|
||||
|
||||
/**
|
||||
* Removes a child Bone
|
||||
* @param bone the bone you want to remove
|
||||
*/
|
||||
void removeChildBone(Bone *bone, bool recursion);
|
||||
|
||||
void update(float delta) override;
|
||||
|
||||
virtual void updateDisplayedColor(const Color3B &parentColor) override;
|
||||
virtual void updateDisplayedOpacity(GLubyte parentOpacity) override;
|
||||
|
||||
virtual void setColor(const Color3B& color) override;
|
||||
virtual void setOpacity(GLubyte opacity) override;
|
||||
|
||||
//! Update color to render display
|
||||
virtual void updateColor();
|
||||
|
||||
//! Update zorder
|
||||
virtual void updateZOrder();
|
||||
|
||||
virtual void setZOrder(int zOrder) override;
|
||||
|
||||
Tween *getTween();
|
||||
|
||||
/*
|
||||
* Whether or not the bone's transform property changed. if true, the bone will update the transform.
|
||||
*/
|
||||
virtual void setTransformDirty(bool dirty);
|
||||
|
||||
virtual bool isTransformDirty();
|
||||
|
||||
virtual AffineTransform getNodeToArmatureTransform() const;
|
||||
virtual AffineTransform getNodeToWorldTransform() const override;
|
||||
|
||||
Node *getDisplayRenderNode();
|
||||
|
||||
/*
|
||||
* Get the ColliderBody list in this bone. The object in the Array is ColliderBody.
|
||||
*/
|
||||
virtual Array *getColliderBodyList();
|
||||
|
||||
public:
|
||||
/*
|
||||
* The origin state of the Bone. Display's state is effected by _boneData, m_pNode, _tweenData
|
||||
* when call setData function, it will copy from the BoneData.
|
||||
*/
|
||||
CC_PROPERTY(BoneData *, _boneData, BoneData);
|
||||
|
||||
//! A weak reference to the Armature
|
||||
CC_PROPERTY(Armature *, _armature, Armature);
|
||||
|
||||
//! A weak reference to the child Armature
|
||||
CC_PROPERTY(Armature *, _childArmature, ChildArmature);
|
||||
|
||||
CC_SYNTHESIZE(DisplayManager *, _displayManager, DisplayManager)
|
||||
|
||||
/*
|
||||
* When Armature play an animation, if there is not a MovementBoneData of this bone in this MovementData, this bone will be hidden.
|
||||
* Set IgnoreMovementBoneData to true, then this bone will also be shown.
|
||||
*/
|
||||
CC_SYNTHESIZE(bool, _ignoreMovementBoneData, IgnoreMovementBoneData)
|
||||
|
||||
CC_SYNTHESIZE(BlendType, _blendType, BlendType)
|
||||
protected:
|
||||
Tween *_tween; //! Calculate tween effect
|
||||
|
||||
//! Used for making tween effect in every frame
|
||||
CC_SYNTHESIZE_READONLY(FrameData *, _tweenData, TweenData);
|
||||
|
||||
CC_SYNTHESIZE(std::string, _name, Name);
|
||||
|
||||
Bone *_parentBone; //! A weak reference to its parent
|
||||
bool _boneTransformDirty; //! Whether or not transform dirty
|
||||
|
||||
//! self Transform, use this to change display's state
|
||||
AffineTransform _worldTransform;
|
||||
};
|
||||
|
||||
NS_CC_EXT_ARMATURE_END
|
||||
|
||||
#endif /*__CCBONE_H__*/
|
|
@ -0,0 +1,396 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "CCDisplayManager.h"
|
||||
#include "../CCBone.h"
|
||||
#include "../CCArmature.h"
|
||||
#include "../utils/CCUtilMath.h"
|
||||
#include "../display/CCSkin.h"
|
||||
|
||||
NS_CC_EXT_ARMATURE_BEGIN
|
||||
|
||||
DisplayManager *DisplayManager::create(Bone *bone)
|
||||
{
|
||||
DisplayManager *pDisplayManager = new DisplayManager();
|
||||
if (pDisplayManager && pDisplayManager->init(bone))
|
||||
{
|
||||
pDisplayManager->autorelease();
|
||||
return pDisplayManager;
|
||||
}
|
||||
CC_SAFE_DELETE(pDisplayManager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DisplayManager::DisplayManager()
|
||||
: _decoDisplayList(NULL)
|
||||
, _displayRenderNode(NULL)
|
||||
, _currentDecoDisplay(NULL)
|
||||
, _displayIndex(-1)
|
||||
, _forceChangeDisplay(false)
|
||||
, _visible(true)
|
||||
, _bone(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
DisplayManager::~DisplayManager()
|
||||
{
|
||||
CC_SAFE_DELETE(_decoDisplayList);
|
||||
|
||||
if( _displayRenderNode )
|
||||
{
|
||||
_displayRenderNode->removeFromParentAndCleanup(true);
|
||||
if(_displayRenderNode->retainCount() > 0)
|
||||
CC_SAFE_RELEASE_NULL(_displayRenderNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool DisplayManager::init(Bone *bone)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
_bone = bone;
|
||||
|
||||
initDisplayList(bone->getBoneData());
|
||||
|
||||
ret = true;
|
||||
}
|
||||
while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void DisplayManager::addDisplay(DisplayData *displayData, int index)
|
||||
{
|
||||
DecorativeDisplay *decoDisplay = NULL;
|
||||
|
||||
if(index >= 0 && (unsigned int)index < _decoDisplayList->count())
|
||||
{
|
||||
decoDisplay = (DecorativeDisplay *)_decoDisplayList->getObjectAtIndex(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
decoDisplay = DecorativeDisplay::create();
|
||||
_decoDisplayList->addObject(decoDisplay);
|
||||
}
|
||||
|
||||
DisplayFactory::addDisplay(_bone, decoDisplay, displayData);
|
||||
|
||||
//! if changed display index is current display index, then change current display to the new display
|
||||
if(index == _displayIndex)
|
||||
{
|
||||
_displayIndex = -1;
|
||||
changeDisplayByIndex(index, false);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayManager::addDisplay(Node *display, int index)
|
||||
{
|
||||
DecorativeDisplay *decoDisplay = NULL;
|
||||
|
||||
if(index >= 0 && (unsigned int)index < _decoDisplayList->count())
|
||||
{
|
||||
decoDisplay = (DecorativeDisplay *)_decoDisplayList->getObjectAtIndex(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
decoDisplay = DecorativeDisplay::create();
|
||||
_decoDisplayList->addObject(decoDisplay);
|
||||
}
|
||||
|
||||
DisplayData *displayData = NULL;
|
||||
if (Skin *skin = dynamic_cast<Skin *>(display))
|
||||
{
|
||||
skin->setBone(_bone);
|
||||
displayData = SpriteDisplayData::create();
|
||||
|
||||
DisplayFactory::initSpriteDisplay(_bone, decoDisplay, skin->getDisplayName().c_str(), skin);
|
||||
|
||||
if (SpriteDisplayData *spriteDisplayData = (SpriteDisplayData *)decoDisplay->getDisplayData())
|
||||
{
|
||||
skin->setSkinData(spriteDisplayData->skinData);
|
||||
((CCSpriteDisplayData *)displayData)->skinData = spriteDisplayData->skinData;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseData baseData;
|
||||
skin->setSkinData(baseData);
|
||||
}
|
||||
}
|
||||
else if (dynamic_cast<ParticleSystemQuad *>(display))
|
||||
{
|
||||
displayData = ParticleDisplayData::create();
|
||||
}
|
||||
else if(Armature *armature = dynamic_cast<Armature *>(display))
|
||||
{
|
||||
displayData = ArmatureDisplayData::create();
|
||||
armature->setParentBone(_bone);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayData = DisplayData::create();
|
||||
}
|
||||
|
||||
decoDisplay->setDisplay(display);
|
||||
decoDisplay->setDisplayData(displayData);
|
||||
|
||||
//! if changed display index is current display index, then change current display to the new display
|
||||
if(index == _displayIndex)
|
||||
{
|
||||
_displayIndex = -1;
|
||||
changeDisplayByIndex(index, false);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayManager::removeDisplay(int index)
|
||||
{
|
||||
_decoDisplayList->removeObjectAtIndex(index);
|
||||
|
||||
if(index == _displayIndex)
|
||||
{
|
||||
setCurrentDecorativeDisplay(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Array *DisplayManager::getDecorativeDisplayList()
|
||||
{
|
||||
return _decoDisplayList;
|
||||
}
|
||||
|
||||
void DisplayManager::changeDisplayByIndex(int index, bool force)
|
||||
{
|
||||
CCASSERT( (_decoDisplayList ? index < (int)_decoDisplayList->count() : true), "the _index value is out of range");
|
||||
|
||||
_forceChangeDisplay = force;
|
||||
|
||||
//! If index is equal to current display index,then do nothing
|
||||
if ( _displayIndex == index)
|
||||
return;
|
||||
|
||||
|
||||
_displayIndex = index;
|
||||
|
||||
//! If displayIndex < 0, it means you want to hide you display
|
||||
if (_displayIndex < 0)
|
||||
{
|
||||
if(_displayRenderNode)
|
||||
{
|
||||
_displayRenderNode->removeFromParentAndCleanup(true);
|
||||
setCurrentDecorativeDisplay(NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DecorativeDisplay *decoDisplay = (DecorativeDisplay *)_decoDisplayList->getObjectAtIndex(_displayIndex);
|
||||
|
||||
setCurrentDecorativeDisplay(decoDisplay);
|
||||
}
|
||||
|
||||
void DisplayManager::setCurrentDecorativeDisplay(DecorativeDisplay *decoDisplay)
|
||||
{
|
||||
#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT
|
||||
if (_currentDecoDisplay && _currentDecoDisplay->getColliderDetector())
|
||||
{
|
||||
_currentDecoDisplay->getColliderDetector()->setActive(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
_currentDecoDisplay = decoDisplay;
|
||||
|
||||
#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT
|
||||
if (_currentDecoDisplay && _currentDecoDisplay->getColliderDetector())
|
||||
{
|
||||
_currentDecoDisplay->getColliderDetector()->setActive(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
Node *displayRenderNode = _currentDecoDisplay == NULL ? NULL : _currentDecoDisplay->getDisplay();
|
||||
if (_displayRenderNode)
|
||||
{
|
||||
if (dynamic_cast<Armature *>(_displayRenderNode) != NULL)
|
||||
{
|
||||
_bone->setChildArmature(NULL);
|
||||
}
|
||||
_displayRenderNode->removeFromParentAndCleanup(true);
|
||||
_displayRenderNode->release();
|
||||
}
|
||||
|
||||
_displayRenderNode = displayRenderNode;
|
||||
|
||||
if(_displayRenderNode)
|
||||
{
|
||||
if (Armature *armature = dynamic_cast<Armature *>(_displayRenderNode))
|
||||
{
|
||||
_bone->setChildArmature(armature);
|
||||
}
|
||||
else if (ParticleSystemQuad *particle = dynamic_cast<ParticleSystemQuad *>(_displayRenderNode))
|
||||
{
|
||||
particle->resetSystem();
|
||||
}
|
||||
|
||||
if (RGBAProtocol *rgbaProtocaol = dynamic_cast<RGBAProtocol *>(_displayRenderNode))
|
||||
{
|
||||
rgbaProtocaol->setColor(_bone->getDisplayedColor());
|
||||
rgbaProtocaol->setOpacity(_bone->getDisplayedOpacity());
|
||||
}
|
||||
|
||||
_displayRenderNode->retain();
|
||||
_displayRenderNode->setVisible(_visible);
|
||||
}
|
||||
}
|
||||
|
||||
Node *DisplayManager::getDisplayRenderNode()
|
||||
{
|
||||
return _displayRenderNode;
|
||||
}
|
||||
|
||||
int DisplayManager::getCurrentDisplayIndex()
|
||||
{
|
||||
return _displayIndex;
|
||||
}
|
||||
|
||||
DecorativeDisplay *DisplayManager::getCurrentDecorativeDisplay()
|
||||
{
|
||||
return _currentDecoDisplay;
|
||||
}
|
||||
|
||||
DecorativeDisplay *DisplayManager::getDecorativeDisplayByIndex( int index)
|
||||
{
|
||||
return (DecorativeDisplay *)_decoDisplayList->getObjectAtIndex(index);
|
||||
}
|
||||
|
||||
void DisplayManager::initDisplayList(BoneData *boneData)
|
||||
{
|
||||
CC_SAFE_DELETE(_decoDisplayList);
|
||||
_decoDisplayList = Array::create();
|
||||
_decoDisplayList->retain();
|
||||
|
||||
CS_RETURN_IF(!boneData);
|
||||
|
||||
Object *object = NULL;
|
||||
Array *displayDataList = &boneData->displayDataList;
|
||||
CCARRAY_FOREACH(displayDataList, object)
|
||||
{
|
||||
DisplayData *displayData = (DisplayData *)object;
|
||||
|
||||
DecorativeDisplay *decoDisplay = DecorativeDisplay::create();
|
||||
decoDisplay->setDisplayData(displayData);
|
||||
|
||||
DisplayFactory::createDisplay(_bone, decoDisplay);
|
||||
|
||||
_decoDisplayList->addObject(decoDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DisplayManager::containPoint(Point &point)
|
||||
{
|
||||
if(!_visible || _displayIndex < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
||||
switch (_currentDecoDisplay->getDisplayData()->displayType)
|
||||
{
|
||||
case CS_DISPLAY_SPRITE:
|
||||
{
|
||||
/*
|
||||
* First we first check if the point is in the sprite content rect. If false, then we continue to check
|
||||
* the contour point. If this step is also false, then we can say the bone not contain this point.
|
||||
*
|
||||
*/
|
||||
|
||||
Point outPoint = Point(0, 0);
|
||||
|
||||
Sprite *sprite = (Sprite *)_currentDecoDisplay->getDisplay();
|
||||
sprite = (Sprite *)sprite->getChildByTag(0);
|
||||
|
||||
ret = CC_SPRITE_CONTAIN_POINT_WITH_RETURN(sprite, point, outPoint);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DisplayManager::containPoint(float x, float y)
|
||||
{
|
||||
Point p = Point(x, y);
|
||||
return containPoint(p);
|
||||
}
|
||||
|
||||
|
||||
void DisplayManager::setVisible(bool visible)
|
||||
{
|
||||
if(!_displayRenderNode)
|
||||
return;
|
||||
|
||||
_visible = visible;
|
||||
_displayRenderNode->setVisible(visible);
|
||||
}
|
||||
|
||||
bool DisplayManager::isVisible()
|
||||
{
|
||||
return _visible;
|
||||
}
|
||||
|
||||
|
||||
Size DisplayManager::getContentSize()
|
||||
{
|
||||
CS_RETURN_IF(!_displayRenderNode) Size(0, 0);
|
||||
return _displayRenderNode->getContentSize();
|
||||
}
|
||||
|
||||
Rect DisplayManager::getBoundingBox()
|
||||
{
|
||||
CS_RETURN_IF(!_displayRenderNode) Rect(0, 0, 0, 0);
|
||||
return _displayRenderNode->getBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
Point DisplayManager::getAnchorPoint()
|
||||
{
|
||||
CS_RETURN_IF(!_displayRenderNode) Point(0, 0);
|
||||
return _displayRenderNode->getAnchorPoint();
|
||||
}
|
||||
|
||||
Point DisplayManager::getAnchorPointInPoints()
|
||||
{
|
||||
CS_RETURN_IF(!_displayRenderNode) Point(0, 0);
|
||||
return _displayRenderNode->getAnchorPointInPoints();
|
||||
}
|
||||
|
||||
|
||||
NS_CC_EXT_ARMATURE_END
|
|
@ -0,0 +1,205 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "CCSkin.h"
|
||||
#include "../utils/CCTransformHelp.h"
|
||||
#include "../utils/CCSpriteFrameCacheHelper.h"
|
||||
#include "../CCArmature.h"
|
||||
|
||||
NS_CC_EXT_ARMATURE_BEGIN
|
||||
|
||||
#if CC_SPRITEBATCHNODE_RENDER_SUBPIXEL
|
||||
#define RENDER_IN_SUBPIXEL
|
||||
#else
|
||||
#define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__))
|
||||
#endif
|
||||
|
||||
Skin *Skin::create()
|
||||
{
|
||||
Skin *skin = new Skin();
|
||||
if(skin && skin->init())
|
||||
{
|
||||
skin->autorelease();
|
||||
return skin;
|
||||
}
|
||||
CC_SAFE_DELETE(skin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Skin *Skin::createWithSpriteFrameName(const char *pszSpriteFrameName)
|
||||
{
|
||||
Skin *skin = new Skin();
|
||||
if(skin && skin->initWithSpriteFrameName(pszSpriteFrameName))
|
||||
{
|
||||
skin->autorelease();
|
||||
return skin;
|
||||
}
|
||||
CC_SAFE_DELETE(skin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Skin *Skin::create(const char *pszFileName)
|
||||
{
|
||||
Skin *skin = new Skin();
|
||||
if(skin && skin->initWithFile(pszFileName))
|
||||
{
|
||||
skin->autorelease();
|
||||
return skin;
|
||||
}
|
||||
CC_SAFE_DELETE(skin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Skin::Skin()
|
||||
: _bone(NULL)
|
||||
, _displayName("")
|
||||
{
|
||||
_skinTransform = AffineTransformIdentity;
|
||||
}
|
||||
|
||||
bool Skin::initWithSpriteFrameName(const char *pszSpriteFrameName)
|
||||
{
|
||||
bool ret = Sprite::initWithSpriteFrameName(pszSpriteFrameName);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
TextureAtlas *atlas = SpriteFrameCacheHelper::getInstance()->getTexureAtlasWithTexture(_texture);
|
||||
setTextureAtlas(atlas);
|
||||
|
||||
_displayName = pszSpriteFrameName;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Skin::initWithFile(const char *pszFilename)
|
||||
{
|
||||
bool ret = Sprite::initWithFile(pszFilename);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
TextureAtlas *atlas = SpriteFrameCacheHelper::getInstance()->getTexureAtlasWithTexture(_texture);
|
||||
setTextureAtlas(atlas);
|
||||
|
||||
_displayName = pszFilename;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Skin::setSkinData(const BaseData &var)
|
||||
{
|
||||
_skinData = var;
|
||||
|
||||
setScaleX(_skinData.scaleX);
|
||||
setScaleY(_skinData.scaleY);
|
||||
setRotation(CC_RADIANS_TO_DEGREES(_skinData.skewX));
|
||||
setPosition(Point(_skinData.x, _skinData.y));
|
||||
|
||||
_skinTransform = getNodeToParentTransform();
|
||||
updateArmatureTransform();
|
||||
}
|
||||
|
||||
const BaseData &Skin::getSkinData() const
|
||||
{
|
||||
return _skinData;
|
||||
}
|
||||
|
||||
void Skin::updateArmatureTransform()
|
||||
{
|
||||
_transform = AffineTransformConcat(_skinTransform, _bone->getNodeToArmatureTransform());
|
||||
}
|
||||
|
||||
void Skin::updateTransform()
|
||||
{
|
||||
// If it is not visible, or one of its ancestors is not visible, then do nothing:
|
||||
if( !_visible)
|
||||
{
|
||||
_quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// calculate the Quad based on the Affine Matrix
|
||||
//
|
||||
|
||||
Size &size = _rect.size;
|
||||
|
||||
float x1 = _offsetPosition.x;
|
||||
float y1 = _offsetPosition.y;
|
||||
|
||||
float x2 = x1 + size.width;
|
||||
float y2 = y1 + size.height;
|
||||
|
||||
float x = _transform.tx;
|
||||
float y = _transform.ty;
|
||||
|
||||
float cr = _transform.a;
|
||||
float sr = _transform.b;
|
||||
float cr2 = _transform.d;
|
||||
float sr2 = -_transform.c;
|
||||
float ax = x1 * cr - y1 * sr2 + x;
|
||||
float ay = x1 * sr + y1 * cr2 + y;
|
||||
|
||||
float bx = x2 * cr - y1 * sr2 + x;
|
||||
float by = x2 * sr + y1 * cr2 + y;
|
||||
|
||||
float cx = x2 * cr - y2 * sr2 + x;
|
||||
float cy = x2 * sr + y2 * cr2 + y;
|
||||
|
||||
float dx = x1 * cr - y2 * sr2 + x;
|
||||
float dy = x1 * sr + y2 * cr2 + y;
|
||||
|
||||
_quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ );
|
||||
_quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ );
|
||||
_quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ );
|
||||
_quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ );
|
||||
}
|
||||
|
||||
// MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS
|
||||
if (_textureAtlas)
|
||||
{
|
||||
_textureAtlas->updateQuad(&_quad, _textureAtlas->getTotalQuads());
|
||||
}
|
||||
}
|
||||
|
||||
AffineTransform Skin::getNodeToWorldTransform() const
|
||||
{
|
||||
return AffineTransformConcat(_transform, _bone->getArmature()->getNodeToWorldTransform());
|
||||
}
|
||||
|
||||
AffineTransform Skin::getNodeToWorldTransformAR() const
|
||||
{
|
||||
AffineTransform displayTransform = _transform;
|
||||
Point anchorPoint = _anchorPointInPoints;
|
||||
|
||||
anchorPoint = PointApplyAffineTransform(anchorPoint, displayTransform);
|
||||
|
||||
displayTransform.tx = anchorPoint.x;
|
||||
displayTransform.ty = anchorPoint.y;
|
||||
|
||||
return AffineTransformConcat(displayTransform, _bone->getArmature()->getNodeToWorldTransform());
|
||||
}
|
||||
|
||||
NS_CC_EXT_ARMATURE_END
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue