Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 23 Oct 2003
Offline Last Active Private

#4641255 Prefixing names using some notation

Posted by on 29 April 2010 - 05:56 AM

Original post by YogurtEmperor
I feel I have made strong points, but there is no way to make everyone agree on this subject and taking it beyond this is too much of a waste of time (no really, look at how much I have typed in these last few posts!)
You're right that there's probably not going to be any agreement on this, and at this point, any further argument would probably just be repetition (there have been some arguments made against type prefixes - including counter-arguments to your arguments - that I don't think you've addressed or responded to in any of your posts, but I imagine repeating them again here probably wouldn't do much good).

I am going to throw out one more thing though. I'm a little embarrassed to admit that I spent time doing this, but I quickly looked through the source code of a fairly large selection of open-source libraries to see what sort of naming conventions they use. Some of these libraries are very well known and widely used, have very large code bases, and presumably have been worked on by many different developers over the years. Interestingly, only one of the libraries I looked at (out of about 20) uses type prefixes (as far as I can tell, at least).

Maybe I just got lucky and happened to randomly pick libraries that reinforce my own point of view. Or maybe type prefixes are more commonly used in closed-source projects or other code bases that I don't have access to. Another possible explanation though is that not that many people are using these sorts of naming conventions. If using type prefixes was 'the best' way to do things, wouldn't more of these projects be using such a convention?

Again, although I prefer no type prefixes, I think individuals/teams should use whatever works best for them, and I wouldn't presume to say that my preferred conventions are better than someone else's. Really, the only reason I've continued to post is that you seem to be arguing for type prefixes as 'the' right way to do things, which I disagree with. (Apologies if I've misinterpreted your arguments.)

#4531497 boost::intrusive_ptr problem

Posted by on 24 September 2009 - 12:26 AM

A couple of quick comments:
- I want to delegate the deletion of the object to a recycle bin. To do that with shared pointers, I'll have to override the delete() operator (which is ok).
- I need to recycle a lot of objects per frame, which are pulled back from that recycle bin.
You can do pooled allocation using shared_ptr as well, e.g. by using boost::pool and implementing operator new and operator delete on a per-class basis.
- No heap allocation required for the ref counter.
boost::shared_ptr has a (perhaps undocumented) feature, a define that turns on automated pooled allocation for ref counters (or at least that's my understanding). I'm not sure if this feature is offered by tr1::shared_ptr though.
- I can use the ref counter to signal an object manager an object is no longer referenced (ref counter == 1).
shared_ptr has a function called unique() which, I think, could be used to accomplish the same thing.

I'm not arguing against the use of intrusive_ptr at all, but I just thought I'd mention the above points about using shared_ptr, just in case.

#4517068 SDL or SFML?

Posted by on 27 August 2009 - 11:34 AM

There doesn't seem to be any clear consensus on this forum.
No, there isn't really - you'll probably just have to make a decision based on your own needs and preferences :)

Here are a few random points to help you along though:

1. SDL is a C API, while SFML is written in C++. You can certainly write object-oriented C++ code using SDL, but you'll most likely end up writing some wrapper code in the process.

2. SDL 1.2.x has been around for a while, and is fairly stable and mature. SFML is newer and is still under active development (AFAIK, at least). At least as of fairly recently though, the SFML forums were fairly active, and the developer(s) were quite quick to respond to bug reports and feature requests.

3. SDL 1.3 is somewhat more modern that 1.2.x in terms of the features it supports. However, I don't know that it's quite 'production-ready' yet.

4. SFML has better out-of-the-box support for sound than SDL. With SDL, you either have to write some low-level code, or use another library for sound. (SDL_mixer is easy to set up and use, but it has some quirks that can be a pain to work around.)

5. SDL 1.2.x vs. SFML isn't really a fair comparison; SDL 1.3 and SFML are closer to each other as far as feature sets are concerned. However, the impression I've gotten is that SFML may be a little more stable and/or mature than SDL 1.3. (I could be totally wrong about that though - that's just based on things I've read online and on my own admittedly limited experience with SDL 1.3 and SFML.)

If I were starting a new project from scratch right now, I'd probably give SFML a try (I use SDL currently). My only real reservation is that SFML uses OpenAL for sound, and I've read that OpenAL has some issues on certain platforms (this is just anecdotal though).

Anyway, hope that's of some help.

#4501034 Determine which side of a line a point is

Posted by on 30 July 2009 - 11:46 AM

I used the first technique.
Just for the record, the techniques are exactly the same, just written differently. Here's how to get from my version to ToohrVyk's version:
diff.x = Bx - Ax
diff.y = By - Ay
perp.x = Ay - By
perp.y = Bx - Ax

dot(p - p1, perp) =
(Cx - Ax) * (Ay - By) + (Cy - Ay) * (Bx - Ax) =
(Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax)

#4500668 Determine which side of a line a point is

Posted by on 30 July 2009 - 12:57 AM

You can determine which side of a line a point is on by converting the line to hyperplane form (implicitly or explicitly) and then computing the perpendicular (pseudo)distance from the point to the hyperplane.

Here's an example implementation (pseudocode, not compiled or tested):
int side(vector2 p1, vector2 p2, vector2 p)
vector2 diff = p2 - p1;
vector2 perp(-diff.y, diff.x);
float d = dot(p - p1, perp);
return sign(d);

#4479485 Best Game Engine for Indie Game?

Posted by on 25 June 2009 - 01:13 AM

You might also take a look at Unity, if you haven't already.

#4471558 Handedness

Posted by on 11 June 2009 - 05:49 PM

So the conclusion is I don't need to change anything..
Is that right? :)
No, not necessarily. As I mentioned earlier, you may have to make adjustments for the differing view space and projection transform conventions, and you may also have to make adjustments to your data so that the visual results are consistent between the two APIs.

There also may be cases where you'll need to take matrix layout and/or vector notation conventions into account (note however that despite the different conventions used, D3D and OpenGL matrices are actually arranged in memory the same way in that the elements of the basis vectors are stored contiguously).

#4471039 Handedness

Posted by on 11 June 2009 - 12:59 AM

Just a quick comment on the 'handedness' issue. Generally speaking, the (geometric) handedness of the coordinate system used should not affect your math library code (by which I mean code that constructs or manipulates vectors, matrices, quaternions, and so on). In other words (for example) a function that builds a rotation matrix or quaternion or computes the cross product of two vectors should be exactly the same regardless of the handedness of the coordinate system being used.

Projection transforms and 'view' transforms (e.g. a 'look at' transform) are exceptions in that they're generally constructed differently for left- and right-handed systems. The differences actually have to do with which direction is considered 'forward' in view space, but are also an indirect result of the coordinate system handedness and the convention that the positive x axis should point to the right in view space.

As for computing cross products, with a typical orthonormal basis the relationships between the vectors should be:
x = yXz
y = zXx
z = xXy
If you're seeing the arguments flipped around depending on handedness, you might be looking at a 'look at' function (where the flipping is related to which direction is to be considered forward in view space).

Even though most functions should be unaffected by handedness, you may find that the results of applying said functions change when switching handedness. For example, triangle windings may flip, models may be mirrored, and rotations may appear to go the 'wrong' way. In these cases though it's the input data that should be changed, not the functions that work with the data.

Also, keep in mind that the DirectX/D3D and OpenGL APIs differ in a few other ways as well, most notably matrix layout (row major vs. column major), vector notation (row vs. column vectors) and the near plane distance for the canonical view volume (zero vs. negative one). The issues of matrix layout, vector notation, and coordinate system handedness are often confused with each other, but in fact they are three separate and unrelated issues (although they can interact with each other in ways that can be quite confusing).

#4450531 Using gluLookAt() To Rotate Meshes

Posted by on 04 May 2009 - 06:32 PM

Try replacing this:
With this:
float m[16];
m[0] = Right.x;
m[1] = Right.y;
m[2] = Right.z;
m[3] = 0.f;
m[4] = Up.x;
m[5] = Up.y;
m[6] = Up.z;
m[7] = 0.f;
m[8] = ViewDir.x;
m[9] = ViewDir.y;
m[10] = ViewDir.z;
m[11] = 0.f;
m[12] = Position.x;
m[13] = Position.y;
m[14] = Position.z;
m[15] = 1.f;
And see if that fixes it.

In short, yes, you are abusing gluLookAt(), and that's (probably) why it isn't working as you expect. gluLookAt() doesn't just build a transform from the input eye, target, and up vectors, it builds an *inverted* transform. This is exactly what you want when setting up the view transform (because the goal is to transform the geometry into the local space of the camera), but it's not what you want when setting up a model transform.

#4400082 Moving object in OpenGL using WASD

Posted by on 11 February 2009 - 04:02 AM

Original post by KieranW
Actually TranslateX doesnt add to the position, it changes it to a new position so I needed to grab the current position and then add to that.

So if the player was at X:20 then I moved foward 1 unit I would need 20 + 1 to get to 21 otherwise I would be back at X:1
Oh, ok. The function names TranslateX() and TranslateY() are a little misleading then (in this context at least, a translation is generally considered to be a relative change in position).

#4332348 row/column-major confusion

Posted by on 13 October 2008 - 12:52 PM

Original post by bela
Thanks for your reply!

I'm trying hard but still don't get it. Given that the memory layout is the same, I don't see why one would have to transpose the matrices.
Could you please describe it in a bit more detail or point me to a paper that contains an explanation?

Thanks in advance,
The first step is to understand that there are two issues involved - matrix 'majorness' and vector notation convention - and they are orthogonal (that is, they are fully independent of each other).

The issue of vector notation convention is purely mathematical (that is, we can discuss it without any reference to or concern with the details of how a computer works). The choice to be made here is whether vectors are represented using column matrices (i.e. 'column vectors'), or using row matrices (i.e. 'row vectors').

Matrix-vector multiplication using row vectors looks like this:
[ x' y' ] = [ x y ][ a b ]
[ c d ]
While with column vectors it looks like this:
[ x' ] = [ a b ][ x ]
[ y' ] [ c d ][ y ]
This follows naturally from the definition of matrix multiplication (and has some additional implications involving the order in which transform matrices must be multiplied to achieve a given effect).

Now we can turn our attention to 'matrix majorness'. This really has nothing to do with math; it's purely a programming-related issue.

Basically, when presented with the problem of storing a matrix in memory, we have to decide whether to store it by rows, or by columns. If we store it by rows, we get something like this (the numbers indicate the location of the element in memory relative to the beginning of the memory block in which the matrix is stored):
[ 0 1 2 ]
[ 3 4 5 ]
[ 6 7 8 ]
Or, we can store by column, like this:
[ 0 3 6 ]
[ 1 4 7 ]
[ 2 5 8 ]
One other thing we have to factor in (I should have mentioned this earlier) is that transform matrices must be built differently, depending on whether they are intended to be used with row vectors or with column vectors. For example, a translation matrix that will be used with row vectors looks like this:
[ 1 0 0 0 ]
[ 0 1 0 0 ]
[ 0 0 1 0 ]
[ x y z 1 ]
While a translation matrix that will be used with column vectors looks like this:
[ 1 0 0 x ]
[ 0 1 0 y ]
[ 0 0 1 z ]
[ 0 0 0 1 ]
(I won't go into the 'why' of this, but please ask if it's not clear.)

So now we have two choices to make: matrix majorness, and vector notation convention. The two choices are (strictly speaking - we're not concerning ourselves here with practical issues such as vectorization and so forth) orthogonal; that is, any of the four combinations:
row major, row vectors
row major, column vectors
column major, row vectors
column major, column vectors
Is valid.

Now we can finally bring it all home. There are four possible combinations here, but we'll only concern ourselves with numbers 1 and 4, above, as these are the conventions used by DirectX and OpenGL, respectively. (There's probably some nuance here regarding whether OpenGL 'really' specifies a notational convention, but most OpenGL references use column vectors, which is good enough for our purposes.)

So, let's write out our translation matrix again, first row major with row vectors, and then column major with column vectors (on the left will be the matrix, and on the right will be the layout in memory):
[ 1 0 0 0 ]    [  0  1  2  3  ]
[ 0 1 0 0 ] [ 4 5 6 7 ]
[ 0 0 1 0 ] [ 8 9 10 11 ]
[ x y z 1 ] [ 12 13 14 15 ]

[ 1 0 0 x ] [ 0 4 8 12 ]
[ 0 1 0 y ] [ 1 5 9 13 ]
[ 0 0 1 z ] [ 2 6 10 14 ]
[ 0 0 0 1 ] [ 3 7 11 15 ]
As you can see, in each case the same location in memory corresponds to the same transform element, and this is why it is not necessary (in practice) to transpose a matrix when going from one API to another. All the API cares about is that the transform is laid out in memory in a certain way (specifically, that the elements of the basis vectors are contiguous).

Now, one might very well say that OpenGL and DirectX matrices are transposes of each other, but if so they would be speaking mathematically, not in terms of programming. If you were to write out a 'DirectX matrix', you would need to transpose it in order for it to 'look like' an OpenGL matrix, but this is a notation issue only; as far as the computer is concerned, they look the same.

This is all a bit confusing (and this took a long time to type!), so please post back if you have any further questions.

#4322114 Angle between two 3D points

Posted by on 27 September 2008 - 12:47 PM

Computing the pitch, yaw, and roll 'between two 3D points' doesn't really make any sense. Could you perhaps clarify what it is you're trying to do?

#4207941 Get Scale Factor From A Matrix

Posted by on 21 April 2008 - 01:12 PM

If you extract the quaternion from the matrix as-is, and the matrix incorporates a scaling, then I believe that the resulting quaternion will be incorrect.

To extract the scale, rotation, and translation from a matrix representing the series of transforms S->R->T:

1. Compute the scaling factors as the magnitudes of the first three basis vectors (columns or rows) of the matrix
2. Divide the first three basis vectors by these values (thus normalizing them)
3. The upper-left 3x3 part of the matrix now represents the rotation (you can use this as is, or convert it to quaternion form)
4. The translation is the fourth basis vector of the matrix (in homogeneous coordinates - it'll be the first three elements that you're interested in)

#4076502 decomposing rotation,translation,scale from matrix

Posted by on 08 October 2007 - 03:23 PM

If the transforms have been combined in the order Scale->Rotate->Translate, you can:

1. Compute the length of the first three basis vectors of the matrix - these are your scale factors.

2. Divide the first three basis vectors through by the scale factors to yield a pure rotation.

3. Extract the translation from the fourth basis vector, as you mentioned.

There are other methods that can be used as well, but the above should suffice for your typical SRT affine transform.

#3856228 Finding the Quaternion Betwee Two Vectors

Posted by on 21 December 2006 - 03:48 PM

Original post by Raghar
You should know I side with Diana, when someone talks about that four element monstrosity.
IMO rejecting quaternions as unuseful (or, conversely, touting them as a panacea for all rotation-related ills) is not very well informed.

Also, don't believe everything you read online about quaternions: much of it is confused, misguided, or simply incorrect.

@The OP: There's actually a very nice algorithm for finding the quaternion that rotates one vector onto another that has a couple of advantages over the 'standard' method, namely that it works with vectors of arbitrary length, and that it handles uniformly (and robustly) the case where the vectors are aligned and nearly parallel.

Here's the algorithm in pseudocode:
quaternion q;
vector3 c = cross(v1,v2);
q.v = c;
if ( vectors are known to be unit length ) {
q.w = 1 + dot(v1,v2);
} else {
q.w = sqrt(v1.length_squared() * v2.length_squared()) + dot(v1,v2);
return q;