Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 22 Aug 2001
Offline Last Active Mar 07 2016 04:10 AM

Posts I've Made

In Topic: [C++]Need help with a customer & salesman question.

15 February 2016 - 08:17 AM

Nobody mentioning the bug in printf (and how it probably shouldn't be used in the first place)?


%ld = long, but the variable is int. This will work great, until you build that code as a 64bit build on Unix, where a long is 64bit and int is 32bit. Most compilers should even warn about this.


Either use %d or (safer) use cout instead of printf.

In Topic: NonCopyable everywhere ?

29 October 2015 - 11:29 PM

The main reason is usually doing things like having "new" in the constructor and "delete" in the destructor. Any accidental temporary copy would typically cause a double delete eventually (or worse, leave your original with an invalid pointer for a long time, only crashing much later and being a real pain to debug).


One solution is explicitly deleting all problem operations (assignment, copy construction, etc.)


A typically better solution is to properly express your ownerships by using the correct smart pointer. In the above case, use a unique_ptr instead of a raw pointer and suddenly code that would accidentally (or intentionally) copy or assign won't compile. Problem solved without messing about with deleting default functions. If data should be shared, use a shared_ptr and data is automatically deleted at the proper point. In both cases, you don't need to worry about manually deleting anything.


Just making literally everything noncopyable for no good reason would simply look like unreflected cargo cult programming (yes, it's a thing and scarily common).

In Topic: Problem when compiling SFML game with Code::Blocks

26 August 2015 - 10:12 PM

That's exactly the same problem, except you apparently changed from static linking to dynamic linking. All your changed build option did was to move the error from compile time to run time.

SFML is trying to call a function that is missing in your version of the standard library. The first step when you get linker errors about stuff being undefined is to copy paste the error (or at least the symbol it complains about) into a search engine (unless you already know which library or source file contains the missing code). All results are the same: you need at least GCC 4.9.

From the fact you HAVE SFML libraries and the error you see now, I would assume you didn't build SFML yourself and just grabbed some pre-built binaries. Those were built with a newer version of GCC and the simplified issue is: it's not compatible with yours (technically the problem is more with the different standard library versions).


Since you're on Windows anyway and struggling with very common compiler/linker errors: why are you adding the extra pain and complexity of using an IDE that uses MinGW instead of some Visual Studio Express or Community version? Dealing with the extra issues from potentially outdated GNU ports for Windows is not something I'd do without a very good reason.

In Topic: Quaternions for FPS Camera?

19 August 2015 - 10:22 AM

Just quickly going over it:
Yes, when you move (especially along local axes), your orientation is relevant.
You won't get anywhere with just your cameras position. A direction means you have a "from" and a "to". To get a view vector from your camera position, you ALSO need the position of whatever you want to look at. If you use a rotation matrix to store the camera orientation, your view vector has nothing to do with the position and is typically the "forward" part (ie. the third column of your rotation matrix).
I think one problem might be that you don't know what to do with those values you are trying to compute. So the basic question before all others is: how do you intend to set up your view? Will you add the view matrix to the transformation stack, specify it separately through an API call or do you plan to use some helper function like "lookAt"?
Uhm, yes. East should be west. That was me being directionally challenged.
If you don't plan to write your own shaders, the w coordinate shouldn't be something to worry about.
Matrices are a bit painful to display (there's also lots of arbitrary decisions that can be made by the API, engine, or yourself). Usually, the matrix is stored as an array of 16 values, the first four being the first column, the next four being the second, etc. The "mathematical" representation would look something like this (with r=right, u=up, f=forward, p=position):
r.x | u.x | f.x | p.x
r.y | u.y | f.y | p.y
r.z | u.z | f.z | p.z
0   | 0   | 0   | 1
Of course you might use completely different conventions. In a top-down game, the y-axis might be forward and z would be up.
If movement is going the wrong way, try moving along different axes. Chances are you're simply not looking at the object from the direction you think are. With a right handed coordinate system, "forward" is -z, but the default is the identity matrix (so your camera wouldn't be facing "into" the screen by default, but out of it).
From a camera perspective, things are always moving and turning the other way. If you move a camera up, it looks like the world is moving down, if you turn it left, it looks the world is spinning to the right, etc. Of course it would be absurd to manually apply that to every single object, but depending on your API/framework, that's what happens automatically. In DX you set the view matrix and the default shader will always multiply it with the objects transformation matrix (ObjectMat * ViewMat).
Well, how would you rotate without a vector (or in this context: axis)? Rotating "left" or "clockwise" without an axis is meaningless. It might seem to make sense to you, because you assume a context where you deal with a standing person or vehicle. The axis you rotate around is the one thing not affected by the rotation (except for your position). If you picture sticking a pencil into your head so that when you turn it always points in the same direction, you will soon realize you're rotating around your "up", aka local y-axis, aka (0,1,0)... (or "down", if you flip the axis and invert the angle it's the exact same thing).
What might help a lot in visualizing things is to grab any 3D modelling software of your choice. Most of them will always display the objects local coordinate system as three color coded arrows sticking out from it. If you get used to thinking of everything in your scene to have these arrows and how each arrow is one column of the transformation matrix, things should become a lot more intuitive. Just think of the camera as one more invisible object and don't worry about the whole "inverse matrix" while modifying or placing it. Treat it as a separate step at the end of everything else.

In Topic: Quaternions for FPS Camera?

19 August 2015 - 01:20 AM

You seem to be confused about the difference between points and vectors and what's supposed to be what (or your naming is just really misleading). (0,0,0) is NOT a useful vector. It has zero length. It has no real direction. It can't be rotated and nothing can be rotated around it. If it's your camera position, it is the one thing that has no business being involved in any of your rotations, because an objects position is irrelevant and separate from its orientation.


Generally, when people are talking about a "view vector", they mean the direction your camera is pointing at (also typically normalized to be unit length).


With all the 0s in your code, I'd expect either that absolutely nothing happens or that the result is completely unpredictable and undefined (try normalizing a zero length vector).


Your first step should be to get an understanding of what you're trying to do and visualize it.


Step one:

Forget you ever heard the word "quaternion". Seriously, if you're a beginner and still trying to wrap your head around rotations and how to get a grip on the camera, 4-dimensional complex numbers should never ever enter the equation at any point. For your task, they offer zero benefit, are most likely less efficient due to all the conversion between matrices and quats and will just add a pointless extra layer of confusion and complexity. Suggesting quats for a simple FPS camera is like telling someone who struggles with a ray-triangle test "you must haz Plücker coords, them's the only way.. you won't understand the underlying math (I didn't), so just copy/paste some code, then go forth and spread the gospel of the one and only true and almighty Plücker" (yes, that's basically the impression I get with everybody immediately telling people to use quats whenever a topic remotely involves rotations).


They are neat and very useful in some cases, but they should still be considered a specialized tool. You wouldn't use a power drill to get a nail into the wall, just because both jobs involve putting a longish piece of metal into a hole.


Step two:

Understand transformation matrices. They aren't mysterious black boxes that magically make graphics happen. In fact, they are by far the easiest representation to visualize an objects orientation in your head (easier than quats and definitely easier than Euler angles). The three columns are literally nothing but your objects right/up/forward vectors. Creating any orientation that only involves 90° (or even 45°) steps is easy enough to not require a single bit of calculation (not that this would ever be useful in practice, just making a point).


Case in point, rotating 90° to the left means "right" is now pointing "north", "up" is still.. uhm.. "skywards" and "forward" is pointing "east" and your position didn't change (let's assume at the origin), ie. the columns are (0,0,-1,0), (0,1,0,0), (-1,0,0,0), (0,0,0,1). If the fourth coordinate (w) confuses you, don't worry about the math and just pretend w=0 means "direction" and w=1 means "position". There are generally no other values (at least not in places you care about anytime soon).


Step three:

There is no camera. A camera is just a nice concept to help picturing stuff in your mind. When it comes down to the math, you just move everything the opposite way of your imaginary camera. Still, just treat that imaginary camera like any other object in your scene until you set the view matrix as the opposite of it. What is used to apply the opposite of a transformation? The inverse matrix. What's neat about a typical camera matrix? No scaling or shearing, so there's a simple and efficient way to invert it (though for now, just use whatever inverse function your math library is offering).


Step four:

Multiplication order. To not get hopelessly confused or just stubbornly following a "you must always multiply matrices THIS way"-mantra, understand the difference between R*M and M*R. Say R is a rotation around the x-axis (1,0,0). Typically, matrix multiplications are applies right to left. If you used the deprecated OpenGL functions, "rotate" would result in R*M and apply the rotation AFTER all previous transformations (using the local coordinate system, which leads to confusing claims about OpenGL applying transformations in "reverse order" by people insisting on thinking in global terms).


Doing M*R means you apply R before other transformations, back when your objects axes were still identical to the worlds axes. Meaning: it rotates around the global x-axis. R*M on the other hand applies it last, so the x-axis you rotate around is whatever is "right" after all the other transformations. I prefer thinking in local coordinates, because unless you're writing an editor or deal with external forces in your physics simulation, you don't care about what's "north" or "west", you care about what's "forward" and what's "right" from your objects point of view. If you want to strafe to the side, you don't want to do pointless calculations to figure out what "right" is. It's right there in the first column of your objects transformation matrix. You also don't care, you simply apply a translation along (1,0,0) by doing T*M (and not the other way around). Later you will get rid of wasteful matrix multiplications for a simple translation, but understanding first, making it work second and making it efficient once you know what you're doing.



A few simple kinds of "disembodied" cameras:



-Store a position vector

-Store two angles for left/right and up/down

-Limit up/down to values

-Create camera transformation: M = rotateAroundX(up/down) * rotateAroundY(left/right) * translation

-Invert, orthonormalize and set as view matrix (you can do the inversion implicitly like Norman Barrows by inverting all signs and the multiplication order, but the idea is picture what's going on, not to optimize).


Third person:

-Store two angles for left/right and up/down

-Store a distance to the observed object

-Limit up/down to values

-Create camera transformation: M = translateBackwards(distance) * rotateAroundX(up/down) * rotateAroundY(left/right) * translation(position of observed object)

    -"Backwards" depends on your coordinate system. with a right handed system most likely (0,0,1).. I prefer left handed, since positive z being forward is more intuitive

-Invert, orthonormalize and set as view matrix


Free camera (think flight simulator):

-Store the whole matrix as one (4x4)

-Add transformations depending on input each frame (do NOT reset the matrix at any point)

     -Do it in local terms (ie. forward is translation(0,0,-1) * M, pitch (up/down) is rotation(1,0,0, angle) * M, etc.)

     -Order of multiple transformations not relevant within frames. While the results are different, changes between frames should be very small and it won't matter much.

-Orthonormalize, invert and set as view matrix


Note that the "normalize" part comes first in this last case. Accumulating all the transformations will add more and more floating point issues and screw up the matrix over time, so it should be "repaired" from time to time (fix axes to be orthogonal to each other and normalize the them to be unit length... don't touch the last column, which is the translation/position).


Those are not be the most efficient, fancy or flexible methods, but they should involve the least effort and are the most trivial ways to achieve a trivial goal that I can think of. Also, if there is one part of your engine where performance usually doesn't matter, it's the camera that is only set up once every frame anyway.