• Create Account

### #ActualgbMike

Posted 29 April 2012 - 02:43 AM

Thanks for the optimization tip I've just swapped out my code for the better version.

Let me go into a bit more detail. I'm working on a simple 3D engine with openGL. I am using this function for collision calculation between a model, made up of triangles, and a ray. In order to run the collision test, I need to convert the ray (which has coordinates relative to global space) to the local space of the model (by applying the rotation, translation, and scale to the origin and end point of the ray)

For now, the ray I'm testing with is a pick ray, generated by a mouse click. That ray's coords are then moved into object space, and run a collision test against each face in the model. The collisions register perfectly one at a time (I'm not outputting any fixed values, rather simply clicking around the edges of my object, to make sure the collisions are accurate) As I mentioned, this functions perfectly with only rotation applied, but becomes inaccurate when a second or 3rd rotation direction is put in place. I've traced the collision area with my mouse, and it looks like, it is testing collisions against the model, with a different rotation. But again, it works perfectly when rotated on only one angle.

I know the pick ray generation is working properly, as is the collision test. (They've both been tested pretty thoroughly in several previous instances) I'm not sure if this helps, but here is the rest of the code for the globalToLocal function. Btw, I've been learning this on my own, so if you happen to catch any other poorly written bits of code, please let me know.

[source lang="cpp"] /* Hierarchy is the set of transformations to apply. In this case, only one element is in the list.*/ void Mesh::globalToLocal( vector<Vector3 *> &in_vertices, list<Transform *> hierarchy ){ for ( int i = 0; i < (int)in_vertices.size(); i++ ) { list<Transform *>::iterator it; for ( it = hierarchy.begin(); it != hierarchy.end(); it ++ ) { applyVertexTranslation ( (*in_vertices[i]), (*it)->translate ); applyVertexRotation ( (*in_vertices[i]), (*it)->rotation ); //scale is not currently added to the heirarchy, since it is never changed/used } }}void Mesh::applyVertexRotation ( Vector3 &point, Vector3 &rotations ){ float rot, oldX, oldY, oldZ; /////////// Z ///////////// if( !(point.x == 0 && point.y == 0) ) { rot = -CMath::DegreesToRadians( rotations.z ); oldX = point.x; oldY = point.y; point.x = oldX * cos(rot) - oldY * sin(rot); point.y = oldX * sin(rot) + oldY * cos(rot); } /////////// Y ///////////// if( !(point.x == 0 && point.z == 0) ) { rot = CMath::DegreesToRadians( rotations.y ); oldX = point.x; oldZ = point.z; point.x = oldX * cos(rot) - oldZ * sin(rot); point.z = oldX * sin(rot) + oldZ * cos(rot); } /////////// X ///////////// if( !(point.z == 0 && point.y == 0) ) { rot = CMath::DegreesToRadians( rotations.x ); oldZ = point.z; oldY = point.y; point.z = oldZ * cos(rot) - oldY * sin(rot); point.y = oldZ * sin(rot) + oldY * cos(rot); }}void Mesh::applyVertexScale ( Vector3 &point, Vector3 &scale ){ point.x /= scale.x; point.y /= scale.y; point.z /= scale.z;}void Mesh::applyVertexTranslation ( Vector3 &point, Vector3 &translations ){ point.x -= translations.x; point.y -= translations.y; point.z -= translations.z;}[/source]

### #2gbMike

Posted 29 April 2012 - 02:42 AM

Thanks for the optimization tip I've just swapped out my code for the better version.

Let me go into a bit more detail. I'm working on a simple 3D engine with openGL. I am using this function for collision calculation between a model, made up of triangles, and a ray. In order to run the collision test, I need to convert the ray (which has coordinates relative to global space) to the local space of the model (by applying the rotation, translation, and scale to the origin and end point of the ray)

For now, the ray I'm testing with is a pick ray, generated by a mouse click. That ray's coords are then moved into object space, and run a collision test against each face in the model. The collisions register perfectly one at a time (I'm not outputting any fixed values, rather simply clicking around the edges of my object, to make sure the collisions are accurate) As I mentioned, this functions perfectly with only rotation applied, but becomes inaccurate when a second or 3rd rotation direction is put in place. I've traced the collision area with my mouse, and it looks like, it is testing collisions against the model, with a different rotation. But again, it works perfectly when rotated on only one angle.

I know the pick ray generation is working properly, as is the collision test. (They've both been tested pretty thoroughly in several previous instances) I'm not sure if this helps, but here is the rest of the code for the globalToLocal function. Btw, I've been learning this on my own, so if you happen to catch any other poorly written bits of code, please let me know.

[source lang="cpp"]/*Hierarchy is the set of transformations to apply. In this case, only one element is inthe list.*/void Mesh::globalToLocal( vector<Vector3 *> &in_vertices, list<Transform *> hierarchy ){for ( int i = 0; i < (int)in_vertices.size(); i++ ){ list<Transform *>::iterator it; for ( it = hierarchy.begin(); it != hierarchy.end(); it ++ ) { applyVertexTranslation ( (*in_vertices[i]), (*it)->translate ); applyVertexRotation ( (*in_vertices[i]), (*it)->rotation ); //scale is not currently added to the heirarchy, since it is never changed/used }}}void Mesh::applyVertexRotation ( Vector3 &point, Vector3 &rotations ){float rot, oldX, oldY, oldZ;/////////// Z /////////////if( !(point.x == 0 && point.y == 0) ){ rot = -CMath::DegreesToRadians( rotations.z ); oldX = point.x; oldY = point.y; point.x = oldX * cos(rot) - oldY * sin(rot); point.y = oldX * sin(rot) + oldY * cos(rot);} /////////// Y /////////////if( !(point.x == 0 && point.z == 0) ){ rot = CMath::DegreesToRadians( rotations.y ); oldX = point.x; oldZ = point.z; point.x = oldX * cos(rot) - oldZ * sin(rot); point.z = oldX * sin(rot) + oldZ * cos(rot);} /////////// X /////////////if( !(point.z == 0 && point.y == 0) ){ rot = CMath::DegreesToRadians( rotations.x ); oldZ = point.z; oldY = point.y; point.z = oldZ * cos(rot) - oldY * sin(rot); point.y = oldZ * sin(rot) + oldY * cos(rot);}}void Mesh::applyVertexScale ( Vector3 &point, Vector3 &scale ){ point.x /= scale.x; point.y /= scale.y; point.z /= scale.z;}void Mesh::applyVertexTranslation ( Vector3 &point, Vector3 &translations ){point.x -= translations.x;point.y -= translations.y;point.z -= translations.z;}[/source]

### #1gbMike

Posted 29 April 2012 - 02:41 AM

Thanks for the optimization tip I've just swapped out my code for the better version.

Let me go into a bit more detail. I'm working on a simple 3D engine with openGL. I am using this function for collision calculation between a model, made up of triangles, and a ray. In order to run the collision test, I need to convert the ray (which has coordinates relative to global space) to the local space of the model (by applying the rotation, translation, and scale to the origin and end point of the ray)

For now, the ray I'm testing with is a pick ray, generated by a mouse click. That ray's coords are then moved into object space, and run a collision test against each face in the model. The collisions register perfectly one at a time (I'm not outputting any fixed values, rather simply clicking around the edges of my object, to make sure the collisions are accurate) As I mentioned, this functions perfectly with only rotation applied, but becomes inaccurate when a second or 3rd rotation direction is put in place. I've traced the collision area with my mouse, and it looks like, it is testing collisions against the model, with a different rotation. But again, it works perfectly when rotated on only one angle.

I know the pick ray generation is working properly, as is the collision test. (They've both been tested pretty thoroughly in several previous instances) I'm not sure if this helps, but here is the rest of the code for the globalToLocal function. Btw, I've been learning this on my own, so if you happen to catch any other poorly written bits of code, please let me know.

[source lang="cpp"] /* Hierarchy is the set of transformations to apply. In this case, only one element is in the list.*/ void Mesh::globalToLocal( vector<Vector3 *> &in_vertices, list<Transform *> hierarchy ){ for ( int i = 0; i < (int)in_vertices.size(); i++ ) { list<Transform *>::iterator it; for ( it = hierarchy.begin(); it != hierarchy.end(); it ++ ) { applyVertexTranslation ( (*in_vertices[i]), (*it)->translate ); applyVertexRotation ( (*in_vertices[i]), (*it)->rotation ); //scale is not currently added to the heirarchy, since it is never changed/used } }}void Mesh::applyVertexRotation ( Vector3 &point, Vector3 &rotations ){ float rot, oldX, oldY, oldZ; /////////// Z ///////////// if( !(point.x == 0 && point.y == 0) ) { rot = -CMath::DegreesToRadians( rotations.z ); oldX = point.x; oldY = point.y; point.x = oldX * cos(rot) - oldY * sin(rot); point.y = oldX * sin(rot) + oldY * cos(rot); } /////////// Y ///////////// if( !(point.x == 0 && point.z == 0) ) { rot = CMath::DegreesToRadians( rotations.y ); oldX = point.x; oldZ = point.z; point.x = oldX * cos(rot) - oldZ * sin(rot); point.z = oldX * sin(rot) + oldZ * cos(rot); } /////////// X ///////////// if( !(point.z == 0 && point.y == 0) ) { rot = CMath::DegreesToRadians( rotations.x ); oldZ = point.z; oldY = point.y; point.z = oldZ * cos(rot) - oldY * sin(rot); point.y = oldZ * sin(rot) + oldY * cos(rot); }}void Mesh::applyVertexScale ( Vector3 &point, Vector3 &scale ){ point.x /= scale.x; point.y /= scale.y; point.z /= scale.z;}void Mesh::applyVertexTranslation ( Vector3 &point, Vector3 &translations ){ point.x -= translations.x; point.y -= translations.y; point.z -= translations.z;}[/source]

PARTNERS