模型重叠检测
最終更新: 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座标的最大值和最小值创建一个矩形范围,
从模型的变换矩形对检查对象的画面座标进行逆向转变,检查是否在矩形内。
使用此函数时请注意以下事项:
- 如果模型的转变座标中包含旋转,将无法正确转变。
- 当接近四边形的图形网格通过旋转变形器等旋转时,尺寸会发生显著变化。
请问这篇文章对您有帮助吗?
是否