From 6b927de9f1aa0e98c906096bc094e3139dfc06a7 Mon Sep 17 00:00:00 2001
From: humbletim <humbletim@gmail.com>
Date: Thu, 2 Mar 2017 18:11:24 -0500
Subject: [PATCH] Add example vec3 system module

---
 scripts/modules/vec3.js | 69 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 scripts/modules/vec3.js

diff --git a/scripts/modules/vec3.js b/scripts/modules/vec3.js
new file mode 100644
index 0000000000..f164f01374
--- /dev/null
+++ b/scripts/modules/vec3.js
@@ -0,0 +1,69 @@
+// Example of using a "system module" to decouple Vec3's implementation details.
+//
+// Users would bring Vec3 support in as a module:
+//   var vec3 = Script.require('vec3');
+//
+
+// (this example is compatible with using as a Script.include and as a Script.require module)
+try {
+    // Script.require
+    module.exports = vec3;
+} catch(e) {
+    // Script.include
+    Script.registerValue("vec3", vec3);
+}
+
+vec3.fromObject = function(v) {
+    //return new vec3(v.x, v.y, v.z);
+    //... this is even faster and achieves the same effect
+    v.__proto__ = vec3.prototype;
+    return v;
+};
+
+vec3.prototype = {
+    multiply: function(v2) {
+        // later on could support overrides like so:
+        //     if (v2 instanceof quat) { [...] }
+        // which of the below is faster (C++ or JS)?
+        // (dunno -- but could systematically find out and go with that version)
+
+        // pure JS option
+        // return new vec3(this.x * v2.x, this.y * v2.y, this.z * v2.z);
+
+        // hybrid C++ option
+        return vec3.fromObject(Vec3.multiply(this, v2));
+    },
+    // detects any NaN and Infinity values
+    isValid: function() {
+        return isFinite(this.x) && isFinite(this.y) && isFinite(this.z);
+    },
+    // format Vec3's, eg:
+    //     var v = vec3();
+    //     print(v); // outputs [Vec3 (0.000, 0.000, 0.000)]
+    toString: function() {
+        if (this === vec3.prototype) {
+            return "{Vec3 prototype}";
+        }
+        function fixed(n) { return n.toFixed(3); }
+        return "[Vec3 (" + [this.x, this.y, this.z].map(fixed) + ")]";
+    },
+};
+
+vec3.DEBUG = true;
+
+function vec3(x, y, z) {
+    if (!(this instanceof vec3)) {
+        // if vec3 is called as a function then re-invoke as a constructor
+        // (so that `value instanceof vec3` holds true for created values)
+        return new vec3(x, y, z);
+    }
+
+    // unfold default arguments (vec3(), vec3(.5), vec3(0,1), etc.)
+    this.x = x !== undefined ? x : 0;
+    this.y = y !== undefined ? y : this.x;
+    this.z = z !== undefined ? z : this.y;
+
+    if (vec3.DEBUG && !this.isValid())
+        throw new Error('vec3() -- invalid initial values ['+[].slice.call(arguments)+']');
+};
+