2013-06-06 12:02:54 +08:00
|
|
|
/****************************************************************************
|
|
|
|
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 "CCDisplayFactory.h"
|
|
|
|
#include "../CCBone.h"
|
|
|
|
#include "../CCArmature.h"
|
|
|
|
#include "../display/CCSkin.h"
|
|
|
|
#include "../display/CCShaderNode.h"
|
|
|
|
#include "../utils/CCSpriteFrameCacheHelper.h"
|
|
|
|
#include "../utils/CCArmatureDataManager.h"
|
|
|
|
#include "../utils/CCTransformHelp.h"
|
|
|
|
|
|
|
|
NS_CC_EXT_BEGIN
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::addDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, CCDisplayData *displayData)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
switch(displayData->displayType)
|
|
|
|
{
|
|
|
|
case CS_DISPLAY_SPRITE:
|
|
|
|
addSpriteDisplay(bone, decoDisplay, displayData);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_PARTICLE:
|
|
|
|
addParticleDisplay(bone, decoDisplay, displayData);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_ARMATURE:
|
|
|
|
addArmatureDisplay(bone, decoDisplay, displayData);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::createDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
switch(decoDisplay->getDisplayData()->displayType)
|
|
|
|
{
|
|
|
|
case CS_DISPLAY_SPRITE:
|
|
|
|
createSpriteDisplay(bone, decoDisplay);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_PARTICLE:
|
|
|
|
createParticleDisplay(bone, decoDisplay);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_ARMATURE:
|
|
|
|
createArmatureDisplay(bone, decoDisplay);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::updateDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, float dt, bool dirty)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CS_RETURN_IF(!decoDisplay);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
|
|
|
#if ENABLE_PHYSICS_DETECT
|
2013-06-07 10:52:32 +08:00
|
|
|
if (dirty)
|
|
|
|
{
|
|
|
|
CCColliderDetector *detector = decoDisplay->getColliderDetector();
|
|
|
|
if (detector)
|
|
|
|
{
|
|
|
|
CCAffineTransform t = CCAffineTransformConcat(bone->nodeToArmatureTransform(), bone->getArmature()->nodeToWorldTransform());
|
|
|
|
detector->updateTransform(t);
|
|
|
|
}
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
#endif
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
switch(decoDisplay->getDisplayData()->displayType)
|
|
|
|
{
|
|
|
|
case CS_DISPLAY_SPRITE:
|
|
|
|
updateSpriteDisplay(bone, decoDisplay, dt, dirty);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_PARTICLE:
|
|
|
|
updateParticleDisplay(bone, decoDisplay, dt, dirty);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_ARMATURE:
|
|
|
|
updateArmatureDisplay(bone, decoDisplay, dt, dirty);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::addSpriteDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, CCDisplayData *displayData)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCSpriteDisplayData *sdp = CCSpriteDisplayData::create();
|
|
|
|
sdp->copy((CCSpriteDisplayData *)displayData);
|
|
|
|
decoDisplay->setDisplayData(sdp);
|
|
|
|
createSpriteDisplay(bone, decoDisplay);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::createSpriteDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCSkin *skin = NULL;
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
CCSpriteDisplayData *displayData = (CCSpriteDisplayData *)decoDisplay->getDisplayData();
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
//! remove .xxx
|
|
|
|
std::string textureName = displayData->displayName;
|
|
|
|
size_t startPos = textureName.find_last_of(".");
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
if(startPos != std::string::npos)
|
|
|
|
{
|
|
|
|
textureName = textureName.erase(startPos);
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
//! create display
|
|
|
|
if(textureName.compare("") == 0)
|
|
|
|
{
|
|
|
|
skin = CCSkin::create();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skin = CCSkin::createWithSpriteFrameName((textureName + ".png").c_str());
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
CCTextureAtlas *atlas = CCSpriteFrameCacheHelper::sharedSpriteFrameCacheHelper()->getTextureAtlas((textureName + ".png").c_str());
|
|
|
|
skin->setTextureAtlas(atlas);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
CCTextureData *textureData = CCArmatureDataManager::sharedArmatureDataManager()->getTextureData(textureName.c_str());
|
|
|
|
if(textureData)
|
|
|
|
{
|
|
|
|
//! Init display anchorPoint, every Texture have a anchor point
|
|
|
|
skin->setAnchorPoint(ccp( textureData->pivotX, textureData->pivotY));
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
skin->setBone(bone);
|
|
|
|
skin->setSkinData(*bone->getBoneData());
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
decoDisplay->setDisplay(skin);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
|
|
|
#if ENABLE_PHYSICS_DETECT
|
2013-06-07 10:52:32 +08:00
|
|
|
if (textureData && textureData->contourDataList.count() > 0)
|
|
|
|
{
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
//! create ContourSprite
|
|
|
|
CCColliderDetector *colliderDetector = CCColliderDetector::create(bone);
|
|
|
|
colliderDetector->addContourDataList(&textureData->contourDataList);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
decoDisplay->setColliderDetector(colliderDetector);
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::updateSpriteDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, float dt, bool dirty)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCSkin *skin = (CCSkin *)decoDisplay->getDisplay();
|
|
|
|
skin->updateTransform();
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::addArmatureDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, CCDisplayData *displayData)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCArmatureDisplayData *adp = CCArmatureDisplayData::create(); ;
|
|
|
|
adp->copy((CCArmatureDisplayData *)displayData);
|
|
|
|
decoDisplay->setDisplayData(adp);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
createArmatureDisplay(bone, decoDisplay);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::createArmatureDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCArmatureDisplayData *displayData = (CCArmatureDisplayData *)decoDisplay->getDisplayData();
|
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
CCArmature *armature = CCArmature::create(displayData->displayName.c_str(), bone);
|
2013-06-07 10:52:32 +08:00
|
|
|
|
2013-06-06 12:02:54 +08:00
|
|
|
/*
|
|
|
|
* because this bone have called this name, so armature should change it's name, or it can't add to
|
|
|
|
* CCArmature's bone children.
|
|
|
|
*/
|
|
|
|
armature->setName((bone->getName() + "_armatureChild").c_str());
|
2013-06-07 10:52:32 +08:00
|
|
|
|
|
|
|
decoDisplay->setDisplay(armature);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::updateArmatureDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, float dt, bool dirty)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CS_RETURN_IF(!dirty);
|
|
|
|
|
|
|
|
CCArmature *armature = bone->getChildArmature();
|
|
|
|
if(armature)
|
|
|
|
{
|
|
|
|
armature->sortAllChildren();
|
|
|
|
armature->update(dt);
|
|
|
|
}
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::addParticleDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, CCDisplayData *displayData)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCParticleDisplayData *adp = CCParticleDisplayData::create(); ;
|
|
|
|
adp->copy((CCParticleDisplayData *)displayData);
|
|
|
|
decoDisplay->setDisplayData(adp);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
createParticleDisplay(bone, decoDisplay);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::createParticleDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCParticleDisplayData *displayData = (CCParticleDisplayData *)decoDisplay->getDisplayData();
|
|
|
|
CCParticleSystem *system = CCParticleSystemQuad::create(displayData->plist.c_str());
|
|
|
|
decoDisplay->setDisplay(system);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::updateParticleDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, float dt, bool dirty)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCParticleSystem *system = (CCParticleSystem *)decoDisplay->getDisplay();
|
|
|
|
CCBaseData node;
|
|
|
|
CCTransformHelp::matrixToNode(bone->nodeToArmatureTransform(), node);
|
|
|
|
system->setPosition(node.x, node.y);
|
|
|
|
system->setScaleX(node.scaleX);
|
|
|
|
system->setScaleY(node.scaleY);
|
|
|
|
system->update(dt);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::addShaderDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay, CCDisplayData *displayData)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCShaderDisplayData *sdp = CCShaderDisplayData::create();
|
|
|
|
sdp->copy((CCShaderDisplayData *)displayData);
|
|
|
|
decoDisplay->setDisplayData(sdp);
|
2013-06-06 12:02:54 +08:00
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
createShaderDisplay(bone, decoDisplay);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
2013-06-07 10:52:32 +08:00
|
|
|
void CCDisplayFactory::createShaderDisplay(CCBone *bone, CCDecorativeDisplay *decoDisplay)
|
2013-06-06 12:02:54 +08:00
|
|
|
{
|
2013-06-07 10:52:32 +08:00
|
|
|
CCShaderDisplayData *displayData = (CCShaderDisplayData *)decoDisplay->getDisplayData();
|
|
|
|
CCShaderNode *sn = CCShaderNode::shaderNodeWithVertex(displayData->vert.c_str(), displayData->frag.c_str());
|
|
|
|
decoDisplay->setDisplay(sn);
|
2013-06-06 12:02:54 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:52:32 +08:00
|
|
|
NS_CC_EXT_END
|