VRCQuestTools icon indicating copy to clipboard operation
VRCQuestTools copied to clipboard

Implement AAOMergePhysBoneProvider for Avatar Optimizer integration

Open Copilot opened this issue 2 months ago • 2 comments

Adds reflection-based provider to access AAO (Avatar Optimizer) MergePhysBone components for performance calculation. AAO's MergePhysBone is internal, requiring reflection to extract merged PhysBone data.

Implementation

  • AAOMergePhysBoneProvider: Extends VRCPhysBoneProviderBase with reflection-based access to AAO's internal componentsSet field
  • Type Resolution: Uses SystemUtility.GetTypeByName("Anatawa12.AvatarOptimizer.MergePhysBone") for proper type validation
  • No Caching: GetPhysBones() fetches latest components on each call to ensure up-to-date data
  • GetAsList() Method: Uses AAO's GetAsList() method on PrefabSafeSet to access components, matching AAO's own MergePhysBoneProcessor implementation
  • Static Reflection Caching: All reflection results (Type, FieldInfo, MethodInfo) are cached statically across all provider instances for optimal performance
  • Type-Safe Method Caching: GetAsList method cache validates declaring type to prevent mismatches
  • Merging: Colliders and ignore transforms merged with .Distinct() for duplicate removal
  • Simplified Properties: RootTransform returns component transform; MultiChildType always returns Ignore

Performance Optimization

  • Static Type Cache: MergePhysBone Type looked up once and reused across all instances
  • Static FieldInfo Cache: componentsSet field looked up once and reused across all instances
  • Static MethodInfo Cache: GetAsList method looked up once with type validation and reused across all calls
  • Significant performance improvement when creating multiple provider instances or calling GetPhysBones() repeatedly

Example Usage

// AAO MergePhysBone component from scene
Component aaoMergePhysBone = GetComponent<AAOMergePhysBone>();

// Wrap with provider
var provider = new AAOMergePhysBoneProvider(aaoMergePhysBone);

// Access merged PhysBones for performance calculation (always fresh data)
VRCPhysBone[] physBones = provider.GetPhysBones();
List<Component> allColliders = provider.Colliders; // Deduplicated across all PhysBones

Testing

8 test cases with mock AAO component covering:

  • PhysBone array extraction from componentsSet using GetAsList() method
  • Duplicate removal in colliders and ignore transforms
  • Null filtering and empty array handling
  • Component validation with proper type checking
Original prompt

This section details on the original issue you should resolve

<issue_title>AAOMergePhysBoneProviderの実装</issue_title> <issue_description>### タスク概要

タイトルの通り。

背景・目的

元Isuueの通り。

技術要件

  • AAOのMergePhysBoneコンポーネントを抽象化してアクセスするクラスを作成する
    • AAOのコンポーネントはinternalであるためリフレクションが必要なことに留意する
  • マージ対象となるPhysBone配列の情報だけAAOから受け取る。他のパラメータは現状では無視してよい。
  • パフォーマンス計算に必要なボーン情報やコライダー情報は、マージ対象のPhysBoneから得られる情報を単純に重複なしでマージしたものを返せばよい。

補足情報

No response

完了条件

ビルドエラーのないこと RoslynAnalyzerによる指摘がないこと</issue_description>

Comments on the Issue (you are @copilot in this section)

  • Fixes kurotu/VRCQuestTools#144

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot avatar Dec 04 '25 23:12 Copilot