Skip to content

Commit 8317fae

Browse files
slimbuckDonovan Hutchencewilleastcott
authored
Orient glb quaterion keys correctly (playcanvas#1975)
* preprocess glb quaterions to consecutive keys to fall in the same winding Co-authored-by: Donovan Hutchence <dhutchence@snapchat.com> Co-authored-by: Will Eastcott <will@playcanvas.com>
1 parent 3a3141d commit 8317fae

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

src/resources/parser/glb-parser.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,11 +807,52 @@ Object.assign(pc, function () {
807807
interpolation));
808808
}
809809

810+
var quatArrays = [];
811+
810812
// convert anim channels
811813
for (i = 0; i < animationData.channels.length; ++i) {
812814
var channel = animationData.channels[i];
813815
var target = channel.target;
814-
curves[channel.sampler]._paths.push(pc.AnimBinder.joinPath([nodes[target.node].name, target.path]));
816+
var curve = curves[channel.sampler];
817+
curve._paths.push(pc.AnimBinder.joinPath([nodes[target.node].name, target.path]));
818+
819+
// if this target is a set of quaternion keys, make note of its index so we can perform
820+
// quaternion-specific processing on it.
821+
if (target.path.startsWith('rotation') && curve.interpolation !== pc.INTERPOLATION_CUBIC) {
822+
quatArrays.push(curve.output);
823+
}
824+
}
825+
826+
// sort the list of array indexes so we can skip dups
827+
quatArrays.sort();
828+
829+
// run through the quaternion data arrays flipping quaternion keys
830+
// that don't fall in the same winding order.
831+
var prevIndex = null;
832+
for (i = 0; i < quatArrays.length; ++i) {
833+
var index = quatArrays[i];
834+
// skip over duplicate array indices
835+
if (i === 0 || index !== prevIndex) {
836+
var data = outputs[index];
837+
if (data.components === 4) {
838+
var d = data.data;
839+
var len = d.length - 4;
840+
for (var j = 0; j < len; j += 4) {
841+
var dp = d[j + 0] * d[j + 4] +
842+
d[j + 1] * d[j + 5] +
843+
d[j + 2] * d[j + 6] +
844+
d[j + 3] * d[j + 7];
845+
846+
if (dp < 0) {
847+
d[j + 4] *= -1;
848+
d[j + 5] *= -1;
849+
d[j + 6] *= -1;
850+
d[j + 7] *= -1;
851+
}
852+
}
853+
}
854+
prevIndex = index;
855+
}
815856
}
816857

817858
// calculate duration of the animation as maximum time value

0 commit comments

Comments
 (0)