mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Add additional skeletal animation and skinning test files
Added comprehensive test models and scripts for skeletal animation features: Skeletal Animation Test Models (models/): - skelanim-empty.usda: Edge case with no animation data - skelanim-mixed.usda: Mixed static and time-sampled (incomplete skeleton binding) - skelanim-rotation-only.usda: Only rotation channels animated - skelanim-single-joint.usda: Single joint animation - skelanim-static.usda: Static values only (incomplete skeleton binding) - skelanim-timesampled.usda: Time-sampled values (incomplete skeleton binding) Synthetic Skin Test Models (models/): - synthetic-skin-8influences.usda: 8 influences per vertex test - synthetic-skin-16influences.usda: 16 influences per vertex test - synthetic-skin-32influences.usda: 32 influences per vertex test Test Scripts (web/js/): - test-anim-debug.js: Animation debugging utility - test-16influences.js: Test 16 influences per vertex - test-all-bone-reduction.js: Bone reduction testing - test-boundaries.js: Boundary condition tests - test-digit-limits.js: Digit parsing limits - test-malicious.js: Malicious input handling - test-number-parsing.js: Number parsing validation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
25
models/skelanim-empty.usda
Normal file
25
models/skelanim-empty.usda
Normal file
@@ -0,0 +1,25 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "Root"
|
||||
upAxis = "Z"
|
||||
)
|
||||
|
||||
def Xform "Root"
|
||||
{
|
||||
def Skeleton "Skel"
|
||||
{
|
||||
uniform token[] joints = ["joint0"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
|
||||
]
|
||||
|
||||
def SkelAnimation "EmptyAnim"
|
||||
{
|
||||
uniform token[] joints = ["joint0"]
|
||||
# No animation data - edge case test
|
||||
}
|
||||
}
|
||||
}
|
||||
45
models/skelanim-mixed.usda
Normal file
45
models/skelanim-mixed.usda
Normal file
@@ -0,0 +1,45 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "Root"
|
||||
upAxis = "Z"
|
||||
)
|
||||
|
||||
def Xform "Root"
|
||||
{
|
||||
def Skeleton "Skel"
|
||||
{
|
||||
uniform token[] joints = ["root", "root/spine", "root/leftArm", "root/rightArm"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (-0.5, 1.5, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0.5, 1.5, 0, 1) )
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (-0.5, 1.5, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0.5, 1.5, 0, 1) )
|
||||
]
|
||||
|
||||
def SkelAnimation "MixedAnim"
|
||||
{
|
||||
uniform token[] joints = ["root", "root/spine", "root/leftArm", "root/rightArm"]
|
||||
|
||||
# Static translations (bind pose)
|
||||
float3[] translations = [(0, 0, 0), (0, 1, 0), (-0.5, 1.5, 0), (0.5, 1.5, 0)]
|
||||
|
||||
# Time-sampled rotations (animated)
|
||||
quatf[] rotations.timeSamples = {
|
||||
0: [(1, 0, 0, 0), (1, 0, 0, 0), (1, 0, 0, 0), (1, 0, 0, 0)],
|
||||
0.5: [(0.9962, 0, 0.0872, 0), (1, 0, 0, 0), (0.9659, 0, 0, 0.2588), (0.9659, 0, 0, -0.2588)],
|
||||
1: [(0.9848, 0, 0.1736, 0), (1, 0, 0, 0), (0.8660, 0, 0, 0.5), (0.8660, 0, 0, -0.5)],
|
||||
1.5: [(0.9962, 0, 0.0872, 0), (1, 0, 0, 0), (0.9659, 0, 0, 0.2588), (0.9659, 0, 0, -0.2588)],
|
||||
2: [(1, 0, 0, 0), (1, 0, 0, 0), (1, 0, 0, 0), (1, 0, 0, 0)]
|
||||
}
|
||||
|
||||
# Static scales (uniform)
|
||||
half3[] scales = [(1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1)]
|
||||
}
|
||||
}
|
||||
}
|
||||
35
models/skelanim-rotation-only.usda
Normal file
35
models/skelanim-rotation-only.usda
Normal file
@@ -0,0 +1,35 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "Root"
|
||||
upAxis = "Z"
|
||||
)
|
||||
|
||||
def Xform "Root"
|
||||
{
|
||||
def Skeleton "Skel"
|
||||
{
|
||||
uniform token[] joints = ["joint0", "joint0/joint1"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) )
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) )
|
||||
]
|
||||
|
||||
def SkelAnimation "RotationOnlyAnim"
|
||||
{
|
||||
uniform token[] joints = ["joint0", "joint0/joint1"]
|
||||
|
||||
# Only rotations are animated, no translations or scales
|
||||
quatf[] rotations.timeSamples = {
|
||||
0: [(1, 0, 0, 0), (1, 0, 0, 0)],
|
||||
0.5: [(0.9239, 0, 0.3827, 0), (0.9659, 0.2588, 0, 0)],
|
||||
1: [(0.7071, 0, 0.7071, 0), (0.8660, 0.5, 0, 0)],
|
||||
1.5: [(0.9239, 0, 0.3827, 0), (0.9659, 0.2588, 0, 0)],
|
||||
2: [(1, 0, 0, 0), (1, 0, 0, 0)]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
models/skelanim-single-joint.usda
Normal file
37
models/skelanim-single-joint.usda
Normal file
@@ -0,0 +1,37 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "Root"
|
||||
upAxis = "Y"
|
||||
)
|
||||
|
||||
def Xform "Root"
|
||||
{
|
||||
def Skeleton "Skel"
|
||||
{
|
||||
uniform token[] joints = ["bone"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
|
||||
]
|
||||
|
||||
def SkelAnimation "SingleJointAnim"
|
||||
{
|
||||
uniform token[] joints = ["bone"]
|
||||
|
||||
# Single joint with time-sampled rotation
|
||||
float3[] translations = [(0, 0, 0)]
|
||||
|
||||
quatf[] rotations.timeSamples = {
|
||||
0: [(1, 0, 0, 0)],
|
||||
0.25: [(0.9239, 0, 0.3827, 0)],
|
||||
0.5: [(0.7071, 0, 0.7071, 0)],
|
||||
0.75: [(0.9239, 0, 0.3827, 0)],
|
||||
1: [(1, 0, 0, 0)]
|
||||
}
|
||||
|
||||
half3[] scales = [(1, 1, 1)]
|
||||
}
|
||||
}
|
||||
}
|
||||
33
models/skelanim-static.usda
Normal file
33
models/skelanim-static.usda
Normal file
@@ -0,0 +1,33 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "Root"
|
||||
upAxis = "Z"
|
||||
)
|
||||
|
||||
def Xform "Root"
|
||||
{
|
||||
def Skeleton "Skel"
|
||||
{
|
||||
uniform token[] joints = ["joint0", "joint0/joint1", "joint0/joint1/joint2"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) )
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 0, 1) )
|
||||
]
|
||||
|
||||
def SkelAnimation "StaticAnim"
|
||||
{
|
||||
uniform token[] joints = ["joint0", "joint0/joint1", "joint0/joint1/joint2"]
|
||||
|
||||
# All static (non-time-sampled) values
|
||||
float3[] translations = [(0.5, 0, 0), (0, 1.5, 0), (0, 0.75, 0)]
|
||||
quatf[] rotations = [(1, 0, 0, 0), (0.7071, 0, 0.7071, 0), (0.9239, 0.3827, 0, 0)]
|
||||
half3[] scales = [(1, 1, 1), (1.2, 1.2, 1.2), (0.8, 0.8, 0.8)]
|
||||
}
|
||||
}
|
||||
}
|
||||
53
models/skelanim-timesampled.usda
Normal file
53
models/skelanim-timesampled.usda
Normal file
@@ -0,0 +1,53 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "Root"
|
||||
upAxis = "Z"
|
||||
)
|
||||
|
||||
def Xform "Root"
|
||||
{
|
||||
def Skeleton "Skel"
|
||||
{
|
||||
uniform token[] joints = ["joint0", "joint0/joint1"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2, 0, 1) )
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ),
|
||||
( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2, 0, 1) )
|
||||
]
|
||||
|
||||
def SkelAnimation "Anim"
|
||||
{
|
||||
uniform token[] joints = ["joint0", "joint0/joint1"]
|
||||
|
||||
# Time-sampled translations
|
||||
float3[] translations.timeSamples = {
|
||||
0: [(0, 0, 0), (0, 2, 0)],
|
||||
1: [(1, 0, 0), (0, 2.5, 0)],
|
||||
2: [(2, 0, 0), (0, 3, 0)],
|
||||
3: [(1, 0, 0), (0, 2.5, 0)],
|
||||
4: [(0, 0, 0), (0, 2, 0)]
|
||||
}
|
||||
|
||||
# Time-sampled rotations
|
||||
quatf[] rotations.timeSamples = {
|
||||
0: [(1, 0, 0, 0), (1, 0, 0, 0)],
|
||||
1: [(0.9239, 0, 0.3827, 0), (0.9659, 0.2588, 0, 0)],
|
||||
2: [(0.7071, 0, 0.7071, 0), (0.8660, 0.5, 0, 0)],
|
||||
3: [(0.9239, 0, 0.3827, 0), (0.9659, 0.2588, 0, 0)],
|
||||
4: [(1, 0, 0, 0), (1, 0, 0, 0)]
|
||||
}
|
||||
|
||||
# Time-sampled scales
|
||||
half3[] scales.timeSamples = {
|
||||
0: [(1, 1, 1), (1, 1, 1)],
|
||||
1: [(1.2, 1, 1), (1, 1.1, 1)],
|
||||
2: [(1.5, 1, 1), (1, 1.2, 1)],
|
||||
3: [(1.2, 1, 1), (1, 1.1, 1)],
|
||||
4: [(1, 1, 1), (1, 1, 1)]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
models/synthetic-skin-16influences.usda
Normal file
114
models/synthetic-skin-16influences.usda
Normal file
@@ -0,0 +1,114 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "root"
|
||||
upAxis = "Z"
|
||||
metersPerUnit = 1
|
||||
)
|
||||
|
||||
def SkelRoot "root"
|
||||
{
|
||||
def Skeleton "Skeleton"
|
||||
{
|
||||
uniform token[] joints = [
|
||||
"Root", "Root/joint1", "Root/joint2", "Root/joint3", "Root/joint4", "Root/joint5", "Root/joint6", "Root/joint7",
|
||||
"Root/joint8", "Root/joint9", "Root/joint10", "Root/joint11", "Root/joint12", "Root/joint13", "Root/joint14", "Root/joint15"
|
||||
]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.5, 0, 1))
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.5, 0, 1))
|
||||
]
|
||||
}
|
||||
|
||||
def Mesh "Mesh" (
|
||||
prepend apiSchemas = ["SkelBindingAPI"]
|
||||
)
|
||||
{
|
||||
uniform bool doubleSided = 0
|
||||
int[] faceVertexCounts = [3, 3, 3, 3, 3, 3]
|
||||
int[] faceVertexIndices = [0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 1]
|
||||
rel skel:skeleton = </root/Skeleton>
|
||||
|
||||
point3f[] points = [
|
||||
(0, 0, 0),
|
||||
(1, 0, 0),
|
||||
(1, 1, 0),
|
||||
(0, 1, 0),
|
||||
(-1, 1, 0),
|
||||
(-1, 0, 0),
|
||||
(-1, -1, 0)
|
||||
]
|
||||
|
||||
int[] primvars:skel:jointIndices = [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
] (
|
||||
elementSize = 16
|
||||
interpolation = "vertex"
|
||||
)
|
||||
|
||||
float[] primvars:skel:jointWeights = [
|
||||
0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625,
|
||||
0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625,
|
||||
0.25, 0.20, 0.15, 0.10, 0.08, 0.06, 0.05, 0.04, 0.03, 0.02, 0.01, 0.005, 0.003, 0.002, 0.001, 0.001,
|
||||
0.20, 0.18, 0.16, 0.14, 0.10, 0.08, 0.06, 0.04, 0.02, 0.01, 0.005, 0.003, 0.002, 0.001, 0.001, 0.001,
|
||||
0.01, 0.02, 0.04, 0.06, 0.08, 0.12, 0.16, 0.20, 0.16, 0.08, 0.04, 0.02, 0.005, 0.003, 0.001, 0.001,
|
||||
0.001, 0.002, 0.003, 0.005, 0.01, 0.02, 0.04, 0.06, 0.08, 0.12, 0.16, 0.20, 0.14, 0.10, 0.05, 0.02,
|
||||
0.001, 0.001, 0.002, 0.003, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 0.08, 0.10, 0.15, 0.20, 0.18, 0.15,
|
||||
0.40, 0.25, 0.15, 0.10, 0.05, 0.03, 0.02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
||||
] (
|
||||
elementSize = 16
|
||||
interpolation = "vertex"
|
||||
)
|
||||
|
||||
matrix4d primvars:skel:geomBindTransform = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
|
||||
|
||||
normal3f[] normals = [
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1)
|
||||
] (
|
||||
interpolation = "vertex"
|
||||
)
|
||||
}
|
||||
}
|
||||
151
models/synthetic-skin-32influences.usda
Normal file
151
models/synthetic-skin-32influences.usda
Normal file
@@ -0,0 +1,151 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "root"
|
||||
upAxis = "Z"
|
||||
metersPerUnit = 1
|
||||
)
|
||||
|
||||
def SkelRoot "root"
|
||||
{
|
||||
def Skeleton "Skeleton"
|
||||
{
|
||||
uniform token[] joints = [
|
||||
"Root", "Root/joint1", "Root/joint2", "Root/joint3", "Root/joint4", "Root/joint5", "Root/joint6", "Root/joint7",
|
||||
"Root/joint8", "Root/joint9", "Root/joint10", "Root/joint11", "Root/joint12", "Root/joint13", "Root/joint14", "Root/joint15",
|
||||
"Root/joint16", "Root/joint17", "Root/joint18", "Root/joint19", "Root/joint20", "Root/joint21", "Root/joint22", "Root/joint23",
|
||||
"Root/joint24", "Root/joint25", "Root/joint26", "Root/joint27", "Root/joint28", "Root/joint29", "Root/joint30", "Root/joint31"
|
||||
]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.75, 0, 1))
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 4.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 5.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 6.75, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.00, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.25, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.50, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 7.75, 0, 1))
|
||||
]
|
||||
}
|
||||
|
||||
def Mesh "Mesh" (
|
||||
prepend apiSchemas = ["SkelBindingAPI"]
|
||||
)
|
||||
{
|
||||
uniform bool doubleSided = 0
|
||||
int[] faceVertexCounts = [4, 4]
|
||||
int[] faceVertexIndices = [0, 1, 2, 3, 0, 3, 4, 5]
|
||||
rel skel:skeleton = </root/Skeleton>
|
||||
|
||||
point3f[] points = [
|
||||
(0, 0, 0),
|
||||
(2, 0, 0),
|
||||
(2, 2, 0),
|
||||
(0, 2, 0),
|
||||
(-2, 2, 0),
|
||||
(-2, 0, 0)
|
||||
]
|
||||
|
||||
int[] primvars:skel:jointIndices = [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
] (
|
||||
elementSize = 32
|
||||
interpolation = "vertex"
|
||||
)
|
||||
|
||||
float[] primvars:skel:jointWeights = [
|
||||
0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125,
|
||||
0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125,
|
||||
0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125,
|
||||
0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125,
|
||||
0.15, 0.12, 0.10, 0.08, 0.07, 0.06, 0.05, 0.045, 0.04, 0.035, 0.03, 0.025, 0.02, 0.018, 0.016, 0.014,
|
||||
0.012, 0.010, 0.009, 0.008, 0.007, 0.006, 0.005, 0.004, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
|
||||
0.001, 0.002, 0.003, 0.005, 0.008, 0.012, 0.018, 0.025, 0.035, 0.045, 0.055, 0.065, 0.075, 0.080, 0.085, 0.088,
|
||||
0.085, 0.080, 0.070, 0.055, 0.040, 0.028, 0.018, 0.012, 0.008, 0.005, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001,
|
||||
0.10, 0.08, 0.06, 0.04, 0.02, 0.01, 0.005, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.003,
|
||||
0.005, 0.01, 0.02, 0.04, 0.06, 0.08, 0.10, 0.08, 0.06, 0.04, 0.02, 0.01, 0.005, 0.003, 0.002, 0.001,
|
||||
0.001, 0.001, 0.001, 0.002, 0.002, 0.003, 0.004, 0.005, 0.006, 0.008, 0.010, 0.012, 0.015, 0.018, 0.022, 0.026,
|
||||
0.030, 0.035, 0.040, 0.045, 0.050, 0.055, 0.060, 0.070, 0.080, 0.090, 0.095, 0.090, 0.070, 0.050, 0.030, 0.020,
|
||||
0.30, 0.25, 0.20, 0.12, 0.08, 0.03, 0.01, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
||||
] (
|
||||
elementSize = 32
|
||||
interpolation = "vertex"
|
||||
)
|
||||
|
||||
matrix4d primvars:skel:geomBindTransform = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
|
||||
|
||||
normal3f[] normals = [
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1)
|
||||
] (
|
||||
interpolation = "vertex"
|
||||
)
|
||||
}
|
||||
}
|
||||
86
models/synthetic-skin-8influences.usda
Normal file
86
models/synthetic-skin-8influences.usda
Normal file
@@ -0,0 +1,86 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "root"
|
||||
upAxis = "Z"
|
||||
metersPerUnit = 1
|
||||
)
|
||||
|
||||
def SkelRoot "root"
|
||||
{
|
||||
def Skeleton "Skeleton"
|
||||
{
|
||||
uniform token[] joints = ["Root", "Root/joint1", "Root/joint2", "Root/joint3", "Root/joint4", "Root/joint5", "Root/joint6", "Root/joint7"]
|
||||
uniform matrix4d[] bindTransforms = [
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.5, 0, 1))
|
||||
]
|
||||
uniform matrix4d[] restTransforms = [
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 1.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 2.5, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.0, 0, 1)),
|
||||
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 3.5, 0, 1))
|
||||
]
|
||||
}
|
||||
|
||||
def Mesh "Mesh" (
|
||||
prepend apiSchemas = ["SkelBindingAPI"]
|
||||
)
|
||||
{
|
||||
uniform bool doubleSided = 0
|
||||
int[] faceVertexCounts = [3, 3, 3, 3]
|
||||
int[] faceVertexIndices = [0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1]
|
||||
rel skel:skeleton = </root/Skeleton>
|
||||
|
||||
point3f[] points = [
|
||||
(0, 0, 0),
|
||||
(1, 0, 0),
|
||||
(1, 1, 0),
|
||||
(0, 1, 0),
|
||||
(-1, 0, 0)
|
||||
]
|
||||
|
||||
int[] primvars:skel:jointIndices = [
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 1, 2, 3, 4, 5, 6, 7
|
||||
] (
|
||||
elementSize = 8
|
||||
interpolation = "vertex"
|
||||
)
|
||||
|
||||
float[] primvars:skel:jointWeights = [
|
||||
0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125,
|
||||
0.30, 0.25, 0.20, 0.15, 0.05, 0.03, 0.01, 0.01,
|
||||
0.05, 0.10, 0.20, 0.30, 0.20, 0.10, 0.04, 0.01,
|
||||
0.01, 0.01, 0.03, 0.05, 0.15, 0.20, 0.25, 0.30,
|
||||
0.40, 0.30, 0.15, 0.10, 0.05, 0.0, 0.0, 0.0
|
||||
] (
|
||||
elementSize = 8
|
||||
interpolation = "vertex"
|
||||
)
|
||||
|
||||
matrix4d primvars:skel:geomBindTransform = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
|
||||
|
||||
normal3f[] normals = [
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1),
|
||||
(0, 0, 1)
|
||||
] (
|
||||
interpolation = "vertex"
|
||||
)
|
||||
}
|
||||
}
|
||||
64
web/js/test-16influences.js
Normal file
64
web/js/test-16influences.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
async function main() {
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init();
|
||||
|
||||
const filePath = '../../models/synthetic-skin-16influences.usda';
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(filePath);
|
||||
|
||||
console.log(`Loading ${filePath} (${data.length} bytes)`);
|
||||
|
||||
// Enable bone reduction in loader
|
||||
loader.setEnableBoneReduction(true);
|
||||
loader.setTargetBoneCount(4);
|
||||
|
||||
// Load USD with bone reduction config
|
||||
await new Promise((resolve, reject) => {
|
||||
loader.parse(
|
||||
data,
|
||||
'synthetic-skin-16influences.usda',
|
||||
(usd) => {
|
||||
console.log('\n=== USD loaded successfully ===');
|
||||
|
||||
// Get mesh info
|
||||
const renderScene = usd.getRenderScene();
|
||||
console.log('\nScene has', renderScene.meshes.length, 'meshes');
|
||||
resolve(usd);
|
||||
},
|
||||
(error) => {
|
||||
console.error('Failed to load USD:', error);
|
||||
reject(error);
|
||||
},
|
||||
{
|
||||
maxMemoryLimitMB: 2048
|
||||
}
|
||||
);
|
||||
}).then((usd) => {
|
||||
const renderScene = usd.getRenderScene();
|
||||
const meshes = renderScene.meshes;
|
||||
console.log('\nMeshes found:', meshes.length);
|
||||
|
||||
for (const mesh of meshes) {
|
||||
console.log('\nMesh path:', mesh.abs_path);
|
||||
if (mesh.joint_and_weights) {
|
||||
console.log(' Joint and weights elementSize:', mesh.joint_and_weights.elementSize);
|
||||
console.log(' Weights per vertex:', mesh.joint_and_weights.elementSize);
|
||||
console.log(' Total joint indices:', mesh.joint_and_weights.jointIndices?.length);
|
||||
console.log(' Total joint weights:', mesh.joint_and_weights.jointWeights?.length);
|
||||
|
||||
const numVertices = mesh.joint_and_weights.jointIndices.length / mesh.joint_and_weights.elementSize;
|
||||
console.log(' Number of vertices:', numVertices);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
96
web/js/test-all-bone-reduction.js
Normal file
96
web/js/test-all-bone-reduction.js
Normal file
@@ -0,0 +1,96 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
async function testFile(filePath, expectedElementSize) {
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init();
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(filePath);
|
||||
|
||||
console.log(`\n=== Testing ${filePath} ===`);
|
||||
console.log(`File size: ${data.length} bytes`);
|
||||
console.log(`Expected elementSize: ${expectedElementSize}`);
|
||||
|
||||
// Enable bone reduction in loader
|
||||
loader.setEnableBoneReduction(true);
|
||||
loader.setTargetBoneCount(4);
|
||||
|
||||
// Load USD with bone reduction config
|
||||
await new Promise((resolve, reject) => {
|
||||
loader.parse(
|
||||
data,
|
||||
filePath.split('/').pop(),
|
||||
(usd) => {
|
||||
console.log('✓ USD loaded successfully');
|
||||
|
||||
// Get render scene
|
||||
const ok = usd.toRenderScene();
|
||||
if (!ok) {
|
||||
console.error('✗ Failed to convert to render scene');
|
||||
reject(new Error('Failed to convert to render scene'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the render scene data
|
||||
const renderSceneJSON = usd.getRenderSceneAsJSON();
|
||||
const renderScene = JSON.parse(renderSceneJSON);
|
||||
|
||||
console.log(`✓ Converted to render scene with ${renderScene.meshes.length} meshes`);
|
||||
|
||||
for (const mesh of renderScene.meshes) {
|
||||
if (mesh.joint_and_weights) {
|
||||
const elementSize = mesh.joint_and_weights.elementSize;
|
||||
console.log(` Mesh: ${mesh.abs_path}`);
|
||||
console.log(` Original elementSize: ${expectedElementSize}`);
|
||||
console.log(` After reduction: ${elementSize}`);
|
||||
|
||||
if (elementSize === 4) {
|
||||
console.log(` ✓ Bone reduction successful: ${expectedElementSize} → ${elementSize}`);
|
||||
} else if (elementSize === expectedElementSize && expectedElementSize <= 4) {
|
||||
console.log(` ✓ No reduction needed (already ≤ 4)`);
|
||||
} else {
|
||||
console.log(` ✗ Bone reduction failed: expected 4, got ${elementSize}`);
|
||||
}
|
||||
|
||||
const numIndices = mesh.joint_and_weights.jointIndices?.length || 0;
|
||||
const numWeights = mesh.joint_and_weights.jointWeights?.length || 0;
|
||||
const numVertices = numIndices / elementSize;
|
||||
console.log(` Vertices: ${numVertices}`);
|
||||
console.log(` Total indices: ${numIndices}`);
|
||||
console.log(` Total weights: ${numWeights}`);
|
||||
}
|
||||
}
|
||||
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
console.error('✗ Failed to load USD:', error);
|
||||
reject(error);
|
||||
},
|
||||
{
|
||||
maxMemoryLimitMB: 2048
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('✗ Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const testFiles = [
|
||||
{ path: '../../models/synthetic-skin-8influences.usda', elementSize: 8 },
|
||||
{ path: '../../models/synthetic-skin-16influences.usda', elementSize: 16 },
|
||||
{ path: '../../models/synthetic-skin-32influences.usda', elementSize: 32 }
|
||||
];
|
||||
|
||||
for (const test of testFiles) {
|
||||
await testFile(test.path, test.elementSize);
|
||||
}
|
||||
|
||||
console.log('\n=== All tests completed ===');
|
||||
}
|
||||
|
||||
main();
|
||||
44
web/js/test-anim-debug.js
Normal file
44
web/js/test-anim-debug.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
|
||||
async function main() {
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init({ useMemory64: false });
|
||||
|
||||
const usd = await new Promise((resolve, reject) => {
|
||||
loader.load('../../models/skintest-blender.usda', resolve, null, reject);
|
||||
});
|
||||
|
||||
console.log('\n=== Animation Debug Info ===');
|
||||
const numAnims = usd.numAnimations();
|
||||
console.log(`Total animations: ${numAnims}`);
|
||||
|
||||
for (let i = 0; i < numAnims; i++) {
|
||||
const animInfo = usd.getAnimationInfo(i);
|
||||
console.log(`\nAnimation ${i}:`);
|
||||
console.log(' animInfo:', JSON.stringify(animInfo, null, 2));
|
||||
|
||||
const anim = usd.getAnimation(i);
|
||||
console.log(' anim.channels:', anim.channels ? anim.channels.length : 0);
|
||||
console.log(' anim.samplers:', anim.samplers ? anim.samplers.length : 0);
|
||||
|
||||
if (anim.channels && anim.channels.length > 0) {
|
||||
console.log('\n First few channels:');
|
||||
for (let j = 0; j < Math.min(3, anim.channels.length); j++) {
|
||||
console.log(` Channel ${j}:`, JSON.stringify(anim.channels[j], null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (anim.samplers && anim.samplers.length > 0) {
|
||||
console.log('\n First sampler:');
|
||||
const sampler = anim.samplers[0];
|
||||
console.log(` times.length: ${sampler.times ? sampler.times.length : 0}`);
|
||||
console.log(` values.length: ${sampler.values ? sampler.values.length : 0}`);
|
||||
if (sampler.times && sampler.times.length > 0) {
|
||||
console.log(` First time: ${sampler.times[0]}`);
|
||||
console.log(` First values: [${sampler.values.slice(0, 3).join(', ')}]`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
21
web/js/test-boundaries.js
Normal file
21
web/js/test-boundaries.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
async function test(file, expected) {
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init();
|
||||
const data = fs.readFileSync(file);
|
||||
return new Promise((resolve) => {
|
||||
loader.parse(data, file,
|
||||
() => resolve('SUCCESS'),
|
||||
() => resolve('FAIL')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
console.log('Testing boundary values (should succeed):',
|
||||
await test('../../models/test-digit-boundaries.usda'));
|
||||
console.log('Testing over-boundary values (should fail):',
|
||||
await test('../../models/test-digit-over-boundaries.usda'));
|
||||
})();
|
||||
58
web/js/test-digit-limits.js
Normal file
58
web/js/test-digit-limits.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
async function testFile(filePath, shouldFail = false) {
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init();
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(filePath);
|
||||
|
||||
console.log(`\nTesting ${filePath} (${data.length} bytes)`);
|
||||
console.log(`Expected to ${shouldFail ? 'FAIL' : 'SUCCEED'}`);
|
||||
|
||||
// Load USD
|
||||
await new Promise((resolve, reject) => {
|
||||
loader.parse(
|
||||
data,
|
||||
filePath.split('/').pop(),
|
||||
(usd) => {
|
||||
if (shouldFail) {
|
||||
console.log('✗ Unexpected: File loaded successfully (should have failed)');
|
||||
} else {
|
||||
console.log('✓ File loaded successfully');
|
||||
}
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
if (shouldFail) {
|
||||
console.log('✓ Expected failure:', error.message || error);
|
||||
} else {
|
||||
console.error('✗ Unexpected failure:', error);
|
||||
}
|
||||
resolve(); // Don't reject so we can continue testing
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('✗ Test error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('=== Testing Digit Length Guards ===');
|
||||
|
||||
// Test normal file with valid numbers
|
||||
await testFile('../../models/test-large-numbers.usda', false);
|
||||
|
||||
// Test file with excessive digits (should fail)
|
||||
await testFile('../../models/test-excessive-digits.usda', true);
|
||||
|
||||
// Test files with bone reduction (should still work)
|
||||
await testFile('../../models/synthetic-skin-16influences.usda', false);
|
||||
|
||||
console.log('\n=== All tests completed ===');
|
||||
}
|
||||
|
||||
main();
|
||||
10
web/js/test-malicious.js
Normal file
10
web/js/test-malicious.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init();
|
||||
const data = fs.readFileSync('../../models/test-malicious-digits.usda');
|
||||
loader.parse(data, 'test',
|
||||
() => console.log('UNEXPECTED: Malicious file loaded'),
|
||||
(e) => console.log('GOOD: Malicious file rejected')
|
||||
);
|
||||
37
web/js/test-number-parsing.js
Normal file
37
web/js/test-number-parsing.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { TinyUSDZLoader } from './src/tinyusdz/TinyUSDZLoader.js';
|
||||
import fs from 'node:fs';
|
||||
|
||||
async function main() {
|
||||
const loader = new TinyUSDZLoader();
|
||||
await loader.init();
|
||||
|
||||
const filePath = '../../models/test-large-numbers.usda';
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(filePath);
|
||||
|
||||
console.log(`Loading ${filePath} (${data.length} bytes)`);
|
||||
|
||||
// Load USD
|
||||
await new Promise((resolve, reject) => {
|
||||
loader.parse(
|
||||
data,
|
||||
'test-large-numbers.usda',
|
||||
(usd) => {
|
||||
console.log('✓ USD loaded successfully');
|
||||
console.log('✓ Large number parsing test passed');
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
console.error('✗ Failed to load USD:', error);
|
||||
reject(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('✗ Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user