digitalmars.D - Velocity Math Module
- Kyle Furlong (8/8) Jan 24 2006 I just started work on Velocity, a game engine. I want the math module
- Mike Parker (2/7) Jan 24 2006 What are the errors you are seeing?
- Kyle Furlong (98/109) Jan 24 2006 With this test program:
- James Dunne (8/128) Jan 24 2006 Sadly, D's templates don't easily analogue to their C++ brothers. I ran...
- Agent Orange (2/111) Jan 24 2006 you cant create a struct template
- Sean Kelly (3/5) Jan 24 2006 DMD allows it, though the docs say it's illegal.
- Oskar Linde (8/13) Jan 25 2006 But the doc also says its legal:
- Dave (7/12) Jan 25 2006 Can you link to where you saw that... (After all, there are whole librar...
- Sean Kelly (3/14) Jan 25 2006 He may have already fixed them. I can't find the clause I remember seei...
- Lucas Goss (111/117) Jan 24 2006 As mentioned elsewhere, you can't create a struct template. Anyways,
- Lucas Goss (341/341) Jan 24 2006 As promised, here's my version of a 2-dimensional vector (I also have
- Kyle Furlong (4/127) Jan 24 2006 Thanks for the heads up. I'm still waiting for Don to weigh in, but does...
- Don Clugston (15/48) Jan 25 2006 For future reference:
- Oskar Linde (9/112) Jan 24 2006 There are just a few minor errors in your code. Find below some
- Kyle Furlong (2/118) Jan 24 2006 It compiles but when you try and use it in another module the compile fa...
- Oskar Linde (12/28) Jan 25 2006 With what errors?
- Kyle Furlong (3/37) Jan 25 2006 Can you attach a file with your version, the ng is making it difficult
- Oskar Linde (4/7) Jan 25 2006 Of course. I should have done that from the start. I hope Unix line
- John C (26/114) Jan 25 2006 See below for corrections that will enable D to compile your template.
- Tom S (9/9) Jan 25 2006 You might want to take a look at my templated math module:
- Dave (90/199) Jan 25 2006 Below is what it looks like you wanted (with comments), complete with a
- Kyle Furlong (16/124) Jan 25 2006 Thank you all for your input. There is still some ambiguity though.
- Kyle Furlong (2/227) Jan 25 2006 Sorry attached the old one on accident.
- Dave (12/93) Jan 25 2006 Change the second 'V' to 'v' in velocity.math.Vector and copy this code ...
- Oskar Linde (17/29) Jan 25 2006 Up until DMD version 0.143 this had to be written as:
- Kyle Furlong (2/40) Jan 26 2006 Thanks for the explanation.
I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd.
Jan 24 2006
Kyle Furlong wrote:I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd.What are the errors you are seeing?
Jan 24 2006
Mike Parker wrote:Kyle Furlong wrote:With this test program: import velocity.math.Vector; int main() { alias Vector!(int,2) Point; Point origin = Point(0,0); Point a = Point(1,1); assert((a + origin) == a); } I get these errors: ---------- Capture Output ----------I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd.What are the errors you are seeing?"C:\dmd\bin\build.exe" Vector.d -clean\d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): cannot have parameter of type void \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(57): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(57): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(57): cannot have parameter of type void \d\import\velocity\math\Vector.d(67): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(67): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(67): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(67): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(67): cannot have parameter of type void \d\import\velocity\math\Vector.d(77): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(77): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(39): cannot implicitly convert expression (this.storage) of type int[2] to int \d\import\velocity\math\Vector.d(44): cannot implicitly convert expression ((this.storage)[(i)..(j)]) of type int[] to int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opAdd.a voids have no value \d\import\velocity\math\Vector.d(49): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(49): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(49): variable velocity.math.Vector.Vector!(int,2).Vector.opAdd.ret voids have no value \d\import\velocity\math\Vector.d(52): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(52): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opSub.a voids have no value \d\import\velocity\math\Vector.d(59): identifier 'Row' is not defined \d\import\velocity\math\Vector.d(59): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(59): Vector!(int,2,int) is used as a type \d\import\velocity\math\Vector.d(59): variable velocity.math.Vector.Vector!(int,2).Vector.opSub.ret voids have no value \d\import\velocity\math\Vector.d(62): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(62): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opAddAssign.a voids have no value \d\import\velocity\math\Vector.d(69): identifier 'Row' is not defined \d\import\velocity\math\Vector.d(69): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(69): Vector!(int,2,int) is used as a type \d\import\velocity\math\Vector.d(69): variable velocity.math.Vector.Vector!(int,2).Vector.opAddAssign.ret voids have no value \d\import\velocity\math\Vector.d(72): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(72): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d(79): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(79): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(79): variable velocity.math.Vector.Vector!(int,2).Vector.opCall.v voids have no value \d\import\velocity\math\Vector.d(85): v must be an array or pointer type, not int \d\import\velocity\math\Vector.d(5): template instance velocity.math.Vector.Vector!(int,2) error instantiating Vector.d(6): voids have no value Vector.d(6): cannot implicitly convert expression ((opCall)((_arguments_ii),0,0)) of type void to Vector Vector.d(7): voids have no value Vector.d(7): cannot implicitly convert expression ((opCall)((_arguments_ii),1,1)) of type void to Vector Vector.d(8): function velocity.math.Vector.Vector!(int,2).Vector.opAdd (void) does not match argument types (Vector ) Vector.d(8): cannot implicitly convert expression (origin) of type Vector to void Vector.d(8): void has no value Vector.d(8): incompatible types for ((((a).opAdd)(cast(void)(origin))) == (a)): 'void' and 'Vector'Terminated with exit code 1.
Jan 24 2006
Kyle Furlong wrote:Mike Parker wrote:Sadly, D's templates don't easily analogue to their C++ brothers. I ran into this same problem attempting something similar to what you've hit. Perhaps I can clear the way for "the template ninja" (Don Clugston) to come in and rescue you! -- Regards, James DunneKyle Furlong wrote:With this test program: import velocity.math.Vector; int main() { alias Vector!(int,2) Point; Point origin = Point(0,0); Point a = Point(1,1); assert((a + origin) == a); } I get these errors: ---------- Capture Output ---------- > "C:\dmd\bin\build.exe" Vector.d -clean \d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): cannot have parameter of type void \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(57): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(57): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(57): cannot have parameter of type void \d\import\velocity\math\Vector.d(67): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(67): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(67): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(67): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(67): cannot have parameter of type void \d\import\velocity\math\Vector.d(77): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(77): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(39): cannot implicitly convert expression (this.storage) of type int[2] to int \d\import\velocity\math\Vector.d(44): cannot implicitly convert expression ((this.storage)[(i)..(j)]) of type int[] to int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opAdd.a voids have no value \d\import\velocity\math\Vector.d(49): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(49): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(49): variable velocity.math.Vector.Vector!(int,2).Vector.opAdd.ret voids have no value \d\import\velocity\math\Vector.d(52): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(52): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opSub.a voids have no value \d\import\velocity\math\Vector.d(59): identifier 'Row' is not defined \d\import\velocity\math\Vector.d(59): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(59): Vector!(int,2,int) is used as a type \d\import\velocity\math\Vector.d(59): variable velocity.math.Vector.Vector!(int,2).Vector.opSub.ret voids have no value \d\import\velocity\math\Vector.d(62): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(62): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opAddAssign.a voids have no value \d\import\velocity\math\Vector.d(69): identifier 'Row' is not defined \d\import\velocity\math\Vector.d(69): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(69): Vector!(int,2,int) is used as a type \d\import\velocity\math\Vector.d(69): variable velocity.math.Vector.Vector!(int,2).Vector.opAddAssign.ret voids have no value \d\import\velocity\math\Vector.d(72): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(72): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d(79): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(79): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(79): variable velocity.math.Vector.Vector!(int,2).Vector.opCall.v voids have no value \d\import\velocity\math\Vector.d(85): v must be an array or pointer type, not int \d\import\velocity\math\Vector.d(5): template instance velocity.math.Vector.Vector!(int,2) error instantiating Vector.d(6): voids have no value Vector.d(6): cannot implicitly convert expression ((opCall)((_arguments_ii),0,0)) of type void to Vector Vector.d(7): voids have no value Vector.d(7): cannot implicitly convert expression ((opCall)((_arguments_ii),1,1)) of type void to Vector Vector.d(8): function velocity.math.Vector.Vector!(int,2).Vector.opAdd (void) does not match argument types (Vector ) Vector.d(8): cannot implicitly convert expression (origin) of type Vector to void Vector.d(8): void has no value Vector.d(8): incompatible types for ((((a).opAdd)(cast(void)(origin))) == (a)): 'void' and 'Vector' > Terminated with exit code 1.I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd.What are the errors you are seeing?
Jan 24 2006
In article <dr6o86$7mq$1 digitaldaemon.com>, Kyle Furlong says...Mike Parker wrote:you cant create a struct templateKyle Furlong wrote:With this test program: import velocity.math.Vector; int main() { alias Vector!(int,2) Point; Point origin = Point(0,0); Point a = Point(1,1); assert((a + origin) == a); } I get these errors: ---------- Capture Output ----------I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd.What are the errors you are seeing?"C:\dmd\bin\build.exe" Vector.d -clean\d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): cannot have parameter of type void \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(57): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(57): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(57): cannot have parameter of type void \d\import\velocity\math\Vector.d(67): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(67): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(67): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(67): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(67): cannot have parameter of type void \d\import\velocity\math\Vector.d(77): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(77): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(39): cannot implicitly convert expression (this.storage) of type int[2] to int \d\import\velocity\math\Vector.d(44): cannot implicitly convert expression ((this.storage)[(i)..(j)]) of type int[] to int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opAdd.a voids have no value \d\import\velocity\math\Vector.d(49): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(49): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(49): variable velocity.math.Vector.Vector!(int,2).Vector.opAdd.ret voids have no value \d\import\velocity\math\Vector.d(52): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(52): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opSub.a voids have no value \d\import\velocity\math\Vector.d(59): identifier 'Row' is not defined \d\import\velocity\math\Vector.d(59): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(59): Vector!(int,2,int) is used as a type \d\import\velocity\math\Vector.d(59): variable velocity.math.Vector.Vector!(int,2).Vector.opSub.ret voids have no value \d\import\velocity\math\Vector.d(62): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(62): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d: variable velocity.math.Vector.Vector!(int,2).Vector.opAddAssign.a voids have no value \d\import\velocity\math\Vector.d(69): identifier 'Row' is not defined \d\import\velocity\math\Vector.d(69): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(69): Vector!(int,2,int) is used as a type \d\import\velocity\math\Vector.d(69): variable velocity.math.Vector.Vector!(int,2).Vector.opAddAssign.ret voids have no value \d\import\velocity\math\Vector.d(72): ret must be an array or pointer type, not int \d\import\velocity\math\Vector.d(72): a must be an array or pointer type, not int \d\import\velocity\math\Vector.d(79): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(79): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(79): variable velocity.math.Vector.Vector!(int,2).Vector.opCall.v voids have no value \d\import\velocity\math\Vector.d(85): v must be an array or pointer type, not int \d\import\velocity\math\Vector.d(5): template instance velocity.math.Vector.Vector!(int,2) error instantiating Vector.d(6): voids have no value Vector.d(6): cannot implicitly convert expression ((opCall)((_arguments_ii),0,0)) of type void to Vector Vector.d(7): voids have no value Vector.d(7): cannot implicitly convert expression ((opCall)((_arguments_ii),1,1)) of type void to Vector Vector.d(8): function velocity.math.Vector.Vector!(int,2).Vector.opAdd (void) does not match argument types (Vector ) Vector.d(8): cannot implicitly convert expression (origin) of type Vector to void Vector.d(8): void has no value Vector.d(8): incompatible types for ((((a).opAdd)(cast(void)(origin))) == (a)): 'void' and 'Vector'Terminated with exit code 1.
Jan 24 2006
Agent Orange wrote:you cant create a struct templateDMD allows it, though the docs say it's illegal. Sean
Jan 24 2006
Sean Kelly wrote:Agent Orange wrote:But the doc also says its legal: template.html: "The body of the TemplateDeclaration must be syntactically correct even if never instantiated. Semantic analysis is not done until instantiated. A template forms its own scope, and the template body can contain classes, structs, types, enums, variables, functions, and other templates." /Oskaryou cant create a struct templateDMD allows it, though the docs say it's illegal.
Jan 25 2006
In article <dr70cq$f0j$1 digitaldaemon.com>, Sean Kelly says...Agent Orange wrote:Can you link to where you saw that... (After all, there are whole libraries built using struct templates and (obviously) supporting code in the reference compiler, so I think the docs. are wrong)? Just want to point it out to Walter so the docs. can be fixed. Thanks, - Daveyou cant create a struct templateDMD allows it, though the docs say it's illegal.Sean
Jan 25 2006
Dave wrote:In article <dr70cq$f0j$1 digitaldaemon.com>, Sean Kelly says...He may have already fixed them. I can't find the clause I remember seeing. SeanAgent Orange wrote:Can you link to where you saw that... (After all, there are whole libraries built using struct templates and (obviously) supporting code in the reference compiler, so I think the docs. are wrong)? Just want to point it out to Walter so the docs. can be fixed.you cant create a struct templateDMD allows it, though the docs say it's illegal.
Jan 25 2006
Kyle Furlong wrote:Mike Parker wrote:As mentioned elsewhere, you can't create a struct template. Anyways, here is a working (or at least somewhat working) version. opEquals wasn't implemented and I didn't test everything, I just got it to compile and made sure it was adding correctly. However the assert will fail since the opEquals isn't implemented. Also I implemented new instead of opCall since I wasn't sure why it was failing (I haven't really used opCall yet). I have a similar version that I'll post later... maybe some collaboration would be nice? Anyways, here it is // main.d import vector; int main(char[][] args) { alias Vector!(int,2) Point; Point origin = new Point(0, 0); Point a = new Point(1,1); assert((a + origin) == a); return 0; } // vector.d module vector; import std.c.stdarg; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ class Vector(T, int Dim = 4) { private T[Dim] storage; this(...) { for (int i = 0; i < _arguments.length; i++) { storage[i] = *cast(T*)_argptr; _argptr += T.sizeof; } } T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T[] opSlice() { return storage[]; } T[] opSlice(int i, int j) { return storage[i..j]; } Vector opAdd(Vector a) { Vector ret = new Vector(); for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector opSub(Vector a) { Vector ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector opAddAssign(Vector a) { Vector ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } // static Vector opCall(...) // { // Vector v; // // for (int i = 0; i < Dim; i++) // { // if (_arguments[i] == typeid(T)) // { // v[i] = *cast(T *)_argptr; // _argptr += T.sizeof; // } // else assert(0); // } // return v; // } }Kyle Furlong wrote:I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.
Jan 24 2006
As promised, here's my version of a 2-dimensional vector (I also have versions with 3 and 4 dimensions). Hmm... I'm also working on a game engine... //============================================================================= // Lucas Goss //============================================================================= module lge.math.vector2; import std.math; //============================================================================= class TVector2(T) { public: // Members ==================================================== //------------------------------------------------------------- const static TVector2 Zero; const static TVector2 UnitX; const static TVector2 UnitY; // Constructors / Destructors ================================= //------------------------------------------------------------- static this() { Zero = new TVector2(0, 0); UnitX = new TVector2(1, 0); UnitY = new TVector2(0, 1); } //------------------------------------------------------------- this() {} //------------------------------------------------------------- this(T x, T y) { this.mX = x; this.mY = y; } //------------------------------------------------------------- this(TVector2 vector) { mX = vector.x; mY = vector.y; } // Operators ================================================== //------------------------------------------------------------- TVector2 opNeg() { return new TVector2(-mX, -mY); } //------------------------------------------------------------- TVector2 opAdd(TVector2 vector) { return new TVector2(mX + vector.x, mY + vector.y); } //------------------------------------------------------------- TVector2 opSub(TVector2 vector) { return new TVector2(mX - vector.x, mY - vector.y); } //------------------------------------------------------------- TVector2 opMul(T scalar) { return new TVector2(scalar * mX, scalar * mY); } //------------------------------------------------------------- TVector2 opDiv(T scalar) { if(scalar != 0) { T invScalar = 1 / scalar; return new TVector2(invScalar * mX, invScalar * mY); } else { return new TVector2(T.max, T.max); } } //------------------------------------------------------------- TVector2 opAddAssign(TVector2 vector) { mX += vector.x; mY += vector.y; return this; } //------------------------------------------------------------- TVector2 opSubAssign(TVector2 vector) { mX -= vector.x; mY -= vector.y; return this; } //------------------------------------------------------------- TVector2 opMulAssign(T scalar) { mX *= scalar; mY *= scalar; return this; } //------------------------------------------------------------- TVector2 opDivAssign(T scalar) { if(scalar != 0) { T invScalar = 1 / scalar; mX *= invScalar; mY *= invScalar; } else { mX = T.max; mY = T.max; } return this; } //------------------------------------------------------------- int opEquals(TVector2 vector) { if(mX == vector.x && mY == vector.y) { return 1; } return 0; } // Properties ================================================= //------------------------------------------------------------- T x() { return mX; } //------------------------------------------------------------- T x(T value) { mX = value; } //------------------------------------------------------------- T y() { return mY; } //------------------------------------------------------------- T y(T value) { mY = value; } // Methods ==================================================== //------------------------------------------------------------- T dot(TVector2 vector) { return (mX * vector.x + mY * vector.y); } //------------------------------------------------------------- T dotPerpendicular(TVector2 vector) { return (mX * vector.y - vector.x * mY); } //------------------------------------------------------------- void getBarycentrics(TVector2 v0, TVector2 v1, TVector2 v2, T barycentric[3]) { // TODO } //------------------------------------------------------------- T length() { return sqrt(mX * mX + mY * mY); } //------------------------------------------------------------- T lengthSquared() { return (mX * mX + mY * mY); } //------------------------------------------------------------- TVector2 normalize() { T vectorLength = length(); if(vectorLength > 0) { T invLength = 1 / vectorLength; mX *= invLength; mY *= invLength; } else { mX = 0; mY = 0; } return this; } //------------------------------------------------------------- TVector2 perpendicular() { return new TVector2(mY, -mX); } // Static Methods ============================================= //------------------------------------------------------------- static void orthonormalize(inout TVector2 u, inout TVector2 v) { u.normalize(); T dot0 = u.dot(v); v -= u * dot0; v.normalize(); } //------------------------------------------------------------- static void orthonormalBasis(inout TVector2 u, inout TVector2 v, bit unitLengthV) { if(!unitLengthV) { v.normalize(); } u = v.perpendicular(); } private: // Members ==================================================== //------------------------------------------------------------- T mX = 0; T mY = 0; // Unittest =================================================== //------------------------------------------------------------- unittest { // Zero, UnitX, UnitY assert(Zero.x == 0 && Zero.y == 0); assert(UnitX.x == 1 && UnitX.y == 0); assert(UnitY.x == 0 && UnitY.y == 1); // this(), this(x, y), this(Vector2) TVector2!(float) v0, v1, v2; v0 = new TVector2!(float)(); assert(v0.x == 0 && v0.y == 0); v1 = new TVector2!(float)(1, 2); assert(v1.x == 1 && v1.y == 2); v2 = new TVector2!(float)(v1); assert(v2.x == 1 && v2.y == 2); // opNeg, opAdd, opSub, opMul, opDiv v1 = -v2; assert(v1.x == -1 && v1.y == -2); v1 = v2; v0 = v1 + v2; assert(v0.x == 2 && v0.y == 4); v0 = v1 - v2; assert(v0.x == 0 && v0.y == 0); v0 = v1 * 3; assert(v0.x == 3 && v0.y == 6); v0 = v1 / 2; assert(v0.x == 0.5 && v0.y == 1); // opAddAssign, opSubAssign, opMulAssign, opDivAssign v0 += v1; assert(v0.x == 1.5 && v0.y == 3); v2.x = 4; v2.y = 5; v2 -= v0; assert(v2.x == 2.5 && v2.y == 2); v1 *= 4; assert(v1.x == 4 && v1.y == 8); v1 /= 2; assert(v1.x == 2 && v1.y == 4); // opEquals v2.x = 2; v2.y = 4; assert(v1 == v2); // x, y v0.x = 1; v0.y = 1; v1.x = v0.x; v1.y = 2; v2.x = v1.y; v2.y = 0; // dot, dotPerpendicular, length, lengthSquared T result = v0.dot(v1); assert(result == 3); result = v0.dotPerpendicular(v1); assert(result == 1); result = v2.length(); assert(result == 2); result = v2.lengthSquared(); assert(result == 4); // normalize, perpendicular v2.normalize(); assert(v2.x == 1 && v2.y == 0); v0 = v1.perpendicular(); assert(v0.x == 2 && v0.y == -1); } } // Instantiated Templates //============================================================================= alias TVector2!(float) Vector2f; alias TVector2!(double) Vector2d; alias TVector2!(real) Vector2;
Jan 24 2006
Lucas Goss wrote:Kyle Furlong wrote:Thanks for the heads up. I'm still waiting for Don to weigh in, but does anyone know how I can get a templated initializer that would work as in the example code?Mike Parker wrote:As mentioned elsewhere, you can't create a struct template. Anyways, here is a working (or at least somewhat working) version. opEquals wasn't implemented and I didn't test everything, I just got it to compile and made sure it was adding correctly. However the assert will fail since the opEquals isn't implemented. Also I implemented new instead of opCall since I wasn't sure why it was failing (I haven't really used opCall yet). I have a similar version that I'll post later... maybe some collaboration would be nice? Anyways, here it is // main.d import vector; int main(char[][] args) { alias Vector!(int,2) Point; Point origin = new Point(0, 0); Point a = new Point(1,1); assert((a + origin) == a); return 0; } // vector.d module vector; import std.c.stdarg; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ class Vector(T, int Dim = 4) { private T[Dim] storage; this(...) { for (int i = 0; i < _arguments.length; i++) { storage[i] = *cast(T*)_argptr; _argptr += T.sizeof; } } T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T[] opSlice() { return storage[]; } T[] opSlice(int i, int j) { return storage[i..j]; } Vector opAdd(Vector a) { Vector ret = new Vector(); for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector opSub(Vector a) { Vector ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector opAddAssign(Vector a) { Vector ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } // static Vector opCall(...) // { // Vector v; // // for (int i = 0; i < Dim; i++) // { // if (_arguments[i] == typeid(T)) // { // v[i] = *cast(T *)_argptr; // _argptr += T.sizeof; // } // else assert(0); // } // return v; // } }Kyle Furlong wrote:I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.
Jan 24 2006
Kyle Furlong wrote:Mike Parker wrote:For future reference: Whenever you see 'void' in a template error message, it normally means there was a semantic error in a template. Especially look out for 'voids have no value'. These error messages don't tell you much other than "the compiler was compiling line 47 of Vector.d when it detected a problem with a template." Sometimes the error messages come out in a strange order; the fundamental problem might not show up until the fourth or fifth error message. Once there's an error in a template, the compiler will spew reams of unhelpful garbage; its common to have 100 error messages caused by a single typo. Although the first error is listed as line 47, that line could be perfectly OK, and the real error could be in another template which is being used in lines 46 or 47.Kyle Furlong wrote:With this test program: import velocity.math.Vector; int main() { alias Vector!(int,2) Point; Point origin = Point(0,0); Point a = Point(1,1); assert((a + origin) == a); } I get these errors: ---------- Capture Output ---------- > "C:\dmd\bin\build.exe" Vector.d -clean \d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): template instance Vector is not a template declaration, it is a struct \d\import\velocity\math\Vector.d(47): Vector!(int,2) is used as a type \d\import\velocity\math\Vector.d(47): cannot have parameter of type void \d\import\velocity\math\Vector.d(57): template instance Vector is not a template declaration, it is a structI'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.
Jan 25 2006
Kyle Furlong wrote:I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.There are just a few minor errors in your code. Find below some corrections inline. With those, the code compiles with DMD 0.144. Regards, Oskar------------------------------------------------------------------------ //| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice()T[] opSlice(){ return storage; } T opSlice(int i, int j)T[] opSlice(int i, int j){ return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret;Vector!(T,Dim) ret; // What is Row?for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret;Vector!(T,Dim) ret; // What is Row?for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } }
Jan 24 2006
Oskar Linde wrote:Kyle Furlong wrote:It compiles but when you try and use it in another module the compile fails.I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.There are just a few minor errors in your code. Find below some corrections inline. With those, the code compiles with DMD 0.144. Regards, Oskar------------------------------------------------------------------------ //| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice()T[] opSlice(){ return storage; } T opSlice(int i, int j)T[] opSlice(int i, int j){ return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret;Vector!(T,Dim) ret; // What is Row?for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret;Vector!(T,Dim) ret; // What is Row?for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } }
Jan 24 2006
Kyle Furlong wrote:Oskar Linde wrote:[snip]Kyle Furlong wrote:I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.There are just a few minor errors in your code. Find below some corrections inline. With those, the code compiles with DMD 0.144.It compiles but when you try and use it in another module the compile fails.With what errors? For me, it works as expected. I might have forgotten some fix. alias Vector!(int,2) Point; Point origin = Point(0,0); Point a = Point(1,1); Point b = Point(2,3); Point c = a + b; writefln("%s %s",c[0],c[1]); Prints 3 4 /Oskar
Jan 25 2006
Oskar Linde wrote:Kyle Furlong wrote:Can you attach a file with your version, the ng is making it difficult to see the differences.Oskar Linde wrote:[snip]Kyle Furlong wrote:I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.There are just a few minor errors in your code. Find below some corrections inline. With those, the code compiles with DMD 0.144.It compiles but when you try and use it in another module the compile fails.With what errors? For me, it works as expected. I might have forgotten some fix. alias Vector!(int,2) Point; Point origin = Point(0,0); Point a = Point(1,1); Point b = Point(2,3); Point c = a + b; writefln("%s %s",c[0],c[1]); Prints 3 4 /Oskar
Jan 25 2006
Kyle Furlong wrote:Can you attach a file with your version, the ng is making it difficult to see the differences.Of course. I should have done that from the start. I hope Unix line endings are OK. /Oskar
Jan 25 2006
"Kyle Furlong" <kylefurlong gmail.com> wrote in message news:dr6l90$5lu$1 digitaldaemon.com...I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated.See below for corrections that will enable D to compile your template.p.s. - Velocity is hosted at dsource. At the moment the license is tbd.--------------------------------------------------------------------------------//| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice() { return storage; }opSlice returns an array, not an element, so: T[] opSlice() { return storage; }T opSlice(int i, int j) { return storage[i..j]; }T[] opSlice(int i, int j) { return storage[i .. j]; }Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret;Vector opAdd(Vector a) { Vector ret;for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret;You haven't defined a 'Vector' template that takes three parameters. Vector opSub(Vector a) { Vector ret;for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret;Vector opAddAssign(Vector a) { Vector ret;for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } }static Vector opCall(...) { Vector v;
Jan 25 2006
You might want to take a look at my templated math module: http://158.75.59.9/~h3/tmp/maths.d -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y ------END GEEK CODE BLOCK------ Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jan 25 2006
Below is what it looks like you wanted (with comments), complete with a unittest. Compile with: dmd -unittest [-O -inline -release] myvector.d module myvector; void main(){} unittest { alias Vector!(int,2) Point; Point o = Point(10,30); assert(o[0] == 10 && o[1] == 30); o[0] = 20, o[1] = 40; assert(o[0] == 20 && o[1] == 40); int[] t = o[0..2]; assert(t[0] == 20 && t[1] == 40); t[0] = 100, t[1] = 200; int[] t2 = o[]; assert(t2[0] == 100 && t2[1] == 200); Point t3,t4,t5 = Point(30,10); t3 = o + t5; assert(t3[0] == 130 && t3[1] == 210); t4 += t5; assert(t4[0] == 30 && t4[1] == 10); } struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } // T opSlice() T[] opSlice() { return storage; } // T opSlice(int i, int j) T[] opSlice(int i, int j) { return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { // Vector!(T,Dim,Row) ret; Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { // Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { // ret[i] = storage[i] + a[i]; storage[i] += a[i]; } // return ret; return *this; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } } In article <dr6l90$5lu$1 digitaldaemon.com>, Kyle Furlong says...This is a multi-part message in MIME format. --------------020800040606050701090906 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd. --------------020800040606050701090906 Content-Type: text/plain; name="Vector.d" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Vector.d" //| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice() { return storage; } T opSlice(int i, int j) { return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } } --------------020800040606050701090906--
Jan 25 2006
Kyle Furlong wrote:I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd. ------------------------------------------------------------------------ //| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice() { return storage; } T opSlice(int i, int j) { return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } }Thank you all for your input. There is still some ambiguity though. Attached is my copy that works now, but some of you suggested keeping the methods in this form: Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Which didn't compile for me. Are there cases where this syntax will work? Or is it permissible to only use the struct name for returning the struct within the struct itself?
Jan 25 2006
Kyle Furlong wrote:Kyle Furlong wrote:Sorry attached the old one on accident.I just started work on Velocity, a game engine. I want the math module to use templated structs for vectors and matrices. Theses structs will overload the different operators (+,*,-)with fast assembly implementations of the operations. I'm running into some errors which I cant understand due to my shaky grasp of the language. Attached is what I have so far for the Vector struct; any pointers are appreciated. p.s. - Velocity is hosted at dsource. At the moment the license is tbd. ------------------------------------------------------------------------ //| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice() { return storage; } T opSlice(int i, int j) { return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } }Thank you all for your input. There is still some ambiguity though. Attached is my copy that works now, but some of you suggested keeping the methods in this form: Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Which didn't compile for me. Are there cases where this syntax will work? Or is it permissible to only use the struct name for returning the struct within the struct itself? ------------------------------------------------------------------------ //| //| ___ __ ______ __________ //| __ | / /_______ /______________(_)_ /_____ __ //| __ | / /_ _ \_ /_ __ \ ___/_ /_ __/_ / / / //| __ |/ / / __/ / / /_/ / /__ _ / / /_ _ /_/ / //| _____/ \___//_/ \____/\___/ /_/ \__/ _\__, / //| __/____/ //| Copyright (c) 2006 Kyle Furlong //| module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ class Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } T opSlice() { return storage; } T opSlice(int i, int j) { return storage[i..j]; } Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector!(T,Dim) opSub(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector!(T,Dim) opAddAssign(Vector!(T,Dim) a) { Vector!(T,Dim,Row) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } /* static Vector!(T,Dim) opCall(...) { Vector!(T,Dim) v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; }*/ }
Jan 25 2006
Change the second 'V' to 'v' in velocity.math.Vector and copy this code into 'main.d', then compile: dmd main.d vector.d main.d ------ import std.stdio, velocity.math.vector; alias Vector!(int,2) Point; void main() { Point origin = Point(10,10); writefln(origin[0],",",origin[1]); } ------module velocity.math.Vector; /************************************************** A fast vector implementation Examples: --- alias Vector!(int,2) Point; Point origin = Point(0,0); --- **************************************************/ struct Vector(T, int Dim = 4) { private T[Dim] storage; T opIndex(int index) { return storage[index]; } T opIndexAssign(T value, int index) { storage[index] = value; return value; } Vector opAdd(Vector a) { Vector ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Vector opSub(Vector a) { Vector ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] - a[i]; } return ret; } Vector opAddAssign(Vector a) { for(int i = 0; i < Dim; i++) { storage[i] += a[i]; } return *this; } Vector opSubAssign(Vector a) { for(int i = 0; i < Dim; i++) { storage[i] -= a[i]; } return *this; } static Vector opCall(...) { Vector v; for (int i = 0; i < Dim; i++) { if (_arguments[i] == typeid(T)) { v[i] = *cast(T *)_argptr; _argptr += T.sizeof; } else assert(0); } return v; } } --------------050605010104060809010402--
Jan 25 2006
In article <dr8oqj$2nqo$1 digitaldaemon.com>, Kyle Furlong says...Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Which didn't compile for me. Are there cases where this syntax will work? Or is it permissible to only use the struct name for returning the struct within the struct itself?Up until DMD version 0.143 this had to be written as: But with the latest version (0.144), the dot (.) before the template identifier is no longer necessary. (Its meaning was to refer to the Vector template in the outer scope rather than the Vector struct in the inner scope.) Within this single member template, Vector refers to the same thing as Vector!(T,Dim). /Oskar
Jan 25 2006
Oskar Linde wrote:In article <dr8oqj$2nqo$1 digitaldaemon.com>, Kyle Furlong says...Thanks for the explanation.Vector!(T,Dim) opAdd(Vector!(T,Dim) a) { Vector!(T,Dim) ret; for(int i = 0; i < Dim; i++) { ret[i] = storage[i] + a[i]; } return ret; } Which didn't compile for me. Are there cases where this syntax will work? Or is it permissible to only use the struct name for returning the struct within the struct itself?Up until DMD version 0.143 this had to be written as: But with the latest version (0.144), the dot (.) before the template identifier is no longer necessary. (Its meaning was to refer to the Vector template in the outer scope rather than the Vector struct in the inner scope.) Within this single member template, Vector refers to the same thing as Vector!(T,Dim). /Oskar
Jan 26 2006