フォーラムでLive2Dのcocos2dでつまづいていた人がいたので、シンプルなモーション再生させてみました。
・Live2Dコミュニティ - cocos2dx 3.9 mtnファイルの読み込みでエラー
開発環境
・Live2D Cocos2d-x 3.5のSimpleプロジェクトをカスタム
・Xcode ver 6.4 (Mac 10.10.5 - Yosemite)
修正手順
2)SampleLive2DSprite.hのコードを修正
モーションマネージャーを追加(コメントのADD参照)
SampleLive2DSprite.h
#ifndef __sampleCocos2dx__SampleLive2DSprite__
#define __sampleCocos2dx__SampleLive2DSprite__
#include "cocos2d.h"
#include "2d/CCSprite.h"
#include <vector>
#include "Live2DModelOpenGL.h"
#include "motion/Live2DMotion.h" // ADD
#include "motion/MotionQueueManager.h" // ADD
class SampleLive2DSprite :public cocos2d::DrawNode {
live2d::Live2DModelOpenGL* live2DModel ;
live2d::MotionQueueManager* motionManager; // ADD
std::vector<cocos2d::Texture2D*> textures ;
public:
SampleLive2DSprite();
virtual ~SampleLive2DSprite();
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
void onDraw(const cocos2d::Mat4 &transform, uint32_t flags);
static SampleLive2DSprite* createDrawNode();
protected:
cocos2d::CustomCommand _customCommand;
};
#endif /* defined(__sampleCocos2dx__SampleLive2DSprite__) */
3)SampleLive2DSprite.cppのコードを修正
モーションロードと再生処理を追加(コメントのADD参照)
SampleLive2DSprite.cpp
#include "SampleLive2DSprite.h"
#include "base/CCDirector.h"
#include "util/UtSystem.h"
#include "graphics/DrawProfileCocos2D.h"
#include "platform/CCFileUtils.h"
using namespace live2d;
USING_NS_CC;
const char* TEXTURES[] ={
"haru/haru_02.1024/texture_00.png" ,
"haru/haru_02.1024/texture_01.png" ,
"haru/haru_02.1024/texture_02.png" ,
NULL
};
AMotion* motion; // モーション ADD
SampleLive2DSprite::SampleLive2DSprite()
{
//Live2D Sample
const char* MODEL = "haru/haru_02.moc" ;
unsigned char* buf;
ssize_t bufSize;
buf = FileUtils::getInstance()->getFileData(MODEL,"rb", &bufSize);
// mocロード
live2DModel = Live2DModelOpenGL::loadModel( buf,bufSize ) ;
free(buf);
// Textureロード
for( int i = 0 ; TEXTURES[i] != NULL ; i++ ){
auto texture =Director::getInstance()->getTextureCache()->addImage(std::string(TEXTURES[i]));
Texture2D::TexParams texParams = { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
texture->setTexParameters(texParams);
texture->generateMipmap();
int glTexNo = texture->getName() ;
live2DModel->setTexture( i , glTexNo ) ;// テクスチャとモデルを結びつける
textures.push_back( texture ) ;
}
// Motionロード ADD Start
const char* MOTION = "haru/motions/tapBody_00.mtn";
unsigned char* motionbuf;
ssize_t MotionSize;
motionbuf = FileUtils::getInstance()->getFileData(MOTION,"rb", &MotionSize);
// モーションロード
motion=Live2DMotion::loadMotion(motionbuf,(int)MotionSize);
// モーションマネージャー生成
motionManager = new MotionQueueManager();
// Motionロード ADD End
// Live2Dモデルはローカル座標で左上を原点にして(CanvasWidth、CanvasWidth)
// のサイズになるため、以下のようにして調整してください。
float w = Director::getInstance()->getWinSize().width;
float h = Director::getInstance()->getWinSize().height;
float scx = 2.0 / live2DModel->getCanvasWidth() ;
float scy = -2.0 / live2DModel->getCanvasWidth() * (w/h);
float x = -1 ;
float y = 1 ;
float matrix []= {
scx , 0 , 0 , 0 ,
0 , scy ,0 , 0 ,
0 , 0 , 1 , 0 ,
x , y , 0 , 1
} ;
live2DModel->setMatrix(matrix) ;// 位置を設定
}
SampleLive2DSprite::~SampleLive2DSprite()
{
delete live2DModel;
// テクスチャを解放
Director::getInstance()->getTextureCache()->removeTextureForKey(std::string(TEXTURES[0]));
Director::getInstance()->getTextureCache()->removeTextureForKey(std::string(TEXTURES[1]));
Director::getInstance()->getTextureCache()->removeTextureForKey(std::string(TEXTURES[2]));
}
void SampleLive2DSprite::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
{
DrawNode::draw(renderer, transform, flags);
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(SampleLive2DSprite::onDraw, this, transform, flags);
renderer->addCommand(&_customCommand);
}
void SampleLive2DSprite::onDraw(const cocos2d::Mat4 &transform, uint32_t flags)
{
kmGLPushMatrix();
kmGLLoadMatrix(&transform);
// モデルのパラメータを変更。動作確認用です。
double t = (UtSystem::getUserTimeMSec()/1000.0) * 2 * M_PI ;// 1秒ごとに2π(1周期)増える
// double cycle=3.0;// パラメータが一周する時間(秒)
// double value=sin( t/cycle );// -1から1の間を周期ごとに変化する
// live2DModel->setParamFloat( "PARAM_ANGLE_X" , (float) (30 * value) ) ;// PARAM_ANGLE_Xのパラメータが[cycle]秒ごとに-30から30まで変化する
// Motion再生 ADD Start
if(motionManager->isFinished())
{
motionManager->startMotion(motion, false);
}
motionManager->updateParam(live2DModel);
// Motion再生 ADD End
// Live2Dの描画前と描画後に以下の関数を呼んでください
// live2d::DrawProfileCocos2D::preDraw() ;
// live2d::DrawProfileCocos2D::postDraw() ;
// これはOpenGLの状態をもとに戻すための処理です。
// これを行わない場合、Cocos2DかLive2Dどちらかで状態の不整合が起こります。
live2d::DrawProfileCocos2D::preDraw();
live2DModel->update() ;
live2DModel->draw() ;
live2d::DrawProfileCocos2D::postDraw() ;
kmGLPopMatrix();
}
SampleLive2DSprite* SampleLive2DSprite::createDrawNode()
{
SampleLive2DSprite *ret = new SampleLive2DSprite();
if (ret && ret->init())
{
ret->autorelease();
return ret;
}
else
{
CC_SAFE_DELETE(ret);
return nullptr;
}
}