diff --git a/binaries/data/mods/public/globalscripts/vector.js b/binaries/data/mods/public/globalscripts/vector.js new file mode 100644 index 0000000000..170022aae3 --- /dev/null +++ b/binaries/data/mods/public/globalscripts/vector.js @@ -0,0 +1,230 @@ +///////////////////////////////////////////////////////////////////// +// Vector2D +// +// Class for representing and manipulating 2D vectors +// +///////////////////////////////////////////////////////////////////// + +// TODO: Type errors if v not instanceof Vector classes +// TODO: Possibly implement in C++ + +function Vector2D(x, y) +{ + if (arguments.length == 2) + this.set(x, y); + else + this.set(0, 0); +} + +Vector2D.prototype.clone = function() +{ + return new Vector2D(this.x, this.y); +}; + +Vector2D.prototype.set = function(x, y) +{ + this.x = x; + this.y = y; + return this; +}; + +Vector2D.prototype.add = function(v) +{ + this.x += v.x; + this.y += v.y; + return this; +}; + +Vector2D.prototype.sub = function(v) +{ + this.x -= v.x; + this.y -= v.y; + return this; +}; + +Vector2D.prototype.mult = function(f) +{ + this.x *= f; + this.y *= f; + return this; +}; + +Vector2D.prototype.div = function(f) +{ + this.x /= f; + this.y /= f; + return this; +}; + +Vector2D.prototype.dot = function(v) +{ + return this.x * v.x + this.y * v.y; +}; + +// get the non-zero coordinate of the vector cross +Vector2D.prototype.cross = function(v) +{ + return this.x * v.y - this.y * v.x; +}; + +Vector2D.prototype.lengthSquared = function() +{ + return this.dot(this); +}; + +Vector2D.prototype.length = function() +{ + return Math.sqrt(this.lengthSquared()); +}; + +/** + * Compare this length to the length of v, + * @return 0 if the lengths are equal + * @return 1 if this is longer than v + * @return -1 if this is shorter than v + * @return NaN if the vectors aren't comparable + */ +Vector2D.prototype.compareLength = function(v) +{ + var dDist = this.lengthSquared() - v.lengthSquared(); + if (!dDist) + return dDist == 0 ? 0 : NaN; + return dDist < 0 ? -1 : 1; +}; + +Vector2D.prototype.distanceToSquared = function(v) +{ + var dx = this.x - v.x; + var dy = this.y - v.y; + return dx * dx + dy * dy; +}; + +Vector2D.prototype.distanceTo = function(v) +{ + return Math.sqrt(this.distanceToSquared(v)); +}; + +Vector2D.prototype.normalize = function() +{ + var mag = this.length(); + if (!mag) + return this; + + return this.div(mag); +}; + +///////////////////////////////////////////////////////////////////// +// Vector3D +// +// Class for representing and manipulating 3D vectors +// +///////////////////////////////////////////////////////////////////// + +function Vector3D(x, y, z) +{ + if (arguments.length == 3) + this.set(x, y, y); + else + this.set(0, 0, 0); +} + +Vector3D.prototype.clone = function() +{ + return new Vector3D(this.x, this.y, this.z); +}; + +Vector3D.prototype.set = function(x, y, z) +{ + this.x = x; + this.y = y; + this.z = z; + return this; +}; + +Vector3D.prototype.add = function(v) +{ + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +Vector3D.prototype.sub = function(v) +{ + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + return this; +}; + +Vector3D.prototype.mult = function(f) +{ + this.x *= f; + this.y *= f; + this.z *= f; + return this; +}; + +Vector3D.prototype.div = function(f) +{ + this.x /= f; + this.y /= f; + this.z /= f; + return this; +}; + +Vector3D.prototype.dot = function(v) +{ + return this.x * v.x + this.y * v.y + this.z * v.z; +}; + +Vector3D.prototype.lengthSquared = function() +{ + return this.dot(this); +}; + +Vector3D.prototype.length = function() +{ + return Math.sqrt(this.lengthSquared()); +}; + +/** + * Compare this length to the length of v, + * @return 0 if the lengths are equal + * @return 1 if this is longer than v + * @return -1 if this is shorter than v + * @return NaN if the vectors aren't comparable + */ +Vector3D.prototype.compareLength = function(v) +{ + var dDist = this.lengthSquared() - v.lengthSquared(); + if (!dDist) + return dDist == 0 ? 0 : NaN; + return dDist < 0 ? -1 : 1; +}; + +Vector3D.prototype.distanceToSquared = function(v) +{ + var dx = this.x - v.x; + var dy = this.y - v.y; + var dz = this.z - v.z; + return dx * dx + dy * dy + dz * dz; +}; + +Vector3D.prototype.distanceTo = function(v) +{ + return Math.sqrt(this.distanceToSquared(v)); +}; + +Vector3D.prototype.normalize = function() +{ + var mag = this.length(); + if (!mag) + return this; + + return this.div(mag); +}; + +// make the prototypes easily accessible to C++ +const Vector2Dprototype = Vector2D.prototype; +const Vector3Dprototype = Vector3D.prototype; diff --git a/binaries/data/mods/public/maps/random/rmgen/vector.js b/binaries/data/mods/public/maps/random/rmgen/vector.js deleted file mode 100644 index ff4c258efe..0000000000 --- a/binaries/data/mods/public/maps/random/rmgen/vector.js +++ /dev/null @@ -1,141 +0,0 @@ -///////////////////////////////////////////////////////////////////// -// Vector2D -// -// Class for representing and manipulating 2D vectors -// -///////////////////////////////////////////////////////////////////// - -// TODO: Type errors if v not instanceof Vector classes -// TODO: Possibly implement in C++ - -function Vector2D(x, y) -{ - if (arguments.length == 2) - { - this.set(x, y); - } - else - { - this.set(0, 0); - } -} - -Vector2D.prototype.set = function(x, y) -{ - this.x = x; - this.y = y; -}; - -Vector2D.prototype.add = function(v) -{ - return new Vector2D(this.x + v.x, this.y + v.y); -}; - -Vector2D.prototype.sub = function(v) -{ - return new Vector2D(this.x - v.x, this.y - v.y); -}; - -Vector2D.prototype.mult = function(f) -{ - return new Vector2D(this.x * f, this.y * f); -}; - -Vector2D.prototype.div = function(f) -{ - return new Vector2D(this.x / f, this.y / f); -}; - -Vector2D.prototype.dot = function(v) -{ - return this.x * v.x + this.y * v.y; -}; - -Vector2D.prototype.lengthSquared = function() -{ - return this.dot(this); -}; - -Vector2D.prototype.length = function() -{ - return sqrt(this.lengthSquared()); -}; - -Vector2D.prototype.normalize = function() -{ - var mag = this.length(); - - this.x /= mag; - this.y /= mag; -}; - -///////////////////////////////////////////////////////////////////// -// Vector3D -// -// Class for representing and manipulating 3D vectors -// -///////////////////////////////////////////////////////////////////// - -function Vector3D(x, y, z) -{ - if (arguments.length == 3) - { - this.set(x, y, y); - } - else - { - this.set(0, 0, 0); - } -} - -Vector3D.prototype.set = function(x, y, z) -{ - this.x = x; - this.y = y; - this.z = z; -}; - -Vector3D.prototype.add = function(v) -{ - return new Vector3D(this.x + v.x, this.y + v.y, this.z + v.z); -}; - -Vector3D.prototype.sub = function(v) -{ - return new Vector3D(this.x - v.x, this.y - v.y, this.z - v.z); -}; - -Vector3D.prototype.mult = function(f) -{ - return new Vector3D(this.x * f, this.y * f, this.z * f); -}; - -Vector3D.prototype.div = function(f) -{ - return new Vector3D(this.x / f, this.y / f, this.z / f); -}; - -Vector3D.prototype.dot = function(v) -{ - return this.x * v.x + this.y * v.y + this.z * v.z; -}; - -Vector3D.prototype.lengthSquared = function() -{ - return this.dot(this); -}; - -Vector3D.prototype.length = function() -{ - return sqrt(this.lengthSquared()); -}; - -Vector3D.prototype.normalize = function() -{ - var mag = this.length(); - - this.x /= mag; - this.y /= mag; - this.z /= mag; -}; - diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index 924092b5ac..71cc9e9786 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -627,7 +627,11 @@ bool ScriptInterface::LoadGlobalScripts() return false; } } - + jsval proto; + if (JS_GetProperty(m->m_cx, JS_GetGlobalObject(m->m_cx), "Vector2Dprototype", &proto)) + vector2Dprototype = CScriptValRooted(m->m_cx, proto); + if (JS_GetProperty(m->m_cx, JS_GetGlobalObject(m->m_cx), "Vector3Dprototype", &proto)) + vector3Dprototype = CScriptValRooted(m->m_cx, proto); return true; } @@ -1033,7 +1037,6 @@ bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path) return ok ? true : false; } - bool ScriptInterface::Eval(const char* code) { jsval rval; diff --git a/source/scriptinterface/ScriptInterface.h b/source/scriptinterface/ScriptInterface.h index c8d3390276..e5b88798ce 100644 --- a/source/scriptinterface/ScriptInterface.h +++ b/source/scriptinterface/ScriptInterface.h @@ -91,6 +91,9 @@ public: */ static shared_ptr CreateRuntime(int runtimeSize = DEFAULT_RUNTIME_SIZE); + CScriptValRooted vector2Dprototype; + CScriptValRooted vector3Dprototype; + /** * Constructor. * @param nativeScopeName Name of global object that functions (via RegisterFunction) will diff --git a/source/simulation2/scripting/EngineScriptConversions.cpp b/source/simulation2/scripting/EngineScriptConversions.cpp index 06d63448e1..f902a00775 100644 --- a/source/simulation2/scripting/EngineScriptConversions.cpp +++ b/source/simulation2/scripting/EngineScriptConversions.cpp @@ -163,7 +163,10 @@ template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const CFixedVector3D& val) { - JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL); + // apply the Vector3D prototype to the return value; + ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); + JSObject* obj = JS_NewObject(cx, NULL, JSVAL_TO_OBJECT(pCxPrivate->pScriptInterface->vector3Dprototype.get()), NULL); + if (!obj) return JSVAL_VOID; @@ -197,7 +200,10 @@ template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const CFixedVector2D& val) { - JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL); + // apply the Vector2D prototype to the return value + ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); + JSObject* obj = JS_NewObject(cx, NULL, JSVAL_TO_OBJECT(pCxPrivate->pScriptInterface->vector2Dprototype.get()), NULL); + if (!obj) return JSVAL_VOID;