1. 新增模型区域点击接口,同时为Windows添加了完美的透明区域鼠标透穿功能,以及Linux的基本点击区域识别功能(即非完美透传)
2. 更新了LICENSE
This commit is contained in:
@@ -80,7 +80,19 @@ public:
|
||||
*/
|
||||
void StopLipSync();
|
||||
|
||||
/**
|
||||
* @brief 获取模型是否有命中区域定义
|
||||
* @return 是否有命中区域
|
||||
*/
|
||||
[[nodiscard]] bool HasHitAreas() const;
|
||||
|
||||
/**
|
||||
* @brief 检测点是否在模型的任何可见部分上
|
||||
* @param x 视图坐标X
|
||||
* @param y 视图坐标Y
|
||||
* @return 是否命中
|
||||
*/
|
||||
[[nodiscard]] bool IsPointOnModel(Csm::csmFloat32 x, Csm::csmFloat32 y);
|
||||
|
||||
/**
|
||||
* @brief model3.jsonが置かれたディレクトリとファイルパスからモデルを生成する \n
|
||||
@@ -177,6 +189,15 @@ protected:
|
||||
*/
|
||||
void DoDraw();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 使用Drawable检测(当没有命中区域时使用)
|
||||
* @param x 视图坐标X
|
||||
* @param y 视图坐标Y
|
||||
* @return 是否命中
|
||||
*/
|
||||
[[nodiscard]] bool IsPointOnDrawable(Csm::csmFloat32 x, Csm::csmFloat32 y);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief model3.jsonからモデルを生成する。<br>
|
||||
|
||||
@@ -82,6 +82,76 @@ LAppModel::~LAppModel()
|
||||
}
|
||||
delete(_modelSetting);
|
||||
}
|
||||
|
||||
bool LAppModel::HasHitAreas() const {
|
||||
return _modelSetting && _modelSetting->GetHitAreasCount() > 0;
|
||||
}
|
||||
|
||||
bool LAppModel::IsPointOnModel(const csmFloat32 x, const csmFloat32 y)
|
||||
{
|
||||
if (_model == nullptr || _opacity < 0.1f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 如果有命中区域,使用HitTest(是否存在命中区域,这取决于模型是否定义这两部分信息)
|
||||
/* 通常是这样的信息,在.model3.json当中
|
||||
"HitAreas": [
|
||||
{
|
||||
"Id": "HitAreaHead",
|
||||
"Name": "Head"
|
||||
},
|
||||
{
|
||||
"Id": "HitAreaBody",
|
||||
"Name": "Body"
|
||||
}
|
||||
]
|
||||
*/
|
||||
if (HasHitAreas())
|
||||
{
|
||||
// 检查常用命中区域
|
||||
const bool hit = HitTest(LAppDefine::HitAreaNameHead, x, y) ||
|
||||
HitTest(LAppDefine::HitAreaNameBody, x, y);
|
||||
if (_debugMode && hit)
|
||||
{
|
||||
LAppPal::PrintLogLn("[APP]Hit model via HitArea at (%.2f, %.2f)", x, y);
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
// 如果没有命中区域,使用Drawable检测
|
||||
return IsPointOnDrawable(x, y);
|
||||
}
|
||||
|
||||
bool LAppModel::IsPointOnDrawable(const csmFloat32 x, const csmFloat32 y)
|
||||
{
|
||||
if (_model == nullptr || _opacity < 0.01f) // 接近完全透明
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 获取所有Drawable的数量
|
||||
const csmInt32 drawableCount = _model->GetDrawableCount();
|
||||
// 遍历所有Drawable
|
||||
for (csmInt32 i = 0; i < drawableCount; ++i)
|
||||
{
|
||||
// 获取Drawable的ID
|
||||
const CubismIdHandle drawableId = _model->GetDrawableId(i);
|
||||
// 检查Drawable是否可见
|
||||
if (_model->GetDrawableDynamicFlagIsVisible(i))
|
||||
{
|
||||
// 使用CubismUserModel提供的IsHit函数检测
|
||||
if (IsHit(drawableId, x, y))
|
||||
{
|
||||
if (_debugMode)
|
||||
{
|
||||
const csmChar* drawableName = _model->GetDrawableId(i)->GetString().GetRawString();
|
||||
LAppPal::PrintLogLn("[APP]Hit drawable: %s at (%.2f, %.2f)",
|
||||
drawableName, x, y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LAppModel::LoadAssets(const csmChar* dir, const csmChar* fileName)
|
||||
{
|
||||
|
||||
+11
-23
@@ -269,35 +269,23 @@ float LAppView::TransformScreenY(float deviceY) const
|
||||
#include "Id/CubismIdManager.hpp"
|
||||
bool LAppView::IsModelHit(const float deviceX, const float deviceY) const {
|
||||
const LAppLive2DManager* live2DManager = LAppLive2DManager::GetInstance();
|
||||
if (!live2DManager || live2DManager->GetModelNum() == 0) {
|
||||
if (!live2DManager || live2DManager->GetModelNum() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 坐标转换(设备坐标 -> Live2D View 坐标)
|
||||
const csmFloat32 viewX = _deviceToScreen->TransformX(deviceX);
|
||||
const csmFloat32 viewY = _deviceToScreen->TransformY(deviceY);
|
||||
// 转换到视图坐标
|
||||
const csmFloat32 viewX = TransformViewX(deviceX);
|
||||
const csmFloat32 viewY = TransformViewY(deviceY);
|
||||
|
||||
// 正确获取 ID Handle(在 SDK 初始化后调用)
|
||||
static const Csm::CubismId* bodyId = nullptr;
|
||||
static const Csm::CubismId* headId = nullptr;
|
||||
if (!bodyId) {
|
||||
bodyId = CubismFramework::GetIdManager()->GetId("Body");
|
||||
headId = CubismFramework::GetIdManager()->GetId("Head");
|
||||
// 遍历所有模型
|
||||
LAppModel* model = live2DManager->GetModel(0);
|
||||
if (model && model->IsPointOnModel(viewX, viewY)) // 调用二次封装的IsPointOnModel函数
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 遍历所有模型进行碰撞检测
|
||||
const csmUint32 modelCount = live2DManager->GetModelNum();
|
||||
for (csmUint32 i = 0; i < modelCount; ++i) {
|
||||
LAppModel* model = live2DManager->GetModel(i);
|
||||
if (!model || !model->GetModel()) continue;
|
||||
|
||||
// 检查命中区域(修正:使用 SDK 提供的 ID)
|
||||
if (model->IsHit(bodyId, viewX, viewY) || model->IsHit(headId, viewX, viewY)) {
|
||||
return true; // 击中模型
|
||||
}
|
||||
}
|
||||
|
||||
return false; // 未击中模型
|
||||
return false;
|
||||
}
|
||||
|
||||
void LAppView::PreModelDraw(LAppModel& refModel)
|
||||
|
||||
Reference in New Issue
Block a user