コア技術
OpenFitterで使用されている主要な技術とアルゴリズムについて説明します。
概要
OpenFitterは、3Dアバター間での衣装フィッティングを実現するために、複数の技術を組み合わせています。Unity Editor拡張としてのフロントエンドと、Blenderをバックエンドとして使用する処理エンジンで構成されています。
フィッティングアルゴリズム
RBF(放射基底関数)変形
コアフィッティングアルゴリズムは RBF(Radial Basis Function)変形 を使用しています。
RBFとは
RBFは、限られた制御点から滑らかな変形を生成する数学的手法です。以下のような特徴があります:
- 局所的な影響: 各制御点は周囲の領域に主に影響を与えます
- 滑らかな補間: 制御点間の変形が自然で滑らかです
- 非線形変形: 複雑な体型の違いにも対応できます
フィッティングプロセスでの使用
- 制御点の設定: ソースとターゲットのボーン位置を制御点として使用
- RBF計算: ソースからターゲットへの変形を計算
- メッシュ変形: 衣装メッシュの各頂点にRBF変形を適用
ボーンポーズ転送
アバター間でボーンの姿勢(ポーズ)を転送します。
プロセス
- ボーンマッピング: ソースとターゲットのボーン構造を対応付け
- ポーズ抽出: ソースアバターのボーンポーズを抽出
- ポーズ適用: ターゲットアバターにポーズを適用
- ウェイト転送: スキニングウェイトを適切に転送
メッシュトポロジーの保持
フィッティング後もメッシュの基本構造を維持します:
- 頂点順序: 元の頂点順序を保持
- ポリゴン構造: ポリゴンの接続関係を維持
- UV座標: テクスチャ座標を保持
- マテリアル: マテリアル割り当てを維持
Blender統合
Blenderをバックエンドとして使用する理由
OpenFitterはBlenderを3D処理エンジンとして使用しています:
- 強力な3D処理: Blenderの成熟した3D処理機能を活用
- Pythonスクリプティング: 柔軟な自動化が可能
- GPL-3コードの互換性: open-fitter-coreのコードをそのまま使用可能
- オープンソース: 無料で再配布可能
ポータブルBlender
ユーザーの既存環境に影響を与えないよう、ポータブル版のBlenderを使用:
- 独立したインストール: システムのBlenderと干渉しない
- 自動ダウンロード: 初回セットアップ時に自動取得
- バージョン管理: 特定のバージョンを使用して互換性を保証
Pythonラッパースクリプト
Unity(C#)とBlender(Python)間の橋渡しを行います:
openfitter_wrapper.py
メインのラッパースクリプト:
# コマンドライン引数からパラメータを受け取る
# open-fitter-coreのフィッティング関数を呼び出す
# 進捗情報を標準出力に出力
# 結果をファイルに保存check_addon_status.py
アドオンのインストール状態を確認:
# Blenderアドオンが正しくインストールされているか確認
# バージョン情報を取得
# 結果をJSON形式で出力install_addon_dependencies.py
アドオンの依存関係をインストール:
# pipを使用して必要なPythonパッケージをインストール
# Blenderの内蔵Python環境にインストール
# インストール結果を報告コマンドライン実行
UnityからBlenderをコマンドラインで起動:
blender.exe --background --python openfitter_wrapper.py -- [arguments]--background: UIなしのバックグラウンドモード--python: 実行するPythonスクリプト--: 以降の引数をスクリプトに渡す
OpenFitterCore パラメータ
Blenderバックエンド(openfitter_wrapper.pyを介したコアスクリプト)が受け取る主要な引数は以下の通りです。
| 引数 | 形式 | 必須 | 説明 |
|---|---|---|---|
--input | パス | YES | 入力となる衣装FBXの絶対パス。 |
--output | パス | YES | 出力先FBXの絶対パス。 |
--base | パス | YES | 基準となる .blend ファイルのパス。 |
--base-fbx | パスリスト | YES | ベースキャラクターのFBXパス。複数ある場合は ; で区切ります。 |
--config | パスリスト | YES | 設定JSONのパス。複数ある場合は ; で区切ります。 |
--init-pose | パス | YES | 初期ポーズ情報のJSONパス。 |
--hips-position | 文字列 | NO | Hipsボーンの位置指定。 |
--blend-shapes | 文字列リスト | NO | 適用するブレンドシェイプ名のリスト(; 区切り)。 |
--blend-shape-values | 数値リスト | NO | 各ブレンドシェイプの適用値(; 区切り)。 |
--blend-shape-mappings | 文字列リスト | NO | ブレンドシェイプのマッピング定義。 |
--target-meshes | 文字列リスト | NO | 処理対象とするメッシュ名のリスト。 |
--mesh-renderers | 文字列リスト | NO | メッシュレンダラーの対応設定。 |
--name-conv | 文字列リスト | NO | 名称変換ルールのリスト。 |
--preserve-bone-names | フラグ | NO | ボーン名を維持するかどうかの指定。 |
--no-subdivision | フラグ | NO | メッシュの自動細分化を無効にします。 |
--no-triangle | フラグ | NO | 三角面化を無効にします。 |
Unity Editor統合
UIToolkit
モダンなUI開発フレームワークを使用:
UXML(UIレイアウト)
XMLベースのレイアウト記述:
<ui:UXML>
<ui:VisualElement class="step-container">
<ui:Label text="Source Selection" class="step-title"/>
<ui:ObjectField name="source-field" type="UnityEngine.GameObject"/>
</ui:VisualElement>
</ui:UXML>USS(スタイル)
CSSライクなスタイリング:
.step-container {
padding: 10px;
margin: 5px;
}
.step-title {
font-size: 16px;
-unity-font-style: bold;
}C#バインディング
C#からUIを操作:
var sourceField = rootElement.Q<ObjectField>("source-field");
sourceField.RegisterValueChangedCallback(evt => {
// 値変更時の処理
});非同期処理
長時間実行される操作には非同期処理を使用:
public async Task<bool> ExecuteFittingAsync()
{
await Task.Run(() => {
// Blenderプロセスの実行
});
return true;
}進捗パーシング
Blenderからの出力をパースして進捗を表示:
public class FittingProgressParser
{
public void ParseLine(string line)
{
// "PROGRESS: 50%" のような出力をパース
// 進捗イベントを発火
}
}データ形式
FBXフォーマット
入出力に使用する3Dモデルフォーマット:
- 互換性: 多くの3Dツールでサポート
- 完全な情報: メッシュ、ボーン、アニメーション、マテリアルを含む
- Unity統合: Unityのネイティブサポート
JSON設定ファイル
フィッティング設定の保存:
{
"sourceAvatar": "Assets/Avatars/Source.fbx",
"targetAvatar": "Assets/Avatars/Target.fbx",
"blendShapes": [
{"name": "vrc.blink_left", "preserve": true},
{"name": "vrc.blink_right", "preserve": true}
]
}MochiFitterデータ互換性
MochiFitterのデータフォーマットに準拠:
- 設定ファイル: 同じJSON構造を使用
- 出力形式: 互換性のあるFBX出力
- ブレンドシェイプ命名: VRChat標準に準拠
最適化技術
並列処理
複数のタスクを並列実行:
var tasks = new List<Task<SetupResult>>
{
downloadBlenderTask,
downloadCoreTask,
downloadAddonTask
};
await Task.WhenAll(tasks);キャッシング
ダウンロードしたファイルをキャッシュ:
- ローカルキャッシュ:
BlenderTools/ディレクトリに保存 - バージョンチェック: ファイルが最新か確認
- 再利用: 既にダウンロード済みの場合はスキップ
メモリ管理
大きなメッシュデータの効率的な処理:
- ストリーミング: ファイルをストリーミングで読み込み
- 早期解放: 不要になったデータは即座に解放
- プロセス分離: Blenderを別プロセスで実行してUnityのメモリ使用を抑制
セキュリティ
サンドボックス化
Blenderプロセスを制限:
- 別プロセス: Unityとは独立したプロセスで実行
- 作業ディレクトリ制限: 特定のディレクトリ内でのみ動作
- タイムアウト: 長時間実行をタイムアウトで制限
入力検証
ユーザー入力の検証:
public bool ValidateSourceAvatar(GameObject avatar)
{
if (avatar == null) return false;
if (!HasValidMesh(avatar)) return false;
if (!HasValidArmature(avatar)) return false;
return true;
}国際化(i18n)
ローカリゼーションシステム
多言語サポート:
public static class I18n
{
public static string Get(string key)
{
// 現在の言語設定に基づいて文字列を取得
return translations[currentLanguage][key];
}
}サポート言語
- 日本語
- 英語
テスト技術
Unity Test Framework
ユニットテストとインテグレーションテスト:
[Test]
public void TestSourceSelection()
{
var presenter = new SourceSelectionStepPresenter(mockView, state);
presenter.OnSourceSelected(testAvatar);
Assert.AreEqual(testAvatar, state.Config.SourceAvatar);
}モックオブジェクト
テスト用のモック実装:
public class MockWizardView : IWizardView
{
public bool NextButtonWasCalled { get; private set; }
public void ShowNextButton()
{
NextButtonWasCalled = true;
}
}ビルドとデプロイ
TypeScriptビルドスクリプト
Node.jsとTypeScriptでビルドツールを作成:
// create-unitypackage.ts
import * as fs from 'fs';
import * as path from 'path';
async function createUnityPackage() {
// Unityパッケージを作成する処理
}VitePressドキュメント
ドキュメントサイトの生成:
npm run docs:build
# docs/.vitepress/dist/にビルド結果が生成されるまとめ
OpenFitterは以下の技術を組み合わせて実現されています:
- RBF変形: 滑らかで自然な衣装フィッティング
- Blender統合: 強力な3D処理エンジン
- Unity Editor拡張: ユーザーフレンドリーなインターフェース
- 非同期処理: レスポンシブなユーザー体験
- モジュラー設計: 保守しやすく拡張可能な構造
これらの技術により、高品質な自動衣装フィッティングを実現しています。
English
Core Technology
This document explains the key technologies and algorithms used in OpenFitter.
Overview
OpenFitter combines multiple technologies to achieve clothing fitting between 3D avatars. It consists of a frontend as a Unity Editor extension and a processing engine using Blender as a backend.
Fitting Algorithm
RBF (Radial Basis Function) Deformation
The core fitting algorithm uses RBF (Radial Basis Function) deformation.
What is RBF
RBF is a mathematical technique that generates smooth deformation from limited control points. It has the following characteristics:
- Local Influence: Each control point primarily affects its surrounding area
- Smooth Interpolation: Deformation between control points is natural and smooth
- Nonlinear Deformation: Can handle complex body shape differences
Use in Fitting Process
- Control Point Setup: Use bone positions of source and target as control points
- RBF Calculation: Calculate deformation from source to target
- Mesh Deformation: Apply RBF deformation to each vertex of clothing mesh
Bone Pose Transfer
Transfers bone pose between avatars.
Process
- Bone Mapping: Map bone structures between source and target
- Pose Extraction: Extract bone pose from source avatar
- Pose Application: Apply pose to target avatar
- Weight Transfer: Appropriately transfer skinning weights
Mesh Topology Preservation
Maintains basic mesh structure after fitting:
- Vertex Order: Preserves original vertex order
- Polygon Structure: Maintains polygon connectivity
- UV Coordinates: Preserves texture coordinates
- Materials: Maintains material assignments
Blender Integration
Why Use Blender as Backend
OpenFitter uses Blender as its 3D processing engine:
- Powerful 3D Processing: Leverages Blender's mature 3D processing capabilities
- Python Scripting: Enables flexible automation
- GPL-3 Code Compatibility: Can use open-fitter-core code directly
- Open Source: Free and redistributable
Portable Blender
Uses portable version of Blender to avoid affecting user's existing environment:
- Independent Installation: Doesn't interfere with system Blender
- Automatic Download: Automatically retrieved during initial setup
- Version Management: Uses specific version to ensure compatibility
Python Wrapper Scripts
Bridges between Unity (C#) and Blender (Python):
openfitter_wrapper.py
Main wrapper script:
# Receive parameters from command line arguments
# Call fitting function of open-fitter-core
# Output progress information to stdout
# Save results to filecheck_addon_status.py
Check add-on installation status:
# Check if Blender add-on is correctly installed
# Get version information
# Output results in JSON formatinstall_addon_dependencies.py
Install add-on dependencies:
# Install required Python packages using pip
# Install into Blender's built-in Python environment
# Report installation resultsCommand Line Execution
Launch Blender from Unity via command line:
blender.exe --background --python openfitter_wrapper.py -- [arguments]--background: Background mode without UI--python: Python script to execute--: Pass subsequent arguments to script
OpenFitterCore Parameters
The primary arguments accepted by the Blender backend (the core script via openfitter_wrapper.py) are as follows:
| Argument | Format | Required | Description |
|---|---|---|---|
--input | Path | YES | Absolute path to the input clothing FBX. |
--output | Path | YES | Absolute path to the output FBX. |
--base | Path | YES | Path to the base .blend file. |
--base-fbx | Path List | YES | Path to the base character FBX. Semicolon-separated if multiple. |
--config | Path List | YES | Path to the config JSON. Semicolon-separated if multiple. |
--init-pose | Path | YES | Path to the initial pose JSON. |
--hips-position | String | NO | Specifies the Hips bone position. |
--blend-shapes | String List | NO | List of blend shape names to apply (semicolon-separated). |
--blend-shape-values | Value List | NO | Application values for each blend shape (semicolon-separated). |
--blend-shape-mappings | String List | NO | Blend shape mapping definitions. |
--target-meshes | String List | NO | List of mesh names to be processed. |
--mesh-renderers | String List | NO | Mesh renderer correspondence settings. |
--name-conv | String List | NO | List of name conversion rules. |
--preserve-bone-names | Flag | NO | Specifies whether to preserve bone names. |
--no-subdivision | Flag | NO | Disables automatic mesh subdivision. |
--no-triangle | Flag | NO | Disables triangulation. |
Unity Editor Integration
UIToolkit
Uses modern UI development framework:
UXML (UI Layout)
XML-based layout description:
<ui:UXML>
<ui:VisualElement class="step-container">
<ui:Label text="Source Selection" class="step-title"/>
<ui:ObjectField name="source-field" type="UnityEngine.GameObject"/>
</ui:VisualElement>
</ui:UXML>USS (Styles)
CSS-like styling:
.step-container {
padding: 10px;
margin: 5px;
}
.step-title {
font-size: 16px;
-unity-font-style: bold;
}C# Binding
Manipulate UI from C#:
var sourceField = rootElement.Q<ObjectField>("source-field");
sourceField.RegisterValueChangedCallback(evt => {
// Handle value change
});Asynchronous Processing
Uses asynchronous processing for long-running operations:
public async Task<bool> ExecuteFittingAsync()
{
await Task.Run(() => {
// Execute Blender process
});
return true;
}Progress Parsing
Parse output from Blender to display progress:
public class FittingProgressParser
{
public void ParseLine(string line)
{
// Parse output like "PROGRESS: 50%"
// Fire progress event
}
}Data Formats
FBX Format
3D model format used for input/output:
- Compatibility: Supported by many 3D tools
- Complete Information: Includes mesh, bones, animations, materials
- Unity Integration: Native Unity support
JSON Configuration Files
Save fitting configuration:
{
"sourceAvatar": "Assets/Avatars/Source.fbx",
"targetAvatar": "Assets/Avatars/Target.fbx",
"blendShapes": [
{"name": "vrc.blink_left", "preserve": true},
{"name": "vrc.blink_right", "preserve": true}
]
}MochiFitter Data Compatibility
Complies with MochiFitter data format:
- Configuration Files: Uses same JSON structure
- Output Format: Compatible FBX output
- Blendshape Naming: Complies with VRChat standards
Optimization Techniques
Parallel Processing
Execute multiple tasks in parallel:
var tasks = new List<Task<SetupResult>>
{
downloadBlenderTask,
downloadCoreTask,
downloadAddonTask
};
await Task.WhenAll(tasks);Caching
Cache downloaded files:
- Local Cache: Saved in
BlenderTools/directory - Version Check: Verify if files are up-to-date
- Reuse: Skip if already downloaded
Memory Management
Efficient processing of large mesh data:
- Streaming: Stream file loading
- Early Release: Immediately release unnecessary data
- Process Separation: Run Blender in separate process to reduce Unity memory usage
Security
Sandboxing
Restrict Blender process:
- Separate Process: Runs independently from Unity
- Working Directory Restriction: Operates only within specific directory
- Timeout: Limit long-running execution with timeout
Input Validation
Validate user input:
public bool ValidateSourceAvatar(GameObject avatar)
{
if (avatar == null) return false;
if (!HasValidMesh(avatar)) return false;
if (!HasValidArmature(avatar)) return false;
return true;
}Internationalization (i18n)
Localization System
Multi-language support:
public static class I18n
{
public static string Get(string key)
{
// Get string based on current language setting
return translations[currentLanguage][key];
}
}Supported Languages
- Japanese
- English
Testing Technologies
Unity Test Framework
Unit tests and integration tests:
[Test]
public void TestSourceSelection()
{
var presenter = new SourceSelectionStepPresenter(mockView, state);
presenter.OnSourceSelected(testAvatar);
Assert.AreEqual(testAvatar, state.Config.SourceAvatar);
}Mock Objects
Mock implementations for testing:
public class MockWizardView : IWizardView
{
public bool NextButtonWasCalled { get; private set; }
public void ShowNextButton()
{
NextButtonWasCalled = true;
}
}Build and Deploy
TypeScript Build Scripts
Create build tools with Node.js and TypeScript:
// create-unitypackage.ts
import * as fs from 'fs';
import * as path from 'path';
async function createUnityPackage() {
// Process to create Unity package
}VitePress Documentation
Generate documentation site:
npm run docs:build
# Build results generated in docs/.vitepress/dist/Summary
OpenFitter is realized by combining the following technologies:
- RBF Deformation: Smooth and natural clothing fitting
- Blender Integration: Powerful 3D processing engine
- Unity Editor Extension: User-friendly interface
- Asynchronous Processing: Responsive user experience
- Modular Design: Maintainable and extensible structure
These technologies enable high-quality automatic clothing fitting.