Thread: Problem with my rotation code?

  1. #16
    'AlHamdulillah
    Join Date
    Feb 2003
    Posts
    790
    ah, I see what you are saying, sounds like a great idea. also, using velocities for rotation makes it much more smooth, cause I am just not changing a vertices position at one time, but can apply movement to it.

    thanks

  2. #17
    Registered User grady's Avatar
    Join Date
    Oct 2003
    Posts
    27
    Originally posted by Silvercord
    (ooo, you said, *quaternion*!) . Oh, and orbits are ellipcital, meaning they never have an eccentricity of zero (that'd be a circle )
    I admit 'quaternion' does sound rather fancy. I'm just pointing out possible things that might be cumbersome in your method, and having a discussion about vectors in general, nothing personal. If you have a nice solution or if I'm making a mistake and there is no problem just say so.

    Yes ε=0 is a circle and indeed that is precisely the only trajectory that will require you to rotate the velocity without changing the magnitude: which is the situation I was referring to in that post. True enough, there are a range of values ε can have for the other conic sections the trajectory can take on. Thus in practice circular orbits are never seen. But so what? Its still the only orbit where rotations alone on the velocity are sufficient

    This veers away from EvBladeRunnervE's original question, which has been answered, towards the new question which is apparently: how should vectors be represented internally. I'm just trying to point out alot of extra math operations incurred if the rule is to always normalize vectors. The only places I can think of where vectors must always be normalized is when they are used as axes of rotations, or they will be representing a 'normal to a surface' vector and used in dot products where you only need cos θ.

    That would only be useful if you had radially symmetric charged objects moving through a magnetic field perpendicular to the axis of symmetry of the object
    Oops, i messed up here, the velocity would have to point along the axis of symmetry and the field has to point out from or in to the axis of symmetry. Not possible, so nevermind that example. I can't think of any simple situation where you would rotate around the velocity vector. However, getting cos θ from the velocity of a vertex and another vector sounds useful.
    Last edited by grady; 12-19-2003 at 12:52 PM.

  3. #18
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    you really haven't done very much graphics programming, have you? Go home, program a game engine, and THEN tell me how useless normalized vectors are

    EDIT: oh, also, I wouldn't compute realtime the orbit of an object in a computer game. If I wanted, say, an asteroid floating around a planet, I'd make way points for it to hit in the editing program. this means that there are no computations involved, it simply would travel from waypoint to waypoint, and *look* like it's orbiting. aesthetics are more important than 100% physically correct computations in computer games, so, fugazi
    Last edited by Silvercord; 12-19-2003 at 02:17 PM.

  4. #19
    'AlHamdulillah
    Join Date
    Feb 2003
    Posts
    790
    here is a new question, when and where should I use a "Velocity" type of class, i can see it as useful in movement, but I dont see how it would be useful in the case of a rotation, where you are moving a "point" to a specific point, not constant movement between one point and the other.....feh, still can't get gametutorials stupid ideas out of my head.

    thanks,

  5. #20
    Registered User grady's Avatar
    Join Date
    Oct 2003
    Posts
    27
    I think you're saying you are clear about linear velocity. Rotations are caused by angular velocity, and the parameters for an angular movement are different from those of a linear movement. You can still chant the old mantra "velocity is magnitude plus a direction" but direction in angular motion is specified by an axis (normalized vector) and the sign of the degrees to rotate through. The sign tells you whether to move counter clockwise or clockwise around the axis. The magnitude can just be thought of as the absolute value of degrees you turn through. So really, if you've got this for your "velocity" data structure:

    Code:
    struct velocity
    {
    	float x,y,z;
    };
    It just won't work for an angular velocity because you need an extra parameter:

    Code:
    struct angvelocity
    {
    	float x,y,z,degrees;
    };
    This is all fine and good, but plugging in an axis and a number of degrees is going to rotate you around the origin of your frame. When you're writing a physics simulation and something gets thrown through the air, it is going to spin on its own local axis. So in addition to the above struct, you have to specify a point to adjust the axis away from the origin of the scene. Rotating not through the origin also makes you have to do a little pre and post processing on the vertex you are rotating.

    So a velocity class that you use like so:
    vtx.x += vel.x;
    vtx.y += vel.y;
    vtx.z += vet.z;
    glVertex3f(vtx.x,vtx.y,vtx.z);
    isn't going to get you anywhere with rotations, because its a linear velocity and has no relation to your angular movement. Bottom line is: you need two types of velocity class, but it all sort of ties into how you are implementing things in your physics code. There might be a more effecient way for your specific needs, but that way, whatever it is, doesn't involve linear velocity telling you anything about angular velocity.
    Last edited by grady; 12-19-2003 at 04:33 PM.

  6. #21
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    just stop posting here.

  7. #22
    'AlHamdulillah
    Join Date
    Feb 2003
    Posts
    790
    just stop posting here.
    I second that.

    Believe it or not, when most people post questions, they do somewhat expect them to be answered by people actually developing/have developed a 3D engine like Silvercord, Grady.

  8. #23
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    ...My suggestion is to normalize the vector first, store it, then rotate the normalized vector through your equations. If I'm correct the normal will never change and will always be perpendicular to the surface pointing 'outward' So if the object rotates, everything remains the same in the relation of the normal to the surface. The only thing changing is the rotation. So theoretically if you compute the normal once and then simply rotate it later - its the same thing and its much faster.

    After all if you rotate a vector and normalize it, is that not the same thing as normalizing the vector first and then rotating the normal later??

    If you wish to get past the oh so slow sqrt function, there is an imprecise way to do a sqrt using a Taylor-Series power function.
    It has a +/- 8% error which might give some wacky results in lighting equations. But you can also get a 3% error if you use a single and not a double, so it's up to you.
    Code:
    
    
    double Fast_Distance3D(double fx,double fy,double fz)
    {
      int temp;
      int x,y,z;
      x=fabs(fx)*1024;
      y=fabs(fy)*1024;
      z=fabs(fz)*1024;
    
      if (y<x) SWAP (x,y,temp);
      if (z<y) SWAP (y,z,temp);
      if (y<x) SWAP (x,y,temp);
      
      int dist=(z+11*(y>>5)+(x>>2));
      return ((double)dist>>10));
    }
    SWAP is left for you to code.

    Even on faster comps, sqrt() still takes a lot of clocks so I'd use any method I could find to minimize its use.

    By the way, there is NO performance hit for using doubles as opposed to singles. The FPU opcode that loads a real into ST(0) FLD can both use singles and doubles - there is no extra cost for converting either one to the native FPU data type which is 80 bits - not 64 as I previously thought.

    EDIT: Kudos to Fordy for pointing this fact out to me over at the assembly board on www.flashdaddee.com


    This is for the 80486 - there is no clock data for the new Pentium IA-32's, but don't expect a lot of difference.

    FLD m32real - 3 clocks
    FLD m64real - 3 clocks
    FLD m80real - 6 clocks
    FLD ST(i) - 4 clocks

    Float is a m32real, and double is an m64real. No performance hit.
    A single is a 32-bit value or float and a double is a 64-bit value.

    Clocks are a measure of how many cycles it takes to execute the instruction. Actual real-time nanoseconds might be different. A computer running at 1 GHz will definitely be able to execute faster than a 2GHz, but the base instruction clock timing remains the same - it just executes it faster.
    Last edited by VirtualAce; 12-20-2003 at 12:51 PM.

  9. #24
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    I only offer what I do.

    blade feel free to pm me with stuff too.

    it is going to spin on its own local axis
    There's an extremely easy way to do this. mVelocity is the ball's current direction. All you need to do, in the renderer, before you render the object, in this case it is a ball, you simply need to rotate the entire coordinate system 90 degrees about the y axis, and then rotate about the forward direction (which is now perpendicular to the forward direction), and it gives the illusion of spinning on its local axis. I just coded it up, and it works.

    Code:
    	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); //so you can tell that the auxsolidsphere is rotating
    			static	float degrees = 0;				
    			degrees += 100 * Export.mFPS.TimeFrac;
    
    			glPushMatrix();
    			glTranslatef(ball.mCurPos.x,ball.mCurPos.y,ball.mCurPos.z);
    			glRotatef(90,0,1,0);
    			glRotatef(degrees,ball.mCurVelocity.x, ball.mCurVelocity.y, ball.mCurVelocity.z);
    			glColor3f(1.0f,0.0f,0.0f);
    			auxSolidSphere(10.0f);
    			glPopMatrix();
    			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    EDIT:
    i implemented taylor iteration, and i've got an equivalent fast_sqrt method(which I posted on these boards), and I found out that they're not really much faster than either the C standard sqrt() in math.h or the intrinsic FSQRT on the FPU (I've reprogrammed all of my math using FPU, just for fun). i.e I ran the sqrt method several million times, and it took 381 ms. that was actually faster than my taylor series iteration in 2 steps! sqrt is *not that* slow

    EDIT1: in fact, the function that you should be most concerned with is the dotproduct function, because it gets called more than any other function. I was wondering why so many people are so anal retentive about getting that function to work with SIMD optimizations and fun junk like that.
    Last edited by Silvercord; 12-20-2003 at 12:57 PM.

  10. #25
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    By the way I believe DirectX's vertex structure - at least one of them - stores the normals for vectors and then rotates them later and it seems to work fine.

    Not sure how OpenGL works becuase I don't code in it, but perhaps it has similiar support. In a large 3D engine with lots of polies, I shudder to think of finding the normal for each surface and I'm sure Silvercoord is not doing this.

    EDIT: Interesting info about the sqrt(). I've not coded the Taylor series in assembly but I'm sure you are correct about the sqrt() and FSQRT. I would probably use FSQRT myself being the asm guy that I am. Either way stack is going to be used for parameters - so the C function might just as well suffice.
    Last edited by VirtualAce; 12-20-2003 at 12:58 PM.

  11. #26
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    hell no bubba

    the normals to surfaces are pre computed for the world, and for collision detection against moving objects in the BSP the normals to the planes for bounding boxes are axially aligned

    i.e they are simply x, y, z and their negatives.

  12. #27
    'AlHamdulillah
    Join Date
    Feb 2003
    Posts
    790
    ok, here is a new question, how do I rotate an object around a specific point? my code works for any axis, but it is based on origin, I presume I could just glTranslatef to the point thereby making that the origin, but I would like to know, or atleast be pointed in the direction of how to do it without translating anything.

    EDIT:

    Silvercord:

    so, the BSP has all of its surface normals stored in the file already?
    Last edited by EvBladeRunnervE; 12-20-2003 at 01:01 PM.

  13. #28
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    translate it out, and then rotate

  14. #29
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    hell no bubba
    Didn't think so.


    To rotate around a specific point in general 3D terms, translate the LOCAL origin to that point using Translate. Then when you transform to world and view the object will rotate correctly.

  15. #30
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    so, the BSP has all of its surface normals stored in the file already?
    yes sahr!

    EDIT: bubba, I pmed you with an asm question.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with game code.
    By ajdspud in forum C++ Programming
    Replies: 5
    Last Post: 02-14-2006, 06:39 PM
  2. Replies: 5
    Last Post: 12-03-2003, 05:47 PM
  3. Help with code for simple Y2K problem
    By Mule in forum C++ Programming
    Replies: 3
    Last Post: 03-06-2003, 12:53 AM
  4. Problem multiplying rotation matrices together
    By Silvercord in forum A Brief History of Cprogramming.com
    Replies: 20
    Last Post: 03-04-2003, 09:20 AM