| 458 | } |
| 459 | |
| 460 | void AnimatedModel::SetBlendShapeWeight(const StringView& name, float value) |
| 461 | { |
| 462 | const auto* model = SkinnedModel.Get(); |
| 463 | CHECK(model); |
| 464 | model->WaitForLoaded(); |
| 465 | value = Math::Clamp(value, -1.0f, 1.0f); |
| 466 | const bool isZero = Math::IsZero(value); |
| 467 | if (!_deformation && !isZero) |
| 468 | _deformation = New<MeshDeformation>(); |
| 469 | Function<void(const MeshBase*, MeshDeformationData&)> deformer; |
| 470 | deformer.Bind<AnimatedModel, &AnimatedModel::RunBlendShapeDeformer>(this); |
| 471 | for (int32 i = 0; i < _blendShapeWeights.Count(); i++) |
| 472 | { |
| 473 | auto& e = _blendShapeWeights[i]; |
| 474 | if (e.First == name) |
| 475 | { |
| 476 | if (isZero) |
| 477 | { |
| 478 | _blendShapeWeights.RemoveAt(i); |
| 479 | |
| 480 | // Remove deformers for meshes using this blend shape |
| 481 | for (const auto& lod : model->LODs) |
| 482 | { |
| 483 | for (const auto& mesh : lod.Meshes) |
| 484 | { |
| 485 | for (const auto& blendShape : mesh.BlendShapes) |
| 486 | { |
| 487 | if (blendShape.Name == name) |
| 488 | { |
| 489 | for (int32 j = 0; j < _blendShapeMeshes.Count(); j++) |
| 490 | { |
| 491 | auto& blendShapeMesh = _blendShapeMeshes[j]; |
| 492 | if (blendShapeMesh.LODIndex == mesh.GetLODIndex() && blendShapeMesh.MeshIndex == mesh.GetIndex()) |
| 493 | { |
| 494 | blendShapeMesh.Usages--; |
| 495 | if (blendShapeMesh.Usages == 0) |
| 496 | { |
| 497 | _deformation->RemoveDeformer(blendShapeMesh.LODIndex, blendShapeMesh.MeshIndex, MeshBufferType::Vertex0, deformer); |
| 498 | _blendShapeMeshes.RemoveAt(j); |
| 499 | } |
| 500 | break; |
| 501 | } |
| 502 | } |
| 503 | break; |
| 504 | } |
| 505 | } |
| 506 | } |
| 507 | } |
| 508 | } |
| 509 | else if (Math::NotNearEqual(e.Second, value)) |
| 510 | { |
| 511 | // Update blend shape weight |
| 512 | e.Second = value; |
| 513 | |
| 514 | // Dirty deformers for meshes using this blend shape |
| 515 | for (const auto& lod : model->LODs) |
| 516 | { |
| 517 | for (const auto& mesh : lod.Meshes) |
nothing calls this directly
no test coverage detected