portal-portal rotation

Started by
15 comments, last by adam17 17 years, 6 months ago
Notice please that the transformation I've suggested means the following: Something that is given in the same co-ordinate system (usually the global space) as the 2nd portal's frame is, is converted into the local co-ordinate system of portal 2 and then converted back to the co-ordinates (again usually the global space) portal 1 is given in by using the frame of portal 1. By "switching" the local reference frame in-between these steps a re-interpretation of the space is done! It simulates the things being moving from the one portal to the other.

E.g. lets assume the example you've given above. Now, a point at the global co-ordinates [0,3,2]T is located 3 length unit in front of the second portal. This is because [0,1,0]T is the normal of the second portal; multiplied with 3 length units in this direction, and added to the location [0,0,2]T of portal 2 yields in just that [0,3,2]T.

Now, that point should be seen throught portal 1. Hence, applying the transformation in total
T1 * R1 * R2-1 * T2-1 * [ 0   3   2 ]T
Doing this stepwise from right to left for clarity means
(1) a := T2-1 * [ 0   3   2 ]T
  [ 1 0 0 0 ]-1   [ 0 ]   [ 1 0 0  0 ]   [ 0 ]   [ 0 ]= [ 0 1 0 0 ]   * [ 3 ] = [ 0 1 0  0 ] * [ 3 ] = [ 3 ]  [ 0 0 1 2 ]     [ 2 ]   [ 0 0 1 -2 ]   [ 2 ]   [ 0 ]  [ 0 0 0 1 ]     [ 1 ]   [ 0 0 0  1 ]   [ 1 ]   [ 1 ]

(2) b := ( R1 * R2-1 ) * a
  [ 0 0 1 0 ]   [ 0 ]   [ 0 ]= [ 1 0 0 0 ] * [ 3 ] = [ 0 ]  [ 0 1 0 0 ]   [ 0 ]   [ 3 ]  [ 0 0 0 1 ]   [ 1 ]   [ 1 ]

Here can already be seen that the point's "in front of" has changed to the global z axis!

(3) T1 * b
  [ 1 0 0 0 ]   [ 5 ]   [ 5 ]= [ 0 1 0 0 ] * [ 0 ] = [ 0 ]  [ 0 0 1 0 ]   [ 0 ]   [ 3 ]  [ 0 0 0 1 ]   [ 1 ]   [ 1 ]

Exactly what I would expect. Althought the point is actually located 3 units in front of portal 2, it appears to be 3 units in front of portal 1!

[Edited by - haegarr on September 30, 2006 7:02:57 AM]
Advertisement
Quote:Original post by adam17
im still struggling with the matrices and all but i had a stroke of genius!

:)

Quote:Original post by adam17
i take the 2 normals of the portals and find the dot product. then i take the cross product of the 2 normals, and rotate the scene around the cross product! i think it will work....

That is in fact the way usual when 1 vector should be rotated onto another one.

Quote:Original post by adam17
EDIT: it works, but the dot product is not oriented correctly. its only 0 <= theta <= pi. i need something for 0 <= theta <= 2pi

Yes, and no. Notice please that exchanging the arguments of the cross product will negate the result. This means that there is another "degree of freedom", allowing you to rotate either up to 180° in CW direction but also up to 180° in CCW direction, making a total of 360°!

However, using this method and a following pivot axis/angle to matrix conversion is just another way to compute
R1 * R2-1
and hence is a valid substitute for computing the up and right vectors and building the inside matrix product, but doesn't change the overall algorithm.
woohoo! i was thinking about how the cross product would negate the angle last night, but i wasnt too sure about it. today the inverse matrix finally clicked and made sense!

unfortunately there must be a bug in my code, because nothing is rendering correctly. take a look:

for(size_t i=0; i<portals.size(); i++){	glPushMatrix();	//get position of second portal	Vector3 trans1 = objects[objects[portals].portal.linkPortalLoc].portal.pos;	//get position of first portal	Vector3 trans2 = objects[portals].portal.pos;	//get normal of first portal	Vector3 norm1 = objects[portals].portal.normal;	//get normal of second portal	Vector3 norm2 = objects[objects[portals].portal.linkPortalLoc].portal.normal;	//get the cross product of the two normals	Vector3 cross = Cross(norm1, norm2);	//...angle	GLfloat	angle = (180/3.1416) * Dot3(norm1, norm2);										glTranslatef(-trans1.x, -trans1.y, -trans1.z);	glRotatef(angle, cross.x, cross.y, cross.z);	glTranslatef(trans2.x, trans2.y, trans2.z);	//render scene in portal	glPopMatrix();}


this is a basic idea of how it renders. the blue and red symbols are the actual portals. the light red and light blue symbols are what the portals are showing:


i am a little worried about my math functions for the cross product and the dot product. i keep checking them but im not seeing anything wrong. there are several different ways of achieving the cross product

Vector3 Cross(Vector3 v1, Vector3 v2){	Vector3	temp_vector;	temp_vector.x = (v1.y * v2.z) - (v1.z * v2.y);	temp_vector.y = (-v1.x * v2.z) + (v1.z * v2.x);	temp_vector.z = (v1.x * v2.y) - (v1.y * v2.x);	return temp_vector;}float Dot3(Vector3 vector1, Vector3 vector2){	float p1;	float p2;	p1 = (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z);	p2 = Magnitude(vector1) * Magnitude(vector2);	return acos(p1/p2);}


[Edited by - adam17 on October 1, 2006 2:13:50 AM]
The dot product is just
float Dot(Vector3 v1, Vector3 v2){ return (v1.x*v2.x)+(v1.y*v2.y)+(v1.z*v2.z);}
Not looked at the rendering code yet, but at the math code snippets:

Quote:Original post by adam17
i am a little worried about my math functions for the cross product and the dot product. i keep checking them but im not seeing anything wrong. there are several different ways of achieving the cross product

The cross product seems me correctly implemented. AFAIK OpenGL's glRotate normalizes the vector, so you don't need to do so by yourself.

The other routine seems me correct as well, but it doesn't implement the dot product and hence shouldn't be named so. It implements the computation of the angle between 2 vectors, and hence you may take into account to declare it as
float angleBetween(Vector a, Vector b);
or something similar instead.
I'm not totally sure about what portal is mapped to what portal, but I see an error in the order of transformations. If you implement
T1 * R * T2-1
then in OpenGL

glTranslatef(T1.x, T1.y, T1.z);
glRotatef( ... );
glTranslatef(-T2.x, -T2.y, -T2.z);
// followed by the scene objects here

would be the correct order. Notice that (due to column vector use) particular transformations more to the right in the formula appear "nearer" to the scene objects in the program. The order in the formula and in the program flow has to be effectively the same.

If it still doesn't work, then try to negate the angle (or else, as an alternative, exhange the arguments to the cross product invocation).
OMG!!!!!!! i got it to work!! THANK YOU SOOOO MUCH! i was about in another reply that it still was not working but i switched the glTranslatef's and it worked! omg im soooooo happy now!

now i just have to figure out how to get my lighting code to work inside of the portals, the recursive nature of portals when facing each other and then the actual transporting!

once again, thank you soo much!

This topic is closed to new replies.

Advertisement