First of all I'd like it if we all prove eatcomics wrong:
Now I've been trying to calculate my own crap in EQ for matrix transformations and such. Now I've got translation and scaling however I'm having a slight problem calculating my rotation.
It will change it's position as it rotates and that is what is happening.....So.....Am I missing something obvious?
This is a very simple problem. When drawing in OpenGL using immediate mode or anything else for that matter, to perform rotation/scaling, you have to do it from the center point of the object. glTranslatef() moves you to the center of the whatever you're going to draw, and you do the rotation and scaling from after that translation. Without doing so, you end up scaling/rotating the entire scene from the last center given. If you just happen to be using Ortho, everything drawn will rotate off of 0.0f, 0.0f, unless set otherwise.
That may be your only problem, because your math for all of this seems like it would work fine .
Re: Rotation
Posted: Sun Mar 27, 2011 2:53 pm
by qpHalcy0n
Yes, you are missing something. Matrix multiplication is not commutative.
For a matrix A and B. AB != BA
Furthermore, depending on the nature of the rotation desired, you may need to translate to the common or world origin to obtain your rotation. You must do this for rotations about the object's common origin. So if you have some model that you want to rotate around its own axis, you must first translate to the world origin, rotate, then translate back.
The final concatenation for rigid body transforms (eliminated shears to keep it simple) is:
X = T(t)T(c)RST(-c)
Here the matrix multiplication happens in reverse order. A Translation to the world origin is performed first ( T(-c) ), followed by a scale (S), then a Rotation (R), then a final desired translation (T(c) and/or T(t)).
Re: Rotation
Posted: Sun Mar 27, 2011 3:14 pm
by Ginto8
N64vSNES, I'd like to point out a little something about what you're doing: it's terribly inefficient for most things. Although I know that you're probably not doing enough of it for a big performance hit, you're putting a lot of load on the CPU that the GPU can (and really, is designed to) take. Although I do understand that reinventing the wheel is a great way to understand the wheel, on a big project this can cause serious performance hits. GL provides its matrix transformation functions because it stores its own GPU-side matrix anyway, so why not let the GPU handle its transformations too? You probably won't have to worry about it with EQ, but keep it in mind for when you're working on more graphically complex projects.
Re: Rotation
Posted: Sun Mar 27, 2011 3:26 pm
by qpHalcy0n
I would like to note that the OpenGL driver will not perform matrix operations on the GPU. These (glMultMatrix, glTranslate, glRotate, etc...) are all implemented on the CPU because of the relative frivolousness of the calculation. The driver detects and is free to make use of SSE optimized routines where available but are still all taking place on the CPU.
To be clear, the vertex T&L (Vertex transform & lighting) is what occurs on the GPU. The state matrices are pushed as part of the current state in finality during draw calls and so the vertices are transformed by GPU hardware, not the matrices.
Re: Rotation
Posted: Sun Mar 27, 2011 3:27 pm
by N64vSNES
Ginto8 wrote:N64vSNES, I'd like to point out a little something about what you're doing: it's terribly inefficient for most things. Although I know that you're probably not doing enough of it for a big performance hit, you're putting a lot of load on the CPU that the GPU can (and really, is designed to) take. Although I do understand that reinventing the wheel is a great way to understand the wheel, on a big project this can cause serious performance hits. GL provides its matrix transformation functions because it stores its own GPU-side matrix anyway, so why not let the GPU handle its transformations too? You probably won't have to worry about it with EQ, but keep it in mind for when you're working on more graphically complex projects.
Sure I understand what you're saying.
But I need the vertices locations after rotation for collision between oriented bounding boxes (can't be bothered to spell it's name).
So I *could* just recalculate the vertices positions after I let OpenGL rotate them but I figure that would just put a equal amount of stress on the CPU right?
Oh and I actually boosted my frame rate by doing this with the transformations so....wtf?
edit:
WE'RE NOT GOING THERE!
Re: Rotation
Posted: Sun Mar 27, 2011 3:30 pm
by eatcomics
7 pages
Edit: I pointed this out to him xD
Re: Rotation
Posted: Mon Mar 28, 2011 9:13 pm
by Falco Girgis
Ginto8 wrote:N64vSNES, I'd like to point out a little something about what you're doing: it's terribly inefficient for most things. Although I know that you're probably not doing enough of it for a big performance hit, you're putting a lot of load on the CPU that the GPU can (and really, is designed to) take. Although I do understand that reinventing the wheel is a great way to understand the wheel, on a big project this can cause serious performance hits. GL provides its matrix transformation functions because it stores its own GPU-side matrix anyway, so why not let the GPU handle its transformations too? You probably won't have to worry about it with EQ, but keep it in mind for when you're working on more graphically complex projects.
qp and I actually had a gigantic conversation about this the other day. Very enlightening (for me, haha). Yeah, I also wanted to point out that this is incorrect (as qpHalcy0n already has).
Notice that you can save/retrive the modelview or projection matrices at any time? There is no way that you are literally grabbing shit off of the PCI-E bus at random like that.
As qp said, in a fixed function pipeline, that shit is happening on the CPU (with SSE hardware acceleration, when available).
And not only that, but you can do plenty of things BETTER than OpenGL even with a shitty matrix implementation. There are many special case affine matrix transforms such as the universal "instance" matrix (scale, rotate, translate) that are being calculated dynamically and inefficiently on the fly by OpenGL. When you do:
OpenGL is literally performing 3 matrix multiplications to give you a single matrix that you can easily instantiate all at once.
"Outperforming" is not just a matter of raw number crunching. It has to do with how general-purpose the OpenGL matrix stack is, and how it makes absolutely no assumptions about your transforms. YOU can make these assumptions, and save some 4x4 matrix multiplies.
Re: OpenGL Rotation
Posted: Tue Mar 29, 2011 6:03 pm
by N64vSNES
Thanks guys I've got quite a education now and I've still achieved my mail goal...kinda
I decided to post here instead of make another thread (Seems silly since it's on the same topic really)
Going waaaaaay back I was trying to do this myself so I can get vertex locations and attempt *gulp* oriented rectangles collision detection.
Result:
I've not found much on the subject so I'm probably going at this at completely the wrong approach but here is how I'm doing it:
I have three functions to return booleans for now:
bool Eternal::IsOrientedCollision(BoundingBox *a, BoundingBox *b) {
int i_minX = 0, i_minY = 0, i_maxX = 0, i_maxY = 0;
float last = a->GetVert(0).x;
// Far left
for ( int i = 1;i < 4;i++ ) {
if ( a->GetVert(i).x < last ) {
last = a->GetVert(i).x;
i_minX = i;
}
}
// Far right
last = a->GetVert(0).x;
for ( int i = 1;i < 4;i++ ) {
if ( a->GetVert(i).x > last ) {
last = a->GetVert(i).x;
i_maxX = i;
}
}
// Far top
last = a->GetVert(0).y;
for ( int i = 1;i < 4;i++ ) {
if ( a->GetVert(i).y < last ) {
last = a->GetVert(i).y;
i_minY = i;
}
}
// Far bottom
last = a->GetVert(0).y;
for ( int i = 1;i < 4;i++ ) {
if ( a->GetVert(i).y > last ) {
last = a->GetVert(i).y;
i_maxY = i;
}
}
bool left_y = false, right_y = false, bottom_y = false, top_y = false;
if ( b->r == 0 ) {
if ( a->GetVert(i_minX).x < b->x + (b->w/2) ) {
left_y = true;
}
if ( a->GetVert(i_maxX).x > b->x - (b->w/2) ) {
right_y = true;
}
if ( a->GetVert(i_minY).y < b->y + (b->h/2) ) {
top_y = true;
}
if ( a->GetVert(i_maxY).y > b->y - (b->h/2) ) {
bottom_y = true;
}
}
else {
}
printf("left vert- %i\nright vert- %i\nBottom vert- %i\nTop vert- %i\n\n",i_minX,i_maxX,i_maxY,i_minY);
if ( left_y && right_y && top_y && bottom_y ) {
return true;
}
return false;
}
Doesn't support the second rectangles orientation right now but whatever. So from the little I could find on this topic you have to get the vertex locations and "project" them so you find a overlap like so:
So....Help?
EDIT:
Just in case you miss the problem, look near the end of the video and it detects a collision under weird circumstances.
Re: OpenGL Rotation
Posted: Tue Mar 29, 2011 7:14 pm
by GroundUpEngine
N64vSNES wrote:
Result:
That's not a bad attempt
Re: OpenGL Rotation
Posted: Tue Mar 29, 2011 9:19 pm
by Ginto8
the weird circumstances are because it's seeing an overlap on the X axis, and taking that as meaning it's colliding. Avansc did a VERY good tutorial on the SAT here: http://elysianshadows.com/phpBB3/viewto ... art=999999. One thing that might interest you is that the axis that separates two convex polygons is always perpendicular to one of the edges (ie. like _|_ where the __ is the edge and | is the axis), so if you project the polygons onto each edge, you'll cover every possible axis.
Re: OpenGL Rotation
Posted: Tue Mar 29, 2011 9:36 pm
by Falco Girgis
Your "projections" are incorrect. You're missing a fundamental linear algebra concept here.
n64vsnes wrote:
Your axis-aligned "projection" is correct, but your oriented one is NOT a projection. You're merely taking one component of each vertex.
You need to learn about vector projections. You're supposed to be taking the dot product of each of your geometry's vertices with each of its axes to "project" each vertex onto a direction vector.
The reason that your axis-aligned case works correctly (and you are able to remain ignorant of linear algebra) is that taking the dot product of any vertex with the x or y axis essentially drops a vector component since one of its components is multiplied by zero.
Vector Projection onto the X axis:
X axis = <1.0, 0.0>
Vector = <3.0, 4.0>
Whadya know? It's like you dropped the y component... because that's what you did. You had no idea you were actually taking a dot product there...
Re: OpenGL Rotation
Posted: Thu Mar 31, 2011 2:34 pm
by Falco Girgis
You figured it out, yet? I'd be glad to help.
1) Look at avansc's article
2) Watch my first video tutorial (2D vectors/linear algebra)
3) Watch Kendall's education in ESRev1, where she discusses the algorithm on a whiteboard.
Keep in mind that you are projecting onto each axis OF EACH POLYGON. In the case of AABBs and OBBs, (since they are both parallelograms), there are only 4 axes to project onto (2 for each object), because two sides of a a rectangle are axis-aligned with two other sides. Since you are normalizing these axes, they are literally the same (save yourself the math).
Get your ass to work.
Re: OpenGL Rotation
Posted: Thu Mar 31, 2011 3:48 pm
by N64vSNES
GyroVorbis wrote:You figured it out, yet? I'd be glad to help.
1) Look at avansc's article
2) Watch my first video tutorial (2D vectors/linear algebra)
3) Watch Kendall's education in ESRev1, where she discusses the algorithm on a whiteboard.
Keep in mind that you are projecting onto each axis OF EACH POLYGON. In the case of AABBs and OBBs, (since they are both parallelograms), there are only 4 axes to project onto (2 for each object), because two sides of a a rectangle are axis-aligned with two other sides. Since you are normalizing these axes, they are literally the same (save yourself the math).
Get your ass to work.
I've spent the past two days doing those exact three things!
I think I'm understanding how the polygons are getting projected a lot better now as at first I was being a idiot and thinking about projecting 8 times instead of 4 (because two faces of a 4 face polygon is parallel) and I wasn't thinking about projecting to a perpendicular axis.
I've drawn some diagrams and I can see how it's working now but getting it down in actual code is a struggle, for example:
Here is two oriented rectangles with a perpendicular axis:
I have no idea how I should calculate that axis (blue line) and when projecting the polygons I'm confused to why that line makes a difference?
I think I might be trying to overcomplicate this actually
I'm going to read avansc's thread again.
Re: OpenGL Rotation
Posted: Thu Mar 31, 2011 5:37 pm
by dandymcgee
N64vSNES wrote:
I have no idea how I should calculate that axis (blue line) and when projecting the polygons I'm confused to why that line makes a difference?
The blue line is correct, but the green ones are not. You're not projecting along the y-axis, you're projecting onto the blue line.
obb.png (6.65 KiB) Viewed 2135 times
This would be the projection on one of the axes. There are four axis total you need to project them onto. As Falco already pointed out, you don't understand what a projection onto an axis is. Go check out the resources he gave you.