模型重叠检测
最終更新: 2023年1月26日
模型本身不具备重叠检测功能,但利用可以获取图形网格顶点信息的功能,可以实装重叠检测处理。
这里描述的“重叠检测”是指测试对象网格是否位于画面上的指定点。
重叠检测准备
在重叠检测中使用图形网格。
有关在Editor上为重叠检测准备图形网格,请参考“Editor上的重叠检测设置”。
准备好重叠检测后,需要用Cubism Viewer(for OW)的功能设置重叠检测,并嵌入到.model3.json文件中。
如果在Cubism Viewer(for OW)上设置重叠检测并输出,在.model3.json文件中会描述如下。
{
...
"HitAreas": [
{
"Id": "HitArea",
"Name": "Body"
}
]
}
在Cubism Viewer(for OW)中,只能注册设置了HitArea~和ID的图形网格,但是,
如果您直接使用文本编辑器加工.model3.json文件,则即使是HitArea~以外的图形网格,您也可以将其设置为重叠检测。
执行重叠检测
您可以使用以下任意函数进行重叠检测。
- Native(C++)的CubismUserModel::IsHit函数
- Web(TypeScript)的CubismUserModel.isHit函数
- Java的CubismUserModel.isHit函数
第一个参数指定对象Drawable的ID,第二个和第三个参数指定要检查的绘制上的X和Y值。
// C++
CubismUserModel model;
CubismIdHandle drawId = CubismFramework::GetIdManager()->GetId("HitArea1");
if(model.IsHit(drawId, x, y))
{
//处理
}
// TypeScript
let model: CubismUserModel;
let drawId: CubismIdHandle = CubismFramework.getIdManager().getId("HitArea1");
if(mode.isHit(drawId, x, y))
{
// 处理
}
// Java
CubismUserModel model;
CubismId drawId = CubismFramework.getIdManager().getId("HitArea1");
if(model.isHit(drawId, x, y)){
// 处理
}
重叠检测的内容及注意事项
// C++
csmBool CubismUserModel::IsHit(CubismIdHandle drawableId, csmFloat32 pointX, csmFloat32 pointY)
{
csmInt32 drawIndex = _model->GetDrawableIndex(drawableId);
if (drawIndex < 0)
{
return false; // 不存在时为false
}
csmInt32 count = _model->GetDrawableVertexCount(drawIndex);
const csmFloat32* vertices = _model->GetDrawableVertices(drawIndex);
csmFloat32 left = _model->GetCanvasWidth();
csmFloat32 right = 0.0f;
csmFloat32 top = _model->GetCanvasHeight();
csmFloat32 bottom = 0.0f;
for (csmInt32 j = 0; j < count; ++j)
{
csmFloat32 x = vertices[Constant::VertexOffset + j * Constant::VertexStep];
csmFloat32 y = vertices[Constant::VertexOffset + j * Constant::VertexStep + 1];
if (x < left)
{
left = x; // Min x
}
if (x > right)
{
right = x; // Max x
}
if (y < top)
{
top = y; // Min y
}
if (y > bottom)
{
bottom = y; // Max y
}
}
csmFloat32 tx = _modelMatrix->InvertTransformX(pointX);
csmFloat32 ty = _modelMatrix->InvertTransformY(pointY);
return ((left <= tx) && (tx <= right) && (top <= ty) && (ty <= bottom));
}
// TypeScript
public isHit(drawableId: CubismIdHandle, pointX: number, pointY: number): boolean
{
const drawIndex: number = this._model.getDrawableIndex(drawableId);
if(drawIndex < 0)
{
return false; // 不存在时为false
}
const count: number = this._model.getDrawableVertexCount(drawIndex);
const vertices: Float32Array = this._model.getDrawableVertices(drawIndex);
let left: number = vertices[0];
let right: number = vertices[0];
let top: number = vertices[1];
let bottom: number = vertices[1];
for(let j: number = 1; j < count; ++j)
{
let x = vertices[Constant.vertexOffset + j * Constant.vertexStep];
let y = vertices[Constant.vertexOffset + j * Constant.vertexStep + 1];
if(x < left)
{
left = x; // Min x
}
if(x > right)
{
right = x; // Max x
}
if(y < top)
{
top = y; // Min y
}
if(y > bottom)
{
bottom = y; // Max y
}
}
const tx: number = this._modelMatrix.invertTransformX(pointX);
const ty: number = this._modelMatrix.invertTransformY(pointY);
return ((left <= tx) && (tx <= right) && (top <= ty) && (ty <= bottom));
}
// Java
public boolean isHit(CubismId drawableId, float pointX, float pointY){
final int drawIndex = model.getDrawableIndex(drawableId);
if (drawIndex < 0) {
return false;
}
final int count = model.getDrawableVertexCount(drawIndex);
final float[] vertices = model.getDrawableVertices(drawIndex);
float left = vertices[0];
float right = vertices[0];
float top = vertices[1];
float bottom = vertices[1];
for (int i = 1; i < count; ++i)
{
float x = vertices[VERTEX_OFFSET + i * VERTEX_STEP];
float y = vertices[VERTEX_OFFSET + i * VERTEX_STEP + 1];
if (x < left) {
// Min x
left = x;
}
if (x > right) {
// Max x
right = x;
}
if (y < top) {
// Min y
top = y;
}
if (y > bottom) {
// Max y
bottom = y;
}
}
final float tx = modelMatrix.invertTransformX(pointX);
final float ty = modelMatrix.invertTransformY(pointY);
return (left <= tx) && (tx <= right) && (top <= ty) && (ty <= bottom);
}
重叠检测的机制是扫描图形网格的所有顶点,并通过顶点的XY座标的最大值和最小值创建一个矩形范围,
从模型的变换矩形对检查对象的画面座标进行逆向转变,检查是否在矩形内。
使用此函数时请注意以下事项:
- 如果模型的转变座标中包含旋转,将无法正确转变。
- 当接近四边形的图形网格通过旋转变形器等旋转时,尺寸会发生显著变化。
请问这篇文章对您有帮助吗?
是否