mirror of https://github.com/axmolengine/axmol.git
267 lines
8.2 KiB
C++
267 lines
8.2 KiB
C++
/**
|
|
* Copyright(c) Live2D Inc. All rights reserved.
|
|
*
|
|
* Use of this source code is governed by the Live2D Open Software license
|
|
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
|
|
*/
|
|
|
|
#include "LAppView.hpp"
|
|
#include "LAppLive2DManager.hpp"
|
|
#include "LAppDefine.hpp"
|
|
#include "LAppPal.hpp"
|
|
#include "LAppModel.hpp"
|
|
|
|
using namespace Csm;
|
|
using namespace LAppDefine;
|
|
|
|
USING_NS_AX;
|
|
|
|
LAppView::LAppView(): DrawNode()
|
|
, _debugRects(NULL)
|
|
{
|
|
}
|
|
|
|
void LAppView::onEnter()
|
|
{
|
|
DrawNode::onEnter();
|
|
|
|
// タッチ関係のイベント管理
|
|
touchMgr = new TouchManager();
|
|
|
|
// デバイス座標からスクリーン座標に変換するための
|
|
deviceToScreen = new CubismMatrix44();
|
|
|
|
// 画面の表示の拡大縮小や移動の変換を行う行列
|
|
viewMatrix = new CubismViewMatrix();
|
|
|
|
Size size = Director::getInstance()->getWinSize();
|
|
|
|
float width = size.width;
|
|
float height = size.height;
|
|
// 縦サイズを基準とする
|
|
float ratio = width / height;
|
|
float left = -ratio;
|
|
float right = ratio;
|
|
float bottom = ViewLogicalLeft;
|
|
float top = ViewLogicalRight;
|
|
|
|
viewMatrix->SetScreenRect(left, right, bottom, top); // デバイスに対応する画面の範囲。 Xの左端, Xの右端, Yの下端, Yの上端
|
|
viewMatrix->Scale(ViewScale, ViewScale);
|
|
|
|
deviceToScreen->LoadIdentity(); // サイズが変わった際などリセット必須
|
|
if (width > height)
|
|
{
|
|
float screenW = fabsf(right - left);
|
|
deviceToScreen->ScaleRelative(screenW / width, -screenW / width);
|
|
}
|
|
else
|
|
{
|
|
float screenH = fabsf(top - bottom);
|
|
deviceToScreen->ScaleRelative(screenH / height, -screenH / height);
|
|
}
|
|
deviceToScreen->TranslateRelative(-width / 2.0f, -height / 2.0f);
|
|
|
|
// 表示範囲の設定
|
|
viewMatrix->SetMaxScale(ViewMaxScale); // 限界拡大率
|
|
viewMatrix->SetMinScale(ViewMinScale); // 限界縮小率
|
|
|
|
// 表示できる最大範囲
|
|
viewMatrix->SetMaxScreenRect(
|
|
ViewLogicalMaxLeft,
|
|
ViewLogicalMaxRight,
|
|
ViewLogicalMaxBottom,
|
|
ViewLogicalMaxTop
|
|
);
|
|
|
|
// イベントリスナー作成
|
|
EventListenerTouchAllAtOnce* listener = EventListenerTouchAllAtOnce::create();
|
|
|
|
// タッチメソッド設定
|
|
listener->onTouchesBegan = AX_CALLBACK_2(LAppView::onTouchesBegan, this);
|
|
listener->onTouchesMoved = AX_CALLBACK_2(LAppView::onTouchesMoved, this);
|
|
listener->onTouchesEnded = AX_CALLBACK_2(LAppView::onTouchesEnded, this);
|
|
|
|
// 優先度100でディスパッチャーに登録
|
|
this->getEventDispatcher()->addEventListenerWithFixedPriority(listener, 100);
|
|
}
|
|
|
|
void LAppView::onExit()
|
|
{
|
|
DrawNode::onExit();
|
|
|
|
delete touchMgr;
|
|
delete deviceToScreen;
|
|
delete viewMatrix;
|
|
}
|
|
|
|
void LAppView::draw(ax::Renderer* renderer, const ax::Mat4& transform, uint32_t flags)
|
|
{
|
|
DrawNode::draw(renderer, transform, flags);
|
|
onDraw(transform, flags);
|
|
}
|
|
|
|
void LAppView::onDraw(const ax::Mat4& transform, uint32_t flags)
|
|
{
|
|
_commandBuffer.PushCommandGroup();
|
|
|
|
Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
|
Director::getInstance()->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);
|
|
|
|
LAppLive2DManager* Live2DMgr = LAppLive2DManager::GetInstance();
|
|
|
|
Live2DMgr->SetViewMatrix(viewMatrix);
|
|
|
|
// Cubism更新・描画
|
|
Live2DMgr->OnUpdate(&_commandBuffer);
|
|
|
|
if (_debugRects)
|
|
{
|
|
drawDebugRects(Live2DMgr);
|
|
}
|
|
|
|
Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
|
|
|
_commandBuffer.PopCommandGroup();
|
|
}
|
|
|
|
void LAppView::onTouchesBegan(const std::vector<Touch*>& touches, Event* event)
|
|
{
|
|
// タッチ開始
|
|
size_t touchNum = touches.size();
|
|
|
|
if (touchNum == 1)
|
|
{
|
|
Point pt = touches[0]->getLocationInView();
|
|
if (DebugTouchLogEnable)LAppPal::PrintLog("[APP]touchesBegan x:%.0f y:%.0f", pt.x, pt.y);
|
|
touchMgr->touchesBegan(pt.x, pt.y);
|
|
}
|
|
}
|
|
|
|
void LAppView::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
|
|
{
|
|
// タッチ中
|
|
size_t touchNum = touches.size();
|
|
|
|
float screenX = this->transformScreenX(touchMgr->getX());
|
|
float screenY = this->transformScreenY(touchMgr->getY());
|
|
float viewX = this->transformViewX(touchMgr->getX());
|
|
float viewY = this->transformViewY(touchMgr->getY());
|
|
|
|
if (touchNum == 1)
|
|
{
|
|
Point pt = touches[0]->getLocationInView();
|
|
|
|
if (DebugTouchLogEnable)
|
|
LAppPal::PrintLog("[APP]touchesMoved device{x:%.0f y:%.0f} screen{x:%.2f y:%.2f} view{x:%.2f y:%.2f}", pt.x, pt.y, screenX, screenY, viewX, viewY);
|
|
|
|
touchMgr->touchesMoved(pt.x, pt.y);
|
|
}
|
|
LAppLive2DManager* live2DMgr = LAppLive2DManager::GetInstance();
|
|
live2DMgr->OnDrag(viewX, viewY);
|
|
}
|
|
|
|
void LAppView::onTouchesEnded(const std::vector<ax::Touch*>& touches, ax::Event* event)
|
|
{
|
|
// タッチ終了
|
|
LAppLive2DManager* live2DMgr = LAppLive2DManager::GetInstance();
|
|
live2DMgr->OnDrag(0, 0);
|
|
|
|
if (touches.size() == 1)
|
|
{
|
|
// シングルタップ
|
|
float x = deviceToScreen->TransformX(touchMgr->getX()); // 論理座標変換した座標を取得。
|
|
float y = deviceToScreen->TransformY(touchMgr->getY()); // 論理座標変換した座標を取得。
|
|
if (DebugTouchLogEnable) LAppPal::PrintLog("[APP]touchesEnded x:%.2f y:%.2f", x, y);
|
|
live2DMgr->OnTap(x, y);
|
|
}
|
|
}
|
|
|
|
void LAppView::updateViewMatrix(float dx, float dy, float cx, float cy, float scale)
|
|
{
|
|
LAppLive2DManager* live2DMgr = LAppLive2DManager::GetInstance();
|
|
|
|
// 拡大縮小
|
|
viewMatrix->AdjustScale(cx, cy, scale);
|
|
|
|
// 移動
|
|
viewMatrix->AdjustTranslate(dx, dy);
|
|
|
|
live2DMgr->SetViewMatrix(viewMatrix);
|
|
}
|
|
|
|
float LAppView::transformViewX(float deviceX)
|
|
{
|
|
float screenX = deviceToScreen->TransformX(deviceX); // 論理座標変換した座標を取得。
|
|
return viewMatrix->InvertTransformX(screenX); // 拡大、縮小、移動後の値。
|
|
}
|
|
|
|
float LAppView::transformViewY(float deviceY)
|
|
{
|
|
float screenY = deviceToScreen->TransformY(deviceY); // 論理座標変換した座標を取得。
|
|
return viewMatrix->InvertTransformY(screenY); // 拡大、縮小、移動後の値。
|
|
}
|
|
|
|
float LAppView::transformScreenX(float deviceX)
|
|
{
|
|
return deviceToScreen->TransformX(deviceX);
|
|
}
|
|
|
|
float LAppView::transformScreenY(float deviceY)
|
|
{
|
|
return deviceToScreen->TransformY(deviceY);
|
|
}
|
|
|
|
void LAppView::setDebugRectsNode(DrawNode* debugRects)
|
|
{
|
|
_debugRects = debugRects;
|
|
}
|
|
|
|
void LAppView::drawDebugRects(LAppLive2DManager* manager) const
|
|
{
|
|
const Color4F hitAreaColor = Color4F(1.0f, 0, 0, 0.2f);
|
|
const Color4F userDataAreaColor = Color4F(0, 0, 1.0f, 0.2f);
|
|
|
|
CubismMatrix44 projection;
|
|
const Size window = Director::getInstance()->getWinSize();
|
|
const CubismVector2 windowSize = CubismVector2(window.width, window.height);
|
|
projection.Scale(1, window.width / window.height);
|
|
|
|
if (viewMatrix != NULL)
|
|
{
|
|
projection.MultiplyByMatrix(viewMatrix);
|
|
}
|
|
|
|
for (csmUint32 i = 0; i < manager->GetModelCount(); ++i)
|
|
{
|
|
_debugRects->clear();
|
|
LAppModel* model = manager->GetModel(i);
|
|
const Csm::csmVector<Csm::csmRectF>& userDataAreas = model->GetUserDataAreas(projection, windowSize);
|
|
for (csmUint32 j = 0; j < userDataAreas.GetSize(); ++j)
|
|
{
|
|
_debugRects->drawSolidRect(Vec2(userDataAreas[j].X, userDataAreas[j].Y)
|
|
, Vec2(userDataAreas[j].GetRight(), userDataAreas[j].GetBottom())
|
|
, userDataAreaColor);
|
|
}
|
|
|
|
const Csm::csmVector<Csm::csmRectF>& hitAreas = model->GetHitAreas(projection, windowSize);
|
|
for (csmUint32 j = 0; j < hitAreas.GetSize(); ++j)
|
|
{
|
|
_debugRects->drawSolidRect(Vec2(hitAreas[j].X, hitAreas[j].Y)
|
|
, Vec2(hitAreas[j].GetRight(), hitAreas[j].GetBottom())
|
|
, hitAreaColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
LAppView* LAppView::createDrawNode()
|
|
{
|
|
LAppView* ret = new(std::nothrow) LAppView();
|
|
if (ret && ret->init())
|
|
{
|
|
ret->autorelease();
|
|
return ret;
|
|
}
|
|
AX_SAFE_DELETE(ret);
|
|
return nullptr;
|
|
}
|