parse static method
Parses the constraint on glTF node index (its nodes[index] JSON),
or returns null when it has none or it is malformed.
Implementation
static VrmNodeConstraint? parse(
int index,
Map<String, dynamic> node,
int nodeCount,
) {
final ext =
(node['extensions'] as Map<String, dynamic>?)?['VRMC_node_constraint']
as Map<String, dynamic>?;
final c = ext?['constraint'] as Map<String, dynamic>?;
if (c == null) return null;
(int, double)? common(Map<String, dynamic>? j) {
final source = j?['source'];
if (source is! int || source < 0 || source >= nodeCount) return null;
if (source == index) return null;
return (source, ((j!['weight'] as num?) ?? 1).toDouble().clamp(0, 1));
}
final roll = c['roll'] as Map<String, dynamic>?;
if (common(roll) case (final source, final weight)) {
final axis = switch (roll!['rollAxis']) {
'X' => Vector3(1, 0, 0),
'Y' => Vector3(0, 1, 0),
'Z' => Vector3(0, 0, 1),
_ => null,
};
if (axis == null) return null;
return VrmRollConstraint(
destination: index,
source: source,
weight: weight,
rollAxis: axis,
);
}
final aim = c['aim'] as Map<String, dynamic>?;
if (common(aim) case (final source, final weight)) {
final axis = switch (aim!['aimAxis']) {
'PositiveX' => Vector3(1, 0, 0),
'NegativeX' => Vector3(-1, 0, 0),
'PositiveY' => Vector3(0, 1, 0),
'NegativeY' => Vector3(0, -1, 0),
'PositiveZ' => Vector3(0, 0, 1),
'NegativeZ' => Vector3(0, 0, -1),
_ => null,
};
if (axis == null) return null;
return VrmAimConstraint(
destination: index,
source: source,
weight: weight,
aimAxis: axis,
);
}
final rotation = c['rotation'] as Map<String, dynamic>?;
if (common(rotation) case (final source, final weight)) {
return VrmRotationConstraint(
destination: index,
source: source,
weight: weight,
);
}
return null;
}