forked from 0ad/0ad
Add vector prototype to vector-like return values from C++ to JS. Fixes #2394.
This was SVN commit r14645.
This commit is contained in:
parent
d677033c4c
commit
fd187f466f
230
binaries/data/mods/public/globalscripts/vector.js
Normal file
230
binaries/data/mods/public/globalscripts/vector.js
Normal file
@ -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;
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -91,6 +91,9 @@ public:
|
||||
*/
|
||||
static shared_ptr<ScriptRuntime> CreateRuntime(int runtimeSize = DEFAULT_RUNTIME_SIZE);
|
||||
|
||||
CScriptValRooted vector2Dprototype;
|
||||
CScriptValRooted vector3Dprototype;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param nativeScopeName Name of global object that functions (via RegisterFunction) will
|
||||
|
@ -163,7 +163,10 @@ template<> bool ScriptInterface::FromJSVal<CFixedVector3D>(JSContext* cx, jsval
|
||||
|
||||
template<> jsval ScriptInterface::ToJSVal<CFixedVector3D>(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<CFixedVector2D>(JSContext* cx, jsval
|
||||
|
||||
template<> jsval ScriptInterface::ToJSVal<CFixedVector2D>(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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user