Animation Retargeting
Drive a rigged 3D character with BVH motion data and output an animated GLB. Bone proportion differences are handled automatically. input_motion accepts the asset_path returned directly from the Motion Retrieval API.
Typical Application Scenarios
- Game character animation: Retarget motion-capture BVH onto custom characters
- Chain with Motion Retrieval: search → get asset_path → pass to this API for a fully automated pipeline
Recommended Workflow
- Prepare a rigged model → GLB with embedded skeleton/skin (
input_model) - Specify the motion → use the
asset_pathfrom Motion Retrieval, or upload a BVH file (input_motion) - Set frame rate → use
fps: 30orfps: -1to keep the source rate - Get the animated GLB → result is a GLB with embedded animation tracks, ready for any 3D engine
API Reference used on this page POST /motions/animations
Chaining with Motion Retrieval
Pass the asset_path from Motion Retrieval results (e.g. motions/h3d/bvh/00035389_000.bvh) directly as input_motion — no download needed.
Basic Examples
curl -X POST 'https://api.v2fun.ai/api/v1/motions/animations' \
-H 'Authorization: Bearer $V2FUN_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"input_model": "models/example_rigged.glb",
"input_motion": "motions/example.bvh"
}'const response = await fetch('https://api.v2fun.ai/api/v1/motions/animations', {
method: 'POST',
headers: {
'Authorization': 'Bearer $V2FUN_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"input_model": "models/example_rigged.glb",
"input_motion": "motions/example.bvh"
}),
});
const data = await response.json();import requests
resp = requests.post(
'https://api.v2fun.ai/api/v1/motions/animations',
headers={
'Authorization': 'Bearer $V2FUN_API_KEY',
'Content-Type': 'application/json',
},
json={
"input_model": "models/example_rigged.glb",
"input_motion": "motions/example.bvh"
},
)
print(resp.json())import java.net.URI;
import java.net.http.*;
HttpClient client = HttpClient.newHttpClient();
String body = "{\"input_model\":\"models/example_rigged.glb\",\"input_motion\":\"motions/example.bvh\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.v2fun.ai/api/v1/motions/animations"))
.header("Authorization", "Bearer $V2FUN_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Core Use Cases
Retarget Motion to Character
Maps BVH motion-capture data onto a rigged character, producing a GLB with complete animation tracks. The input is the static rigged model; the output is the animated version (playable in the viewer).
curl -X POST 'https://api.v2fun.ai/api/v1/motions/animations' \
-H 'Authorization: Bearer $V2FUN_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"input_model": "https://asset.v2fun.ai/upload/animation-input-mannequin.glb",
"input_motion": "motions/h3d/bvh/00041332_000.bvh",
"fps": 30
}'const response = await fetch('https://api.v2fun.ai/api/v1/motions/animations', {
method: 'POST',
headers: {
'Authorization': 'Bearer $V2FUN_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"input_model": "https://asset.v2fun.ai/upload/animation-input-mannequin.glb",
"input_motion": "motions/h3d/bvh/00041332_000.bvh",
"fps": 30
}),
});
const data = await response.json();import requests
resp = requests.post(
'https://api.v2fun.ai/api/v1/motions/animations',
headers={
'Authorization': 'Bearer $V2FUN_API_KEY',
'Content-Type': 'application/json',
},
json={
"input_model": "https://asset.v2fun.ai/upload/animation-input-mannequin.glb",
"input_motion": "motions/h3d/bvh/00041332_000.bvh",
"fps": 30
},
)
print(resp.json())import java.net.URI;
import java.net.http.*;
HttpClient client = HttpClient.newHttpClient();
String body = "{\"input_model\":\"https://asset.v2fun.ai/upload/animation-input-mannequin.glb\",\"input_motion\":\"motions/h3d/bvh/00041332_000.bvh\",\"fps\":30}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.v2fun.ai/api/v1/motions/animations"))
.header("Authorization", "Bearer $V2FUN_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Example response:
{
"status": "COMPLETED",
"result": "models/867a17e3-ec0e-4977-8b14-6a44cc69c9cb.glb",
"metadata": [
{
"t_pose_model": "models/be3d686b-4779-4e90-b2e1-ef4fc3f4800a.glb",
"downloads": [
{
"asset_path": "models/867a17e3-ec0e-4977-8b14-6a44cc69c9cb.glb",
"download_url": "https://..."
}
]
}
]
}The returned GLB contains embedded animation tracks and can be imported directly into Unity, Unreal, Three.js, and other engines.
