arkavo-org / arkavo-org/VRMMetalKit

Enhance VRM 0.x migration and fallback support

Open
#69 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
6
Forks
2
Avg merge
18h 51m
Merged PRs (30d)
26

Description

## Issue Description

VRMMetalKit has basic VRM 0.x fallback support but lacks the comprehensive migration tools available in UniVRM. This limits compatibility with older VRM content and migration workflows.

## Current State

✅ **Implemented:**
- Basic VRM 0.x format detection
- Fallback parsing for VRM 0.x files
- Preset name mapping (VRM 0.x → VRM 1.0)

⚠️ **Limited:**
- Material migration (MToon 0.x → MToon 1.0)
- BlendShape → Expression migration
- SpringBone parameter migration
- Metadata migration

## UniVRM Migration Features

UniVRM provides comprehensive migration:
```csharp
// UniVRM/Packages/VRM10/Runtime/Migration/
- MigrationVrm.cs // Main migration coordinator
- MigrationVrmMaterial.cs // Material conversion
- MigrationVrmExpression.cs // BlendShape → Expression
- MigrationVrmSpringBone.cs // SpringBone updates
- MigrationVrmMeta.cs // Metadata migration
```

## Key Migration Areas

### 1. Material Migration

**VRM 0.x MToon → VRM 1.0 MToon:**

```swift
// Current: Basic fallback
private func mapVRM0PresetToVRM1(_ presetName: String) -> VRMExpressionPreset? {
// Simple name mapping
}

// Needed: Comprehensive material migration
struct MToonMigrator {
func migrate(vrm0Material: VRM0Material) -> MToonMaterial {
// Convert property names
// Adjust value ranges
// Handle deprecated properties
// Map texture slots
}
}
```

**Property Mappings:**
- `_Color` → `baseColorFactor`
- `_ShadeColor` → `shadeColorFactor`
- `_BumpScale` → `normalTextureScale`
- `_ReceiveShadowRate` → `shadingShiftFactor`
- `_ShadingGradeRate` → `shadingToonyFactor`
- And many more...

### 2. Expression Migration

**BlendShapePreset → ExpressionPreset:**

```swift
// VRM 0.x BlendShape names
enum VRM0BlendShapePreset {
case unknown, neutral, a, i, u, e, o
case blink, joy, angry, sorrow, fun
case lookup, lookdown, lookleft, lookright
case blink_l, blink_r
}

// Migration to VRM 1.0
struct ExpressionMigrator {
func migrate(blendShape: VRM0BlendShape) -> VRMExpression {
// Map preset names
// Convert morph target binds
// Migrate material color binds
// Handle isBinary flag
}
}
```

**Preset Mappings:**
- `joy` → `happy`
- `sorrow` → `sad`
- `fun` → `relaxed`
- `a`, `i`, `u`, `e`, `o` → `aa`, `ih`, `ou`, `ee`, `oh`

### 3. SpringBone Migration

**VRM 0.x → VRM 1.0 SpringBone:**

```swift
struct SpringBoneMigrator {
func migrate(vrm0SpringBone: VRM0SpringBone) -> VRMSpringBone {
// Convert bone groups to joints
// Migrate collider groups
// Update parameter names:
// - stiffnessForce (same)
// - gravityPower (same)
// - gravityDir (same)
// - dragForce (same)
// - hitRadius → jointRadius
}
}
```

### 4. Metadata Migration

**VRM 0.x Meta → VRM 1.0 Meta:**

```swift
struct MetadataMigrator {
func migrate(vrm0Meta: VRM0Meta) -> VRMMeta {
// License migration:
// - allowedUserName → avatarPermission
// - violentUssageName → violentUsage
// - sexualUssageName → sexualUsage
// - commercialUssageName → commercialUsage

// Update license URLs
// Migrate thumbnail
// Convert author info
}
}
```

## Implementation Plan

### Phase 1: Core Migration Framework

```swift
// Sources/VRMMetalKit/Migration/
public protocol VRMMigrator {
associatedtype Input
associatedtype Output

func migrate(_ input: Input) throws -> Output
}

public struct VRM0to1Migrator {
let materialMigrator: MToonMigrator
let expressionMigrator: ExpressionMigrator
let springBoneMigrator: SpringBoneMigrator
let metadataMigrator: MetadataMigrator

public func migrate(_ vrm0: VRM0Model) throws -> VRMModel {
// Coordinate all migrations
}
}
```

### Phase 2: Material Migration

- [ ] Create MToon property mapping table
- [ ] Implement texture slot migration
- [ ] Handle deprecated properties
- [ ] Add validation for migrated materials

### Phase 3: Expression Migration

- [ ] Create BlendShape → Expression mapping
- [ ] Migrate morph target binds
- [ ] Migrate material color binds
- [ ] Handle custom expressions

### Phase 4: SpringBone Migration

- [ ] Convert bone groups to joints
- [ ] Migrate collider definitions
- [ ] Update parameter names
- [ ] Preserve physics behavior

### Phase 5: Metadata Migration

- [ ] License field migration
- [ ] Author info migration
- [ ] Thumbnail migration
- [ ] URL updates

### Phase 6: Testing & Validation

- [ ] Test with real VRM 0.x models
- [ ] Compare with UniVRM migration results
- [ ] Validate migrated models
- [ ] Document migration differences

## Suggested File Structure

```
Sources/VRMMetalKit/Migration/
├── VRMMigrator.swift # Protocol and coordinator
├── VRM0Types.swift # VRM 0.x data structures
├── MToonMigrator.swift # Material migration
├── ExpressionMigrator.swift # BlendShape → Expression
├── SpringBoneMigrator.swift # SpringBone migration
├── MetadataMigrator.swift # Metadata migration
└── MigrationValidation.swift # Post-migration checks
```

## Testing Strategy

```swift
func testMToonMigration() throws {
let vrm0Material = loadVRM0Material()
let migrator = MToonMigrator()
let vrm1Material = try migrator.migrate(vrm0Material)

XCTAssertEqual(vrm1Material.baseColorFactor, expectedColor)
XCTAssertEqual(vrm1Material.shadingToonyFactor, expectedToony)
}

func testFullModelMigration() async throws {
let vrm0URL = Bundle.module.url(forResource: test_vrm0, withExtension: vrm)!
let model = try await VRMModel.load(from: vrm0URL, device: device)

// Verify migration occurred
XCTAssertEqual(model.specVersion, .v1_0)
XCTAssertNotNil(model.expressions[.happy])
}
```

## Acceptance Criteria

- [ ] Successfully migrate VRM 0.x models to VRM 1.0
- [ ] Preserve visual appearance after migration
- [ ] Maintain physics behavior
- [ ] Pass VRM 1.0 validation
- [ ] Document migration process
- [ ] Provide migration examples
- [ ] Unit tests for each migrator

## Priority

**Medium** - Important for backward compatibility but not blocking core VRM 1.0 support

## Estimated Effort

- Phase 1 (Framework): 1 week
- Phase 2 (Materials): 2 weeks
- Phase 3 (Expressions): 1 week
- Phase 4 (SpringBone): 1 week
- Phase 5 (Metadata): 1 week
- Phase 6 (Testing): 1 week
- **Total:** 7 weeks

## Related Issues

- Related: #66 (spec compliance)
- Related: #68 (export functionality)
- Blocks: Full VRM 0.x compatibility

## References

- VRM 0.x Specification: https://github.com/vrm-c/vrm-specification/tree/master/specification/0.0
- VRM 1.0 Specification: https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_vrm-1.0
- UniVRM Migration: https://github.com/vrm-c/UniVRM/tree/master/Assets/VRM10/Runtime/Migration
- Migration Guide: https://vrm.dev/en/vrm/vrm_migration/

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the existing VRM 0.x detection, fallback parsing, and preset mapping, then compare the proposed Sources/VRMMetalKit/Migration files with UniVRM's Runtime/Migration references. Run the proposed testMToonMigration and testFullModelMigration cases using real VRM 0.x models. Done means migration, validation, documentation, examples, and tests cover materials, expressions, SpringBone, and metadata.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.