Thread: Moving a 3d object

  1. #1
    Registered User
    Join Date
    Nov 2001
    Posts
    162

    Moving a 3d object

    Here is the code for moving an object through 3D space in my program. Whats wrong with it is that it moves, but not in the right direction. Could anybody tell me what part of this is wrong? Thanks!
    Code:
    void MATH::UpdatePos(VEC *vPos, float speed)
    {
    vPos->view.x = vPos->pos.x + sin(vPos->yaw) * sin(vPos->pitch+90);
    vPos->view.y = vPos->pos.y + cos(vPos->yaw);
    vPos->view.z = vPos->pos.z + cos(vPos->yaw) * -sin(vPos->pitch+90);
    // Get the current view vector (the direction we are looking)
    CVector3 vVector = vPos->view - vPos->pos;
    vVector = Normalize(vVector);
    
    vPos->pos.x += vVector.x * speed;		// Add our acceleration to our position's X
    vPos->pos.y += vVector.y * speed;		// Add our acceleration to our position's Y
    vPos->pos.z += vVector.z * speed;		// Add our acceleration to our position's Z
    vPos->view.x += vVector.x * speed;			// Add our acceleration to our view's X
    vPos->view.y += vVector.y * speed;			// Add our acceleration to our view's Y
    vPos->view.z += vVector.z * speed;			// Add our acceleration to our view's Z
    }
    Here are the class defininions if you need them:
    Code:
    struct CVector3
    {
    public:
    	
    	// A default constructor
    	CVector3() {}
    
    	// This is our constructor that allows us to initialize our data upon creating an instance
    	CVector3(float X, float Y, float Z) 
    	{ 
    		x = X; y = Y; z = Z;
    	}
    
    	// Here we overload the + operator so we can add vectors together 
    	CVector3 operator+(CVector3 vVector)
    	{
    		// Return the added vectors result.
    		return CVector3(vVector.x + x, vVector.y + y, vVector.z + z);
    	}
    
    	// Here we overload the - operator so we can subtract vectors 
    	CVector3 operator-(CVector3 vVector)
    	{
    		// Return the subtracted vectors result
    		return CVector3(x - vVector.x, y - vVector.y, z - vVector.z);
    	}
    	
    	// Here we overload the * operator so we can multiply by scalars
    	CVector3 operator*(float num)
    	{
    		// Return the scaled vector
    		return CVector3(x * num, y * num, z * num);
    	}
    
    	// Here we overload the / operator so we can divide by a scalar
    	CVector3 operator/(float num)
    	{
    		// Return the scale vector
    		return CVector3(x / num, y / num, z / num);
    	}
    
    	float x, y, z; 						
    };
    
    struct VEC
    {
    	CVector3 pos;				//The position
    	float pitch, yaw, roll;     //The pitch, yaw, and roll gotten from key input
    	CVector3 view;  //The view vector calculated
    };

  2. #2
    geek SilentStrike's Avatar
    Join Date
    Aug 2001
    Location
    NJ
    Posts
    1,141
    What is the orientation with the yaw and pitch? IE, if you are looking straight with yaw and pitch=0, are you looking down the positive z axis?

    You are adding 90 to the argument of sin, probably thinking it's in degrees, but it's in radians, definite bug there.

    Few speed optimizations...

    Code:
    vPos->view.x = vPos->pos.x + sin(vPos->yaw) * sin(vPos->pitch+90);
    vPos->view.y = vPos->pos.y + cos(vPos->yaw);
    vPos->view.z = vPos->pos.z + cos(vPos->yaw) * -sin(vPos->pitch+90);
    // Get the current view vector (the direction we are looking)
    CVector3 vVector = vPos->view - vPos->pos;
    vVector = Normalize(vVector);
    So overkill. First, you are adding vPos->view vector to the directional vector, and then subtracting it away.. waste of time. Second, you are normalizing an already normalized vector. The following code does the same thing.

    Code:
    CVector3 vVector(sin(vPos->yaw) * sin(vPos->pitch+90), cos(vPos->yaw), cos(vPos->yaw) * -sin(vPos->pitch+90));
    Given, the adding 90 to the pitch is still broken, but if that is fixed, and the trig is right (that killed me when making the camera in my own free floating 3d gravity sim, by far hardest part of the whole project), it will work.

    You may not even need to keep the view vector at all, as getting the direction it is pointing requires only knowing the yaw and pitch.

    Also, consider taking the vectors by pointer/reference rather than by value. Finally, consider doing only one division in the division operator (do a single division to find reciprocal, and then use multiplaction operator), division is typically 5-10x slower than multiplcation, 1 div and 3 muls are usually quite a bit faster than 3 divs.
    Prove you can code in C++ or C# at TopCoder, referrer rrenaud
    Read my livejournal

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    162
    Yes, 0 pitch and yaw is pointing towards the +z axis(into the screen). I will try taking away the +90 thing when I get to my home computer. Thanks for the optomizations, too

  4. #4
    Sayeh
    Guest
    Make sure you know the way your screen geometry has your cartesian system defined-- right-handed or left-handed.

  5. #5
    Sayeh
    Guest
    Oh, and by the way-- it's _much_ more effecient to use matrix math for rotations... and surprisingly, it's not as difficult as it seems.

    For sake of example, let's assume that your coordinate system has +Y going up, +X going right, and +Z going into the screen.

    Please take a moment and draw a cartesian coordinate with three vectors leading off from 0,0,0 for x, y, and z. It will _really_ help because you can actually visualize how easy a matrix is to use this way.

    If we turn this coordinate system into a matrix (3x3) and define the coordinates, they look like this:

    x = 1,0,0
    y = 0,1,0, and
    z = 0,0,1

    Gee, doesn't that look like an identity matrix! In a 3x3 rotation matrix, because you're working with identities, the vertical columns are equivalent to the axis, and the horizontal rows are equivalent to the coordinates.

    As an example, of using this rotation matrix, what happens if we rotate around z (y & z move clockwise) 90 degrees? We use 90 degrees to make it easy to visualize.

    Well, that means that the z-coord stays the same (0,0,1), and the z-axis stays the same (0,0,0 to 0,0,1). But look what happens to X and Y:

    'x' moved down and left (clockwise), so it's coordinate is now 0,-1,0. And and 'y' moved right and down (clockwise), so it's coordinate is now 1,0,0.

    Look what that did to the identity matrix:

    x = 0,-1,0
    y = 1, 0,0, and
    z = 0, 0,1

    You have a new identity matrix. Now you simply aply this matrix to each coord you want moved, and voila-- they rotate appropriately.

    Very fun stuff

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Include Problems
    By loopshot in forum Game Programming
    Replies: 13
    Last Post: 02-17-2006, 03:22 PM
  2. A question about constructors...
    By Wolve in forum C++ Programming
    Replies: 9
    Last Post: 05-04-2005, 04:24 PM
  3. A 3D Program for my 3D models...?
    By Rune Hunter in forum C++ Programming
    Replies: 26
    Last Post: 08-19-2004, 10:04 AM
  4. 3D SDK for C++ programmers
    By chand in forum Game Programming
    Replies: 2
    Last Post: 05-20-2003, 07:38 AM
  5. 3d engines
    By Unregistered in forum Game Programming
    Replies: 7
    Last Post: 12-17-2001, 11:19 AM