Skip to content

Commit 95665bc

Browse files
Flexible multiple clips (#421)
* Revert "Only one clip at a time" This reverts commit 0a7f8a0. * Support for multiple clips using regular expressions * Code review feedback * Revert "Code review feedback" This reverts commit f1a2069. * Use single quotes
1 parent cbd68e2 commit 95665bc

File tree

5 files changed

+21
-17
lines changed

5 files changed

+21
-17
lines changed

examples/animation-controls/animation-controls.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ const animationNames = {
1010

1111
updateAnimationMixer = () => {
1212

13-
const data = {}
13+
const data = {useRegExp: true}
1414
data.clip = 'none'
1515
Object.entries(animationNames).forEach((name) => {
1616

17-
const el = document.getElementById(name[0])
18-
17+
const regExpEscape = (s) => {
18+
return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
19+
}
20+
21+
el = document.getElementById(name[0])
1922
if (el.checked) {
20-
data.clip = name[1]
23+
if (data.clip) data.clip += "|"
24+
data.clip += regExpEscape(name[1])
2125
}
2226
})
2327

examples/animation-controls/index.html

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,18 @@
1414
<div class="topRight">
1515
<div>Controls</div>
1616
<div style="display: grid; grid-template-columns: 50% 50%">
17-
<label for="none">None</label>
18-
<input type="radio" id="none" name="animations" checked="true">
1917
<label for="attack">Attack</label>
20-
<input type="radio" id="attack" name="animations">
18+
<input type="checkbox" id="attack" name="attack">
2119
<label for="death">Death</label>
22-
<input type="radio" id="death" name="animations">
20+
<input type="checkbox" id="death" name="death">
2321
<label for="idle">Idle</label>
24-
<input type="radio" id="idle" name="animations">
22+
<input type="checkbox" id="idle" name="idle">
2523
<label for="jump">Jump</label>
26-
<input type="radio" id="jump" name="animations">
24+
<input type="checkbox" id="jump" name="jump">
2725
<label for="run">Run</label>
28-
<input type="radio" id="run" name="animations">
26+
<input type="checkbox" id="run" name="run">
2927
<label for="walk">Walk</label>
30-
<input type="radio" id="walk" name="animations">
28+
<input type="checkbox" id="walk" name="walk">
3129
<label for="duration">Duration (s)</label>
3230
<input type="text" id="duration" name="duration" value="0">
3331
<label for="clampWhenFinished">Clamp When Finished</label>

examples/bundle.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45064,6 +45064,7 @@ var LoopMode = {
4506445064
module.exports = AFRAME.registerComponent('animation-mixer', {
4506545065
schema: {
4506645066
clip: { default: '*' },
45067+
useRegExp: { default: false },
4506745068
duration: { default: 0 },
4506845069
clampWhenFinished: { default: false, type: 'boolean' },
4506945070
crossFadeDuration: { default: 0 },
@@ -45158,7 +45159,7 @@ module.exports = AFRAME.registerComponent('animation-mixer', {
4515845159

4515945160
if (!clips.length) return;
4516045161

45161-
var re = wildcardToRegExp(data.clip);
45162+
var re = data.useRegExp ? data.clip : wildcardToRegExp(data.clip);
4516245163

4516345164
for (var clip, i = 0; clip = clips[i]; i++) {
4516445165
if (clip.name.match(re)) {

src/loaders/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ an animation and its duration:
3333
| Property | Default | Description |
3434
|-------------------|----------|-----------------------------------------------------------|
3535
| clip | * | Name of the animation clip(s) to play. Accepts wildcards. |
36+
| useRegExp | false | If true, interpret the `clip` string as a regular expression. If false, it is treated as a literal string, except for the * character, which is treated as a variable-length wildcard. |
37+
3638
| duration | 0 | Duration of one cycle of the animation clip, in seconds. This provides the same functionality as timeScale (apart from pausing), with duration = clipLength/timeScale. This property only has an effect if timeScale is set to 1, otherwise the value of timeScale is used to determine animation playback speed. |
3739
| crossFadeDuration | 0 | Duration of cross-fades between clips, in seconds. |
3840
| loop | repeat | `once`, `repeat`, or `pingpong`. In `repeat` and `pingpong` modes, the clip plays once plus the specified number of repetitions. For `pingpong`, every second clip plays in reverse. |
@@ -41,9 +43,7 @@ an animation and its duration:
4143
| clampWhenFinished | false | If true, halts the animation at the last frame. |
4244
| startAt | 0 | Configures the animation clip to begin at a specific start time (in milliseconds). This is useful when you need to jump to an exact time in an animation. The input parameter will be scaled by the mixer's timeScale. Negative values will result in a pause before the animation begins. |
4345

44-
A list of available animations can usually be found by inspecting the model file or its documentation. All animations will play by default. To play only a specific set of animations, use wildcards: `animation-mixer="clip: run_*"`.
45-
46-
There is no provided syntax to specify multiple animations, except via the * wildcard. For example: `animation-mixer="clip: run,walk"` will match neither `run` nor `walk`, and would only match a clip named `run,walk`.
46+
A list of available animations can usually be found by inspecting the model file or its documentation. All animations will play by default. To play only a specific set of animations, use wildcards: `animation-mixer="clip: run_*"`, or use the useRegExp flag to enable full regular expression matching, e.g. `animation-mixer="useRegExp: true; clip: run|walk"`.
4747

4848
### Animation Events
4949

src/loaders/animation-mixer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const LoopMode = {
1414
module.exports = AFRAME.registerComponent('animation-mixer', {
1515
schema: {
1616
clip: { default: '*' },
17+
useRegExp: {default: false},
1718
duration: { default: 0 },
1819
clampWhenFinished: { default: false, type: 'boolean' },
1920
crossFadeDuration: { default: 0 },
@@ -108,7 +109,7 @@ module.exports = AFRAME.registerComponent('animation-mixer', {
108109

109110
if (!clips.length) return;
110111

111-
const re = wildcardToRegExp(data.clip);
112+
const re = data.useRegExp ? data.clip : wildcardToRegExp(data.clip);
112113

113114
for (let clip, i = 0; (clip = clips[i]); i++) {
114115
if (clip.name.match(re)) {

0 commit comments

Comments
 (0)