LoginSignup
8
9

More than 5 years have passed since last update.

cocos2dでLive2Dモーション再生

Last updated at Posted at 2016-03-14

フォーラムでLive2Dのcocos2dでつまづいていた人がいたので、シンプルなモーション再生させてみました。
Live2Dコミュニティ - cocos2dx 3.9 mtnファイルの読み込みでエラー

開発環境

Live2D Cocos2d-x 3.5のSimpleプロジェクトをカスタム
・Xcode ver 6.4 (Mac 10.10.5 - Yosemite)

修正手順

1)モーションファイルをResoucesフォルダ配下におく
screenshoto.png

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;
    }
}

実行結果

これで簡単にモーション再生できました!
001.gif

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9