(_options: SequenceOptions = SEQUENCE_DEFAULTS)
| 27 | * @category Transforms |
| 28 | */ |
| 29 | export function sequence(_options: SequenceOptions = SEQUENCE_DEFAULTS): Transform { |
| 30 | const options = assignDefaults(SEQUENCE_DEFAULTS, _options); |
| 31 | |
| 32 | return createTransform(NAME, (doc: Document): void => { |
| 33 | const logger = doc.getLogger(); |
| 34 | const root = doc.getRoot(); |
| 35 | const fps = options.fps; |
| 36 | |
| 37 | // Collect sequence nodes. |
| 38 | const sequenceNodes = root.listNodes().filter((node) => node.getName().match(options.pattern)); |
| 39 | |
| 40 | // Sort by node name. |
| 41 | if (options.sort) { |
| 42 | sequenceNodes.sort((a, b) => (a.getName() > b.getName() ? 1 : -1)); |
| 43 | } |
| 44 | |
| 45 | // Create animation cycling visibility of each node. |
| 46 | const anim = doc.createAnimation(options.name); |
| 47 | const animBuffer = root.listBuffers()[0]; |
| 48 | sequenceNodes.forEach((node, i) => { |
| 49 | // Create keyframe tracks that show each node for a single frame. |
| 50 | let inputArray; |
| 51 | let outputArray; |
| 52 | if (i === 0) { |
| 53 | inputArray = [i / fps, (i + 1) / fps]; |
| 54 | outputArray = [1, 1, 1, 0, 0, 0]; |
| 55 | } else if (i === sequenceNodes.length - 1) { |
| 56 | inputArray = [(i - 1) / fps, i / fps]; |
| 57 | outputArray = [0, 0, 0, 1, 1, 1]; |
| 58 | } else { |
| 59 | inputArray = [(i - 1) / fps, i / fps, (i + 1) / fps]; |
| 60 | outputArray = [0, 0, 0, 1, 1, 1, 0, 0, 0]; |
| 61 | } |
| 62 | |
| 63 | // Append channel to animation sequence. |
| 64 | const input = doc.createAccessor().setArray(new Float32Array(inputArray)).setBuffer(animBuffer); |
| 65 | const output = doc |
| 66 | .createAccessor() |
| 67 | .setArray(new Float32Array(outputArray)) |
| 68 | .setBuffer(animBuffer) |
| 69 | .setType(Accessor.Type.VEC3); |
| 70 | const sampler = doc |
| 71 | .createAnimationSampler() |
| 72 | .setInterpolation(AnimationSampler.Interpolation.STEP) |
| 73 | .setInput(input) |
| 74 | .setOutput(output); |
| 75 | const channel = doc |
| 76 | .createAnimationChannel() |
| 77 | .setTargetNode(node) |
| 78 | .setTargetPath(AnimationChannel.TargetPath.SCALE) |
| 79 | .setSampler(sampler); |
| 80 | anim.addSampler(sampler).addChannel(channel); |
| 81 | }); |
| 82 | |
| 83 | logger.debug(`${NAME}: Complete.`); |
| 84 | }); |
| 85 | } |
no test coverage detected