Merge pull request #11221 from super626/v3

3d animation quality control
This commit is contained in:
minggo 2015-03-31 17:23:58 +08:00
commit c1cd041912
8 changed files with 127 additions and 30 deletions

View File

@ -26,6 +26,7 @@
#include "3d/CCSprite3D.h" #include "3d/CCSprite3D.h"
#include "3d/CCSkeleton3D.h" #include "3d/CCSkeleton3D.h"
#include "platform/CCFileUtils.h" #include "platform/CCFileUtils.h"
#include "base/CCConfiguration.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -68,6 +69,7 @@ bool Animate3D::init(Animation3D* animation)
animation->retain(); animation->retain();
setDuration(animation->getDuration()); setDuration(animation->getDuration());
setOriginInterval(animation->getDuration()); setOriginInterval(animation->getDuration());
setHighQuality(Configuration::getInstance()->getHighAnimate3DQuality());
return true; return true;
} }
@ -83,6 +85,7 @@ bool Animate3D::init(Animation3D* animation, float fromTime, float duration)
setOriginInterval(duration); setOriginInterval(duration);
_animation = animation; _animation = animation;
animation->retain(); animation->retain();
setHighQuality(Configuration::getInstance()->getHighAnimate3DQuality());
return true; return true;
} }
@ -310,29 +313,27 @@ void Animate3D::update(float t)
t = 1 - t; t = 1 - t;
t = _start + t * _last; t = _start + t * _last;
for (const auto& it : _boneCurves)
{
for (const auto& it : _boneCurves) { for (const auto& it : _boneCurves) {
auto bone = it.first; auto bone = it.first;
auto curve = it.second; auto curve = it.second;
if (curve->translateCurve) if (curve->translateCurve)
{ {
curve->translateCurve->evaluate(t, transDst, EvaluateType::INT_LINEAR); curve->translateCurve->evaluate(t, transDst, _translateEvaluate);
trans = &transDst[0]; trans = &transDst[0];
} }
if (curve->rotCurve) if (curve->rotCurve)
{ {
curve->rotCurve->evaluate(t, rotDst, EvaluateType::INT_QUAT_SLERP); curve->rotCurve->evaluate(t, rotDst, _roteEvaluate);
rot = &rotDst[0]; rot = &rotDst[0];
} }
if (curve->scaleCurve) if (curve->scaleCurve)
{ {
curve->scaleCurve->evaluate(t, scaleDst, EvaluateType::INT_LINEAR); curve->scaleCurve->evaluate(t, scaleDst, _scaleEvaluate);
scale = &scaleDst[0]; scale = &scaleDst[0];
} }
bone->setAnimationValue(trans, rot, scale, this, _weight); bone->setAnimationValue(trans, rot, scale, this, _weight);
} }
}
for (const auto& it : _nodeCurves) for (const auto& it : _nodeCurves)
{ {
@ -341,18 +342,18 @@ void Animate3D::update(float t)
Mat4 transform; Mat4 transform;
if (curve->translateCurve) if (curve->translateCurve)
{ {
curve->translateCurve->evaluate(t, transDst, EvaluateType::INT_LINEAR); curve->translateCurve->evaluate(t, transDst, _translateEvaluate);
transform.translate(transDst[0], transDst[1], transDst[2]); transform.translate(transDst[0], transDst[1], transDst[2]);
} }
if (curve->rotCurve) if (curve->rotCurve)
{ {
curve->rotCurve->evaluate(t, rotDst, EvaluateType::INT_QUAT_SLERP); curve->rotCurve->evaluate(t, rotDst, _roteEvaluate);
Quaternion qua(rotDst[0], rotDst[1], rotDst[2], rotDst[3]); Quaternion qua(rotDst[0], rotDst[1], rotDst[2], rotDst[3]);
transform.rotate(qua); transform.rotate(qua);
} }
if (curve->scaleCurve) if (curve->scaleCurve)
{ {
curve->scaleCurve->evaluate(t, scaleDst, EvaluateType::INT_LINEAR); curve->scaleCurve->evaluate(t, scaleDst, _scaleEvaluate);
transform.scale(scaleDst[0], scaleDst[1], scaleDst[2]); transform.scale(scaleDst[0], scaleDst[1], scaleDst[2]);
} }
node->setAdditionalTransform(&transform); node->setAdditionalTransform(&transform);
@ -383,6 +384,28 @@ void Animate3D::setOriginInterval(float interval)
_originInterval = interval; _originInterval = interval;
} }
void Animate3D::setHighQuality(bool isHighQuality)
{
if (isHighQuality)
{
_translateEvaluate = EvaluateType::INT_LINEAR;
_roteEvaluate = EvaluateType::INT_QUAT_SLERP;
_scaleEvaluate = EvaluateType::INT_LINEAR;
}
else
{
_translateEvaluate = EvaluateType::INT_NEAR;
_roteEvaluate = EvaluateType::INT_NEAR;
_scaleEvaluate = EvaluateType::INT_NEAR;
}
_isHighQuality = isHighQuality;
}
bool Animate3D::getHighQuality() const
{
return _isHighQuality;
}
Animate3D::Animate3D() Animate3D::Animate3D()
: _state(Animate3D::Animate3DState::Running) : _state(Animate3D::Animate3DState::Running)
, _animation(nullptr) , _animation(nullptr)
@ -395,7 +418,7 @@ Animate3D::Animate3D()
, _lastTime(0.0f) , _lastTime(0.0f)
, _originInterval(0.0f) , _originInterval(0.0f)
{ {
setHighQuality(true);
} }
Animate3D::~Animate3D() Animate3D::~Animate3D()
{ {

View File

@ -105,6 +105,12 @@ public:
CC_DEPRECATED_ATTRIBUTE bool getPlayBack() const { return _playReverse; } CC_DEPRECATED_ATTRIBUTE bool getPlayBack() const { return _playReverse; }
CC_DEPRECATED_ATTRIBUTE void setPlayBack(bool reverse) { _playReverse = reverse; } CC_DEPRECATED_ATTRIBUTE void setPlayBack(bool reverse) { _playReverse = reverse; }
/**get & set high quality
* @param true: is high quality, false: is low quality
*/
void setHighQuality(bool isHighQuality);
bool getHighQuality() const;
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
Animate3D(); Animate3D();
@ -137,6 +143,13 @@ protected:
float _accTransTime; // acculate transition time float _accTransTime; // acculate transition time
float _lastTime; // last t (0 - 1) float _lastTime; // last t (0 - 1)
float _originInterval;// save origin interval time float _originInterval;// save origin interval time
// animation quality
EvaluateType _translateEvaluate;
EvaluateType _roteEvaluate;
EvaluateType _scaleEvaluate;
bool _isHighQuality; // true: is high quality, false: is low quality
std::unordered_map<Bone3D*, Animation3D::Curve*> _boneCurves; //weak ref std::unordered_map<Bone3D*, Animation3D::Curve*> _boneCurves; //weak ref
std::unordered_map<Node*, Animation3D::Curve*> _nodeCurves; std::unordered_map<Node*, Animation3D::Curve*> _nodeCurves;

View File

@ -874,6 +874,8 @@ bool Bundle3D::loadMaterialsBinary(MaterialDatas& materialdatas)
{ {
NMaterialData materialData; NMaterialData materialData;
materialData.id = _binaryReader.readString(); materialData.id = _binaryReader.readString();
// skip: diffuse(3), ambient(3), emissive(3), opacity(1), specular(3), shininess(1)
float data[14]; float data[14];
_binaryReader.read(&data,sizeof(float), 14); _binaryReader.read(&data,sizeof(float), 14);

View File

@ -50,6 +50,7 @@ Configuration::Configuration()
, _maxDirLightInShader(1) , _maxDirLightInShader(1)
, _maxPointLightInShader(1) , _maxPointLightInShader(1)
, _maxSpotLightInShader(1) , _maxSpotLightInShader(1)
, _isAnimate3DHighQuality(true)
{ {
} }
@ -262,6 +263,11 @@ int Configuration::getMaxSupportSpotLightInShader() const
return _maxSpotLightInShader; return _maxSpotLightInShader;
} }
bool Configuration::getHighAnimate3DQuality() const
{
return _isAnimate3DHighQuality;
}
// //
// generic getters for properties // generic getters for properties
// //
@ -350,6 +356,12 @@ void Configuration::loadConfigFile(const std::string& filename)
_maxSpotLightInShader = _valueDict[name].asInt(); _maxSpotLightInShader = _valueDict[name].asInt();
else else
_valueDict[name] = Value(_maxSpotLightInShader); _valueDict[name] = Value(_maxSpotLightInShader);
name = "cocos2d.x.3d.animate_high_quality";
if (_valueDict.find(name) != _valueDict.end())
_isAnimate3DHighQuality = _valueDict[name].asBool();
else
_valueDict[name] = Value(_isAnimate3DHighQuality);
} }
NS_CC_END NS_CC_END

View File

@ -164,6 +164,11 @@ public:
*/ */
int getMaxSupportSpotLightInShader() const; int getMaxSupportSpotLightInShader() const;
/** get 3d animate quality
* @return true: is high quality, false: is low quality
*/
bool getHighAnimate3DQuality() const;
/** Returns whether or not an OpenGL is supported. /** Returns whether or not an OpenGL is supported.
* *
* @param searchName A given search name. * @param searchName A given search name.
@ -230,6 +235,7 @@ protected:
int _maxDirLightInShader; //max support directional light in shader int _maxDirLightInShader; //max support directional light in shader
int _maxPointLightInShader; // max support point light in shader int _maxPointLightInShader; // max support point light in shader
int _maxSpotLightInShader; // max support spot light in shader int _maxSpotLightInShader; // max support spot light in shader
bool _isAnimate3DHighQuality; // animation 3d quality, true: is high quality, false: is low quality
ValueMap _valueDict; ValueMap _valueDict;
}; };

View File

@ -1348,6 +1348,19 @@ Sprite3DWithSkinTest::Sprite3DWithSkinTest()
listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DWithSkinTest::onTouchesEnded, this); listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DWithSkinTest::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
// swich camera
MenuItemFont::setFontName("fonts/arial.ttf");
MenuItemFont::setFontSize(15);
_menuItem = MenuItemFont::create("High Quality", CC_CALLBACK_1(Sprite3DWithSkinTest::switchAnimationQualityCallback,this));
_menuItem->setColor(Color3B(0,200,20));
auto menu = Menu::create(_menuItem,NULL);
menu->setPosition(Vec2::ZERO);
_menuItem->setPosition(VisibleRect::left().x + 50, VisibleRect::top().y -70);
addChild(menu, 1);
_highQuality = true;
_sprits.clear();
auto s = Director::getInstance()->getWinSize(); auto s = Director::getInstance()->getWinSize();
addNewSpriteWithCoords( Vec2(s.width/2, s.height/2) ); addNewSpriteWithCoords( Vec2(s.width/2, s.height/2) );
} }
@ -1366,8 +1379,9 @@ void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
auto sprite = EffectSprite3D::create(fileName); auto sprite = EffectSprite3D::create(fileName);
sprite->setScale(3); sprite->setScale(3);
sprite->setRotation3D(Vec3(0,180,0)); sprite->setRotation3D(Vec3(0,180,0));
addChild(sprite);
sprite->setPosition( Vec2( p.x, p.y) ); sprite->setPosition( Vec2( p.x, p.y) );
addChild(sprite);
_sprits.push_back(sprite);
auto animation = Animation3D::create(fileName); auto animation = Animation3D::create(fileName);
if (animation) if (animation)
@ -1386,8 +1400,28 @@ void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
speed = animate->getSpeed() - 0.5 * CCRANDOM_0_1(); speed = animate->getSpeed() - 0.5 * CCRANDOM_0_1();
} }
animate->setSpeed(inverse ? -speed : speed); animate->setSpeed(inverse ? -speed : speed);
animate->setTag(110);
animate->setHighQuality(_highQuality);
auto repeate = RepeatForever::create(animate);
repeate->setTag(110);
sprite->runAction(repeate);
}
}
sprite->runAction(RepeatForever::create(animate)); void Sprite3DWithSkinTest::switchAnimationQualityCallback(Ref* sender)
{
_highQuality = !_highQuality;
if (_highQuality)
_menuItem->setString("High Quality");
else
_menuItem->setString("Low Quality");
for (auto iter: _sprits)
{
RepeatForever* repAction = dynamic_cast<RepeatForever*>(iter->getActionByTag(110));
Animate3D* animate3D = dynamic_cast<Animate3D*>(repAction->getInnerAction());
animate3D->setHighQuality(_highQuality);
} }
} }
@ -2354,7 +2388,7 @@ NodeAnimationTest::NodeAnimationTest()
int tIndex = _vectorIndex - 1; int tIndex = _vectorIndex - 1;
if(tIndex < 0) if(tIndex < 0)
_vectorIndex = _sprites.size()-1; _vectorIndex = (int)_sprites.size()-1;
else else
_vectorIndex--; _vectorIndex--;

View File

@ -293,7 +293,12 @@ public:
void addNewSpriteWithCoords(Vec2 p); void addNewSpriteWithCoords(Vec2 p);
void switchAnimationQualityCallback(Ref* sender);
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override; void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override;
private:
std::vector<Sprite3D*> _sprits;
bool _highQuality;
MenuItemFont* _menuItem;
}; };
class Sprite3DWithSkinOutlineTest : public Sprite3DTestDemo class Sprite3DWithSkinOutlineTest : public Sprite3DTestDemo

View File

@ -22,6 +22,8 @@
<integer>1</integer> <integer>1</integer>
<key>cocos2d.x.3d.max_spot_light_in_shader</key> <key>cocos2d.x.3d.max_spot_light_in_shader</key>
<integer>1</integer> <integer>1</integer>
<key>cocos2d.x.3d.animate_high_quality</key>
<true/>
</dict> </dict>
<key>metadata</key> <key>metadata</key>
<dict> <dict>