From b060c07db129aa8af48e744f5fe8fade38b9001f Mon Sep 17 00:00:00 2001 From: "Michael \"Z\" Goddard" Date: Tue, 7 Nov 2017 17:18:23 -0500 Subject: [PATCH] Compare new setRotationCenter values after truncating to 32bit `Skin._rotationCenter` is a twgl vector or said another way a Float32Array. JavaScript casts values stored in this array as 32 bit floats instead of JavaScript's standard 64 bit floats. Comparing the equality, like `setRotationCenter` does, of a 64 bit float against a value stored in a 32 bit container will virtually always be false. Truncating the new value into a 32 bit (losing precision) will give a more useful comparison and remove a lot of current false positives. --- src/Skin.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Skin.js b/src/Skin.js index f54eddb..a92fdfe 100644 --- a/src/Skin.js +++ b/src/Skin.js @@ -4,6 +4,19 @@ const twgl = require('twgl.js'); const RenderConstants = require('./RenderConstants'); +/** + * Truncate a number into what could be stored in a 32 bit floating point value. + * @param {number} num Number to truncate. + * @return {number} Truncated value. + */ +const toFloat32 = (function () { + const memory = new Float32Array(1); + return function (num) { + memory[0] = num; + return memory[0]; + }; +}()); + class Skin extends EventEmitter { /** * Create a Skin, which stores and/or generates textures for use in rendering. @@ -79,7 +92,11 @@ class Skin extends EventEmitter { */ setRotationCenter (x, y) { const emptySkin = this.size[0] === 0 && this.size[1] === 0; - const changed = x !== this._rotationCenter[0] || y !== this._rotationCenter[1]; + // Compare a 32 bit x and y value against the stored 32 bit center + // values. + const changed = ( + toFloat32(x) !== this._rotationCenter[0] || + toFloat32(y) !== this._rotationCenter[1]); if (!emptySkin && changed) { this._rotationCenter[0] = x; this._rotationCenter[1] = y;