2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
2020-10-17 16:32:16 +08:00
|
|
|
Copyright (c) 2013-2017 Chukong Technologies Inc.
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-10-01 16:24:52 +08:00
|
|
|
https://axmolengine.github.io/
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2020-10-21 10:12:00 +08:00
|
|
|
#include "CCDisplayFactory.h"
|
|
|
|
#include "CCBone.h"
|
|
|
|
#include "CCArmature.h"
|
|
|
|
#include "CCSkin.h"
|
|
|
|
#include "CCArmatureDataManager.h"
|
|
|
|
#include "CCTransformHelp.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
#include "2d/CCParticleSystemQuad.h"
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
USING_NS_AX;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
namespace cocostudio
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::addDisplay(Bone* bone, DecorativeDisplay* decoDisplay, DisplayData* displayData)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
switch (displayData->displayType)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
case CS_DISPLAY_SPRITE:
|
|
|
|
addSpriteDisplay(bone, decoDisplay, displayData);
|
|
|
|
break;
|
2021-12-25 10:04:45 +08:00
|
|
|
case CS_DISPLAY_PARTICLE:
|
2019-11-23 20:27:39 +08:00
|
|
|
addParticleDisplay(bone, decoDisplay, displayData);
|
|
|
|
break;
|
2021-12-25 10:04:45 +08:00
|
|
|
case CS_DISPLAY_ARMATURE:
|
2019-11-23 20:27:39 +08:00
|
|
|
addArmatureDisplay(bone, decoDisplay, displayData);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::createDisplay(Bone* bone, DecorativeDisplay* decoDisplay)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
switch (decoDisplay->getDisplayData()->displayType)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::updateDisplay(Bone* bone, float dt, bool dirty)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Node* display = bone->getDisplayRenderNode();
|
2019-11-23 20:27:39 +08:00
|
|
|
CS_RETURN_IF(!display);
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
switch (bone->getDisplayRenderNodeType())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
case CS_DISPLAY_SPRITE:
|
|
|
|
if (dirty)
|
|
|
|
{
|
|
|
|
static_cast<Skin*>(display)->updateArmatureTransform();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_PARTICLE:
|
|
|
|
updateParticleDisplay(bone, display, dt);
|
|
|
|
break;
|
|
|
|
case CS_DISPLAY_ARMATURE:
|
|
|
|
updateArmatureDisplay(bone, display, dt);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
Mat4 transform = bone->getNodeToArmatureTransform();
|
|
|
|
display->setAdditionalTransform(&transform);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT || ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
|
|
|
|
if (dirty)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
DecorativeDisplay* decoDisplay = bone->getDisplayManager()->getCurrentDecorativeDisplay();
|
|
|
|
ColliderDetector* detector = decoDisplay->getColliderDetector();
|
2019-11-23 20:27:39 +08:00
|
|
|
if (detector)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
# if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_BREAK_IF(!detector->getBody());
|
2021-12-25 10:04:45 +08:00
|
|
|
# endif
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Mat4 displayTransform = display->getNodeToParentTransform();
|
|
|
|
Vec2 anchorPoint = display->getAnchorPointInPoints();
|
|
|
|
anchorPoint = PointApplyTransform(anchorPoint, displayTransform);
|
2019-11-23 20:27:39 +08:00
|
|
|
displayTransform.m[12] = anchorPoint.x;
|
|
|
|
displayTransform.m[13] = anchorPoint.y;
|
2021-12-25 10:04:45 +08:00
|
|
|
Mat4 t = TransformConcat(bone->getArmature()->getNodeToParentTransform(), displayTransform);
|
2019-11-23 20:27:39 +08:00
|
|
|
detector->updateTransform(t);
|
2021-12-25 10:04:45 +08:00
|
|
|
} while (0);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::addSpriteDisplay(Bone* bone, DecorativeDisplay* decoDisplay, DisplayData* displayData)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
SpriteDisplayData* sdp = SpriteDisplayData::create();
|
|
|
|
sdp->copy((SpriteDisplayData*)displayData);
|
2019-11-23 20:27:39 +08:00
|
|
|
decoDisplay->setDisplayData(sdp);
|
|
|
|
createSpriteDisplay(bone, decoDisplay);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::createSpriteDisplay(Bone* bone, DecorativeDisplay* decoDisplay)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Skin* skin = nullptr;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
SpriteDisplayData* displayData = (SpriteDisplayData*)decoDisplay->getDisplayData();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
std::string textureName = displayData->displayName;
|
2021-12-25 10:04:45 +08:00
|
|
|
size_t startPos = textureName.find_last_of(".");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (startPos != std::string::npos)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
textureName = textureName.erase(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! create display
|
2021-12-25 10:04:45 +08:00
|
|
|
if (textureName.empty())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
skin = Skin::create();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skin = Skin::createWithSpriteFrameName((textureName + ".png"));
|
|
|
|
}
|
|
|
|
|
|
|
|
decoDisplay->setDisplay(skin);
|
|
|
|
|
|
|
|
if (skin == nullptr)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
skin->setBone(bone);
|
|
|
|
|
|
|
|
initSpriteDisplay(bone, decoDisplay, displayData->displayName.c_str(), skin);
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Armature* armature = bone->getArmature();
|
2019-11-23 20:27:39 +08:00
|
|
|
if (armature)
|
|
|
|
{
|
|
|
|
if (armature->getArmatureData()->dataVersion >= VERSION_COMBINED)
|
|
|
|
{
|
|
|
|
skin->setSkinData(displayData->skinData);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skin->setSkinData(*bone->getBoneData());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::initSpriteDisplay(Bone* bone, DecorativeDisplay* decoDisplay, const char* displayName, Skin* skin)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
//! remove .xxx
|
|
|
|
std::string textureName = displayName;
|
2021-12-25 10:04:45 +08:00
|
|
|
size_t startPos = textureName.find_last_of(".");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (startPos != std::string::npos)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
textureName = textureName.erase(startPos);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
TextureData* textureData = ArmatureDataManager::getInstance()->getTextureData(textureName);
|
|
|
|
if (textureData)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
//! Init display anchorPoint, every Texture have a anchor point
|
2021-12-25 10:04:45 +08:00
|
|
|
skin->setAnchorPoint(Vec2(textureData->pivotX, textureData->pivotY));
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#if ENABLE_PHYSICS_BOX2D_DETECT || ENABLE_PHYSICS_CHIPMUNK_DETECT || ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
|
|
|
|
if (textureData && textureData->contourDataList.size() > 0)
|
|
|
|
{
|
|
|
|
|
|
|
|
//! create ContourSprite
|
2021-12-25 10:04:45 +08:00
|
|
|
ColliderDetector* colliderDetector = ColliderDetector::create(bone);
|
2019-11-23 20:27:39 +08:00
|
|
|
colliderDetector->addContourDataList(textureData->contourDataList);
|
|
|
|
|
|
|
|
decoDisplay->setColliderDetector(colliderDetector);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::addArmatureDisplay(Bone* bone, DecorativeDisplay* decoDisplay, DisplayData* displayData)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ArmatureDisplayData* adp = ArmatureDisplayData::create();
|
|
|
|
adp->copy((ArmatureDisplayData*)displayData);
|
2019-11-23 20:27:39 +08:00
|
|
|
decoDisplay->setDisplayData(adp);
|
|
|
|
|
|
|
|
createArmatureDisplay(bone, decoDisplay);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::createArmatureDisplay(Bone* bone, DecorativeDisplay* decoDisplay)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ArmatureDisplayData* displayData = (ArmatureDisplayData*)decoDisplay->getDisplayData();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Armature* armature = Armature::create(displayData->displayName, bone);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
decoDisplay->setDisplay(armature);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::updateArmatureDisplay(Bone* /*bone*/, Node* display, float dt)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Armature* armature = (Armature*)display;
|
|
|
|
if (armature)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
armature->sortAllChildren();
|
|
|
|
armature->update(dt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::addParticleDisplay(Bone* bone, DecorativeDisplay* decoDisplay, DisplayData* displayData)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ParticleDisplayData* adp = ParticleDisplayData::create();
|
|
|
|
adp->copy((ParticleDisplayData*)displayData);
|
2019-11-23 20:27:39 +08:00
|
|
|
decoDisplay->setDisplayData(adp);
|
|
|
|
|
|
|
|
createParticleDisplay(bone, decoDisplay);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::createParticleDisplay(Bone* bone, DecorativeDisplay* decoDisplay)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ParticleDisplayData* displayData = (ParticleDisplayData*)decoDisplay->getDisplayData();
|
|
|
|
ParticleSystem* system = ParticleSystemQuad::create(displayData->displayName);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
system->removeFromParent();
|
|
|
|
system->cleanup();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
Armature* armature = bone->getArmature();
|
2019-11-23 20:27:39 +08:00
|
|
|
if (armature)
|
|
|
|
{
|
|
|
|
system->setParent(armature);
|
|
|
|
}
|
|
|
|
|
|
|
|
decoDisplay->setDisplay(system);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
void DisplayFactory::updateParticleDisplay(Bone* bone, Node* display, float dt)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ParticleSystem* system = (ParticleSystem*)display;
|
2019-11-23 20:27:39 +08:00
|
|
|
BaseData node;
|
|
|
|
TransformHelp::matrixToNode(bone->getNodeToArmatureTransform(), node);
|
|
|
|
system->setPosition(node.x, node.y);
|
|
|
|
system->setScaleX(node.scaleX);
|
|
|
|
system->setScaleY(node.scaleY);
|
|
|
|
system->update(dt);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
} // namespace cocostudio
|