Errors with code

Started by
4 comments, last by GameDev.net 19 years, 6 months ago
I get two errors when compilging the following code: Q3DMath.cpp

#include "Q3DMath.h"
#include "QuickCG.h"
#include <cmath>

Vector3::Vector3(Scalar x, Scalar y, Scalar z)
{
    this->x = x;
    this->y = y;
    this->z = z;
}

Vector3::Vector3()
{
    x = 0.0;
    y = 0.0;
    z = 0.0;
} 

Scalar Vector3::length()
{
    return sqrt(x * x + y * y + z * z);
}

Scalar length(Vector3 v)
{
    return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

void Vector3::normalize()
{
    Scalar l = length();
    if(l != 0)
    {
        x /= l;
        y /= l;
        z /= l;
    }    
}

Vector3 normalize(Vector3 v)
{
    v.normalize();
    return v;
}

Scalar Vector3::distance(Vector3 v)
{
    return sqrt((v.x - x) * (v.x - x) + (v.y - y) * (v.y - y) + (v.z - z) * (v.z - z));
}  

Scalar distance(Vector3 v, Vector3 w)
{
    return sqrt((v.x - w.x) * (v.x - w.x) + (v.y - w.y) * (v.y - w.y) + (v.z - w.z) * (v.z - w.z));
}

Scalar Vector3::dot(Vector3 v)
{
    return v.x * x + v.y * y + v.z * z;
}             

Scalar dot(Vector3 v, Vector3 w)
{
    return v.x * w.x + v.y * w.y + v.z * w.z;
}

Vector3 Vector3::cross(Vector3 v)
{
    Vector3 u;

	u.x = ((v.y * z) - (v.z * y));
	u.y = ((v.z * x) - (v.x * z));
	u.z = ((v.x * y) - (v.y * x));
    return u;    
} 

Vector3 cross(Vector3 v, Vector3 w)
{
    Vector3 u;

	u.x = ((v.y * w.z) - (v.z * w.y));
	u.y = ((v.z * w.x) - (v.x * w.z));
	u.z = ((v.x * w.y) - (v.y * w.x));
    return u;
}

//Subtract two vectors
Vector3 operator-(Vector3 v, Vector3 w)
{
    Vector3 u;
    u.x = v.x - w.x;
    u.y = v.y - w.y;
    u.z = v.z - w.z;
    return u;
}

//Return the negative of the vector
Vector3 operator-(Vector3 v)
{
    Vector3 u;
    u.x = -v.x;
    u.y = -v.y;
    u.z = -v.z;
    return u;
}

//Add two vectors
Vector3 operator+(Vector3 v, Vector3 w)
{
    Vector3 u;
    u.x = v.x + w.x;
    u.y = v.y + w.y;
    u.z = v.z + w.z;
    return u;
}

//Multiplies a vector by a scalar
Vector3 operator*(Vector3 v, Scalar a)
{
    Vector3 w;
    w.x = v.x * a;
    w.y = v.y * a;
    w.z = v.z * a;
    return w;
}

//Multiplies a vector by a scalar
Vector3 operator*(Scalar a, Vector3 v)
{
    Vector3 w;
    w.x = v.x * a;
    w.y = v.y * a;
    w.z = v.z * a;
    return w;
}

//Divides a vector through a scalar
Vector3 operator/(Vector3 v, Scalar a)
{
    Vector3 w;
    w.x = v.x / a;
    w.y = v.y / a;
    w.z = v.z / a;
    return w;
}

//Gives the angle between two 3D vectors (in radians)
Scalar vectorAngle(Vector3 v, Vector3 w)
{
    //dot product(v,w) = length(v)*length(w)*cos(angle) ==> angle = acos(dot/(length(v)*length(w))) = acos(dot(norm(v)*norm(w)));
    Scalar cosineOfAngle = dot(normalize(v), normalize(w));
    //for acos, the value has to be between -1.0 and 1.0, but due to numerical imprecisions it sometimes comes outside this range
    if(cosineOfAngle > 1.0) cosineOfAngle = 1.0;
    if(cosineOfAngle < -1.0) cosineOfAngle = -1.0;
    return -acos(cosineOfAngle);
}

//Rotate vector v around arbitrary axis axis for angle radians
//It can only rotate around an axis through our object, to rotate around another axis:
//first translate the object to the axis, then use this function, then translate back in the new direction.
Vector3 rotateAroundArbitrary(Vector3 v, Vector3 axis, Scalar angle)
{
    if((v.x == 0) && (v.y == 0) && (v.z == 0)) return Vector3();

    Vector3 w;
    Scalar c, s, t;

    axis.normalize();

    //calculate parameters of the rotation matrix
    c = cos(angle);
    s = sin(angle);
    t = 1 - c;

    //multiply v with rotation matrix
    w.x = (t * axis.x * axis.x +          c) * v.x 
        + (t * axis.x * axis.y + s * axis.z) * v.y 
        + (t * axis.x * axis.z - s * axis.y) * v.z;
        
    w.y = (t * axis.x * axis.y - s * axis.z) * v.x 
        + (t * axis.y * axis.y +          c) * v.y 
        + (t * axis.y * axis.z + s * axis.x) * v.z;
        
    w.z = (t * axis.x * axis.z + s * axis.y) * v.x 
        + (t * axis.y * axis.z - s * axis.x) * v.y 
        + (t * axis.z * axis.z +          c) * v.z;

    w.normalize();
    w = w * v.length();
    
    return w;
}



Matrix3::Matrix3(Scalar a, Scalar b, Scalar c, Scalar d, Scalar e, Scalar f, Scalar g, Scalar h, Scalar i)
{
    this->a = a;
    this->b = b;
    this->c = c;
    this->d = d;
    this->e = e;
    this->f = f;
    this->g = g;
    this->h = h;
    this->i = i;
}
    
Matrix3::Matrix3()
{
    a = 0.0;
    b = 0.0;
    c = 0.0;
    d = 0.0;
    e = 0.0;
    f = 0.0;
    g = 0.0;
    h = 0.0;
    i = 0.0;
}

////////////////////////////////////////////////////////////////////////////////
//Transpose:                                                                  //
//                                                                            //
// [ a b c ]T    [ a d g ]                                                    //
// [ d e f ]  =                                                      //</span>
<span class="cpp-comment">// [ g h i ]     [ c f i ]                                                    //</span>
<span class="cpp-comment">////////////////////////////////////////////////////////////////////////////////</span>
<span class="cpp-keyword">void</span> Matrix3::transpose()
{
    b += d; d = b - d; b -= d; <span class="cpp-comment">//swap b and d</span>
    c += g; g = c - g; c -= g; <span class="cpp-comment">//swap c and g</span>
    f += h; h = f - h; f -= h; <span class="cpp-comment">//swap f and h</span>
}  

Matrix3 transpose(Matrix3 A)
{
    A.transpose();
    <span class="cpp-keyword">return</span> A;
} 

Scalar Matrix3::determinant()
{
    Scalar det = a * e * i 
               + b * f * g 
               + d * h * c 
               - g * e * c 
               - d * b * i 
               - h * f * a;
              
    <span class="cpp-keyword">return</span> det;
}   

Scalar determinant(Matrix3 A)
{
    <span class="cpp-keyword">return</span> A.determinant();
}     

<span class="cpp-comment">//Inverse of a 3x3 matrix</span>
<span class="cpp-keyword">void</span> Matrix3::inverse()
{
    <span class="cpp-comment">/*
    the inverse is the adjoint divided through the determinant
    find the matrix of minors (minor = determinant of 2x2 matrix of the 2 rows/colums current element is NOT in)
    turn them in cofactors (= change some of the signs)
    find the adjoint by transposing the matrix of cofactors
    divide this through the determinant to get the inverse
    */</span>
    
    Scalar det = determinant();
    Matrix3 B;

    <span class="cpp-comment">//included in these calculations: minor, cofactor (changed signs), transpose (by the order of "="), division through determinant</span>
    B.a = ( e * i - h * f) / det;
    B.b = (-b * i + h * c) / det;
    B.c = ( b * f - e * c) / det;
    B.d = (-d * i + g * f) / det;
    B.e = ( a * i - g * c) / det;
    B.f = (-a * f + d * c) / det;
    B.g = ( d * h - g * e) / det;
    B.h = (-a * h + g * b) / det;
    B.i = ( a * e - d * b) / det;
    
    *<span class="cpp-keyword">this</span> = B;
}

Matrix3 inverse(Matrix3 A)
{
    A.inverse();
    <span class="cpp-keyword">return</span> A;
} 

<span class="cpp-comment">//Add two matrices</span>
Matrix3 <span class="cpp-keyword">operator</span>+(Matrix3 A, Matrix3 B)
{
    A.a += B.a;
    A.b += B.b;
    A.c += B.c;
    A.d += B.d;
    A.e += B.e;
    A.f += B.f;
    A.g += B.g;
    A.h += B.h;
    A.i += B.i;
    <span class="cpp-keyword">return</span> A;
}

<span class="cpp-comment">//Subtract two matrices</span>
Matrix3 <span class="cpp-keyword">operator</span>-(Matrix3 A, Matrix3 B)
{
    A.a -= B.a;
    A.b -= B.b;
    A.c -= B.c;
    A.d -= B.d;
    A.e -= B.e;
    A.f -= B.f;
    A.g -= B.g;
    A.h -= B.h;
    A.i -= B.i;
    <span class="cpp-keyword">return</span> A;
}

<span class="cpp-comment">//Multiply a matrix with a scalar</span>
Matrix3 <span class="cpp-keyword">operator</span>*(Matrix3 A, Scalar a)
{
    A.a *= a;
    A.b *= a;
    A.c *= a;
    A.d *= a;
    A.e *= a;
    A.f *= a;
    A.g *= a;
    A.h *= a;
    A.i *= a;
    <span class="cpp-keyword">return</span> A;
}

<span class="cpp-comment">//Multiply a matrix with a scalar</span>
Matrix3 <span class="cpp-keyword">operator</span>*(Scalar a, Matrix3 A)
{
    A.a *= a;
    A.b *= a;
    A.c *= a;
    A.d *= a;
    A.e *= a;
    A.f *= a;
    A.g *= a;
    A.h *= a;
    A.i *= a;
    <span class="cpp-keyword">return</span> A;
}

<span class="cpp-comment">//Divide a matrix through a scalar</span>
Matrix3 <span class="cpp-keyword">operator</span>/(Matrix3 A, Scalar a)
{
    A.a /= a;
    A.b /= a;
    A.c /= a;
    A.d /= a;
    A.e /= a;
    A.f /= a;
    A.g /= a;
    A.h /= a;
    A.i /= a;
    <span class="cpp-keyword">return</span> A;
}

<span class="cpp-comment">//Multiply a matrix with a column vector, resulting in a column vector</span>
Vector3 <span class="cpp-keyword">operator</span>*(Matrix3 A, Vector3 v)
{
    Vector3 w;
    w.x = A.a * v.x + A.b * v.y + A.c * v.z;
    w.y = A.d * v.x + A.e * v.y + A.f * v.z;
    w.z = A.g * v.x + A.h * v.y + A.i * v.z;
    <span class="cpp-keyword">return</span> w;
}  

<span class="cpp-comment">//Multiply a vector with a row matrix, resulting in a row vector</span>
Vector3 <span class="cpp-keyword">operator</span>*(Vector3 v, Matrix3 A)
{
    Vector3 w;
    w.x = A.a * v.x + A.d * v.y + A.g * v.z;
    w.y = A.b * v.x + A.e * v.y + A.h * v.z;
    w.z = A.c * v.x + A.f * v.y + A.i * v.z;
    <span class="cpp-keyword">return</span> w;
}

<span class="cpp-comment">//Multiply a 3x3 matrix with a 3x3 matrix</span>
Matrix3 <span class="cpp-keyword">operator</span>*(Matrix3 A, Matrix3 B)
{
    Matrix3 C;
    C.a = A.a * B.a + A.b * B.d + A.c * B.g;
    C.b = A.a * B.b + A.b * B.e + A.c * B.h;
    C.c = A.a * B.c + A.b * B.h + A.c * B.i;
    C.d = A.d * B.a + A.e * B.d + A.f * B.g;
    C.e = A.d * B.b + A.e * B.e + A.f * B.h;
    C.f = A.d * B.c + A.e * B.h + A.f * B.i;
    C.g = A.g * B.a + A.h * B.d + A.i * B.g;
    C.h = A.g * B.b + A.h * B.e + A.i * B.h;
    C.i = A.g * B.c + A.h * B.h + A.i * B.i;
    <span class="cpp-keyword">return</span> C;
}



<span class="cpp-comment">//Camera functions</span>

<span class="cpp-comment">/*
Note: 
Every function that changes u, v or dir should use "generateMatrix();" at the end,
unless that function already calls another one that generates it, at the end.
*/</span>
Camera::Camera(Scalar posx, Scalar posy, Scalar posz, Scalar ux, Scalar uy, Scalar uz, Scalar vx, Scalar vy, Scalar vz, Scalar dirx, Scalar diry, Scalar dirz, Scalar nearClip, Scalar farClip)
{
    pos.x = posx;
    pos.y = posy;
    pos.z = posz;
    u.x = ux;
    u.y = uy;
    u.z = uz;
    v.x = vx;
    v.y = vy;
    v.z = vz;
    dir.x = dirx;
    dir.y = diry;
    dir.z = dirz;
    <span class="cpp-keyword">this</span>-&gt;nearClip = nearClip;
    <span class="cpp-keyword">this</span>-&gt;farClip = farClip;
    generateMatrix();
}    

<span class="cpp-comment">//Construct a camera with default parameters</span>
Camera::Camera()
{
    pos.x = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    pos.y = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    pos.z = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    u.x = <span class="cpp-number">1</span>.<span class="cpp-number">0</span>;
    u.y = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    u.z = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    v.x = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    v.y = <span class="cpp-number">1</span>.<span class="cpp-number">0</span>;
    v.z = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    dir.x = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    dir.y = <span class="cpp-number">0</span>.<span class="cpp-number">0</span>;
    dir.z = <span class="cpp-number">1</span>.<span class="cpp-number">0</span>;
    nearClip = <span class="cpp-number">0</span>.<span class="cpp-number">1</span>;
    farClip = <span class="cpp-number">1000000</span>.<span class="cpp-number">0</span>;
    generateMatrix();        
}

Vector3 Camera::getU()
{
    <span class="cpp-keyword">return</span> u;
}    
Vector3 Camera::getV()
{
    <span class="cpp-keyword">return</span> v;
}    
Vector3 Camera::getDir()
{
    <span class="cpp-keyword">return</span> dir;
}    
Vector3 Camera::getPos()
{
    <span class="cpp-keyword">return</span> pos;
}

<span class="cpp-keyword">void</span> Camera::setU(Vector3 newU)
{
    u = newU;
    generateMatrix();
}    
<span class="cpp-keyword">void</span> Camera::setV(Vector3 newV)    
{
    v = newV;
    generateMatrix();
}

<span class="cpp-keyword">void</span> Camera::setDir(Vector3 newDir)    
{
    dir = newDir;
    generateMatrix();
}    

<span class="cpp-keyword">void</span> Camera::setPos(Vector3 newPos)
{
    pos = newPos;
} 

<span class="cpp-keyword">void</span> Camera::move(Vector3 offset)
{
    pos = pos + offset;
}  

<span class="cpp-keyword">void</span> Camera::rotate(Vector3 axis, Scalar angle)
{
    u = rotateAroundArbitrary(u, axis, angle);
    v = rotateAroundArbitrary(v, axis, angle);
    dir = rotateAroundArbitrary(dir, axis, angle);
    generateMatrix();
}   

<span class="cpp-comment">//Look in a certain direction.</span>
<span class="cpp-keyword">void</span> Camera::setLookDir(Vector3 newDir)
{
    Vector3 axis = cross(dir, newDir);
    <span class="cpp-keyword">if</span>(axis.length() == <span class="cpp-number">0</span>) <span class="cpp-keyword">return</span>;
    
    Scalar angle = vectorAngle(dir, newDir);
    <span class="cpp-keyword">if</span>(angle != <span class="cpp-number">0</span>) rotate(axis, angle);   
}

<span class="cpp-comment">//Look at a certain point (the point will come in the center of the screen, if nothing's in front of it that is)</span>
<span class="cpp-keyword">void</span> Camera::lookAt(Vector3 lookAtMe)
{
    setLookDir(lookAtMe - pos);
}

Scalar Camera::getDist(Vector3 point)
{
    <span class="cpp-keyword">return</span> distance(pos, point);
}

<span class="cpp-comment">//Set the distance to a point</span>
<span class="cpp-keyword">void</span> Camera::setDist(Vector3 point, Scalar dist)
{
    Scalar currentDist = distance(pos, point);
    move(currentDist * normalize(point - pos));
}    

<span class="cpp-keyword">void</span> Camera::zoom(Scalar a)
{
    <span class="cpp-comment">//increasing length of dir or decreasing length of the plane (u and v) = zoom IN</span>
    u = u / a;
    v = v / a;
    generateMatrix();
}

<span class="cpp-keyword">void</span> Camera::zoomU(Scalar a)
{
    u = u / a;
    generateMatrix();
}

<span class="cpp-keyword">void</span> Camera::zoomV(Scalar a)
{
    v = v / a;
    generateMatrix();
}

Scalar Camera::getZoomU()
{
   <span class="cpp-keyword">return</span>(dir.length() / u.length());
}

Scalar Camera::getZoomV()
{
   <span class="cpp-keyword">return</span>(dir.length() / v.length());
}

<span class="cpp-keyword">void</span> Camera::setZoomU(Scalar a)
{
    u = u / (a / getZoomU());
    generateMatrix();
}

<span class="cpp-keyword">void</span> Camera::setZoomV(Scalar a)
{
    v = v / (a / getZoomV());
    generateMatrix();
}    

Scalar Camera::getFOVU()
{
    <span class="cpp-keyword">return</span>(<span class="cpp-number">2</span>.<span class="cpp-number">0</span> * atan2(u.length(), dir.length()));
}

Scalar Camera::getFOVV()
{
    <span class="cpp-keyword">return</span>(<span class="cpp-number">2</span>.<span class="cpp-number">0</span> * atan2(v.length(), dir.length()));
}

<span class="cpp-keyword">void</span> Camera::setFOVU(Scalar angle)
{
    setZoomU(<span class="cpp-number">1</span>.<span class="cpp-number">0</span> / tan(angle / <span class="cpp-number">2</span>.<span class="cpp-number">0</span>));
}

<span class="cpp-keyword">void</span> Camera::setFOVV(Scalar angle)
{
    setZoomV(<span class="cpp-number">1</span>.<span class="cpp-number">0</span> / tan(angle / <span class="cpp-number">2</span>.<span class="cpp-number">0</span>));
}     

<span class="cpp-comment">////////////////////////////////////////////////////////////////////////////////</span>
<span class="cpp-comment">//Functions to get Yaw, Pitch and Roll. Normally to do things with the camera, </span>
<span class="cpp-comment">//you never need these angles, everything works with vectors!</span>
<span class="cpp-comment">//However, these can be useful if you want a compass in your game, or a weapon </span>
<span class="cpp-comment">//that allows you to accurately change it's pitch</span>
<span class="cpp-comment">////////////////////////////////////////////////////////////////////////////////</span>

<span class="cpp-comment">/*
Yaw is the wind direction the camera is looking at if you'd be standing on planet earth, and the ground has vectors X and Z, while Y points to the sky
       N
       ^ 
       |z 
       |   x        Looking in the direction Z = North (0°, 0 rad)
W —–+—–&gt; E    Looking in the direction X = East (+90°, +1.57 rad)
       |            Looking in negative Z = South (180°, 3.1415 rad, sign jump)
       |            Looking in negative X = West (-90°, -1.57 rad)
       |
       S
*/</span>
Scalar Camera::getYaw()
{    
    <span class="cpp-comment">//the atan2 function returns the angle of a 2D point (like from polar coordinates), so here it gives angle of dir projected on XZ plane, which is what we want for the yaw</span>
    <span class="cpp-keyword">return</span>(atan2(dir.x, dir.z));
}

<span class="cpp-comment">//setYaw can be used to make you look at a certain wind direction (where the ground is the XZ plane)</span>
<span class="cpp-keyword">void</span> Camera::setYaw(Scalar angle)
{    
    Scalar currentAngle = getYaw();
    <span class="cpp-comment">//to change yaw, you have to rotate around the "up" axis of the WORLD = the y axis</span>
    rotate(Vector3(<span class="cpp-number">0</span>,<span class="cpp-number">1</span>,<span class="cpp-number">0</span>), - angle + currentAngle);
}

<span class="cpp-comment">//rotates camera around world Y-axis with given angle (in space this would make no sense since there isn't really an "up" or "down" of the world, instead you rotate around the "up" and "down" of your own spaceship there</span>
<span class="cpp-comment">//When rolled, yawPlanet will give very annoying rotation, so for a spacegame or flight simulator you'll want to use yawSpace instead.</span>
<span class="cpp-keyword">void</span> Camera::yawPlanet(Scalar angle)
{    
    rotate(Vector3(<span class="cpp-number">0</span>,<span class="cpp-number">1</span>,<span class="cpp-number">0</span>), angle);
}

<span class="cpp-comment">//rotates camera around camera v axis with given angle (this one makes sense in space, but not on a planet, on a planet your camera would start getting a "roll")</span>
<span class="cpp-keyword">void</span> Camera::yawSpace(Scalar angle)
{    
    rotate(v, angle);
}

<span class="cpp-comment">/*
Pitch is only useful to define if you're standing on a plane or a planet, and there's a sky
The plane you're standing on is the XZ plane, and Y points to the sky
Pitch is 0° if you look forward (direction vector parallel to the XZ plane)
Pitch is +90° if you look to the sky (maximum "up")
Pitch is -90° if you look at the ground (maximum "down")
Pitches of more than 90° or less than -90° aren't defined, since these can also be made by having  yaw 180° rotated and having a pitch between -90° and +90°
*/</span>
Scalar Camera::getPitch()
{
    <span class="cpp-comment">//Project dir on the XZ plane</span>
    <span class="cpp-comment">//Then find angle between dir and projected dir   </span>
    <span class="cpp-comment">//With atan2: angle of the point (lengthof2Dvector(dir.x, dir.z), dir.y)</span>
    <span class="cpp-keyword">return</span> atan2(dir.y, sqrt(dir.x * dir.x + dir.z * dir.z));
}

<span class="cpp-comment">/*
setPitch can be used to make you look to the sky or floor with certain angle without changing wind direction
NOT useful for spacecrafts etc… because there's no up or down in space and X, Y and Z axes have no physical meaning there
only useful for FPS games or other games where you walk on a planet surface
*/</span>
<span class="cpp-keyword">void</span> Camera::setPitch(Scalar angle)
{    
    Scalar currentAngle = getPitch();
    <span class="cpp-comment">//to change pitch, you have to rotate around the horizontal vector of the camera</span>
    rotate(u, angle - currentAngle);
}

<span class="cpp-comment">//pitches the camera over a certain amount</span>
<span class="cpp-keyword">void</span> Camera::pitch(Scalar angle)
{    
    rotate(u, angle);
}

<span class="cpp-comment">/*
Roll is only necessary for spacegames, flightsimulators or rare effects of FPS games
Roll 0° = cam.u parallel with XZ plane, cam.v points upwards
Roll +90° = cam.v parallel with XZ plane, cam.u points downwards
Roll +-180° = cam.u parallel with XZ plane, cam.v points downwards (= you're upside down)
Roll -90° = cam.v parallel with XZ plane, cam.u points upwards
In space games the angles have no physical meaning, but in the coordinate system this angle is an "Euler" angle.
*/</span>
Scalar Camera::getRoll()
{
    <span class="cpp-comment">//roll is the angle between the plane (world_up, camera_dir) and the plane (camera_up, camera_dir)</span>
    <span class="cpp-comment">//the angle between two planes is the angle between their normals</span>
    <span class="cpp-comment">//the normals are gotten with cross products</span>
    <span class="cpp-comment">//the vectorAngle function uses acos and dot product</span>
    Scalar roll = vectorAngle(cross(Vector3(<span class="cpp-number">0</span>, <span class="cpp-number">1</span>, <span class="cpp-number">0</span>), dir), cross(v, dir));
    <span class="cpp-keyword">if</span>(u.y &lt; <span class="cpp-number">0</span>) roll = -roll;
    <span class="cpp-keyword">return</span> roll;
}

<span class="cpp-keyword">void</span> Camera::setRoll(Scalar angle)
{    
    Scalar currentAngle = getRoll();
    <span class="cpp-comment">//to change roll, you have to rotate around the direction vector of the camera</span>
    rotate(dir, angle - currentAngle);
}

<span class="cpp-comment">//rolls the camera by rotating it around the direction vector (only makes sense in space or for "shaking" effects)</span>
<span class="cpp-keyword">void</span> Camera::roll(Scalar angle)
{    
    rotate(dir, angle);
}

<span class="cpp-comment">//makes u, v and dir perpendicular by using cross product, maintains exact direction and roll if only v was skewed</span>
Vector3 Camera::resetSkewU()
{
    Scalar oldZoomU = getZoomU(); 
    Scalar oldZoomV = getZoomV();
    u = cross(dir, v);
    v = cross(dir, -u);
    setZoomU(oldZoomU);
    setZoomV(oldZoomV);
}

<span class="cpp-comment">//makes u, v and dir perpendicular by using cross product, maintains exact direction and roll if only u was skewed</span>
Vector3 Camera::resetSkewV()
{
    Scalar oldZoomU = getZoomU(); 
    Scalar oldZoomV = getZoomV();
    v = cross(dir, u);
    u = cross(dir, -v);
    setZoomU(oldZoomU);
    setZoomV(oldZoomV);
}

<span class="cpp-comment">//get and set screen ratios of the camera (ratio of length of u and v, e.g. 4:3, 16:9, 640:480, …)</span>
Scalar Camera::getRatioUV()
{
    <span class="cpp-keyword">return</span> u.length() / v.length();
}    

Scalar Camera::getRatioVU()
{
    <span class="cpp-keyword">return</span> v.length() / u.length();
}

<span class="cpp-comment">//changes V    </span>
<span class="cpp-keyword">void</span> Camera::setRatioUV(Scalar ratio)
{
    v.normalize();
    v = v * u.length() / ratio;
    generateMatrix();    
}    

<span class="cpp-comment">//changes U</span>
<span class="cpp-keyword">void</span> Camera::setRatioVU(Scalar ratio)
{
    u.normalize();
    u = u * v.length() / ratio;
    generateMatrix();
} 

<span class="cpp-comment">//scale U, V and Dir without changing what you see</span>
Scalar Camera::getScale()
{
    <span class="cpp-keyword">return</span> dir.length();
}    
<span class="cpp-keyword">void</span> Camera::setScale(Scalar dirLength)
{
    scale(dir.length() / dirLength);
}
    
<span class="cpp-keyword">void</span> Camera::scale(Scalar factor)    
{
    dir = dir * factor;
    u = u * factor;
    v = v * factor;
    generateMatrix();
}    

<span class="cpp-keyword">void</span> Camera::generateMatrix()
{
    <span class="cpp-comment">//the cameraMatrix is generated, this is the matrix with 3 column vectors: u, v and dir</span>
    <span class="cpp-comment">//it has to be generated everytime u, v or dir are changed  </span>
    camMatrix.a = u.x;
    camMatrix.d = u.y;
    camMatrix.g = u.z;
    camMatrix.b = v.x;
    camMatrix.e = v.y;
    camMatrix.h = v.z;
    camMatrix.c = dir.x;
    camMatrix.f = dir.y;
    camMatrix.i = dir.z;

    <span class="cpp-comment">//this is the inverse of the camMatrix, to use for transformations</span>
    invCamMatrix = inverse(camMatrix);
}

Matrix3 Camera::getMatrix()
{
    <span class="cpp-keyword">return</span> camMatrix;
}

Matrix3 Camera::getInvMatrix()
{
    <span class="cpp-keyword">return</span> invCamMatrix;
}

<span class="cpp-keyword">void</span> Camera::setMatrix(Matrix3 matrix)
{
    <span class="cpp-comment">//to make sure the vectors and the matrix are according to each other, set the vectors to the given matrix </span>
    <span class="cpp-comment">//and then use generateMatrix with these new vectors</span>
    u.x = matrix.a;
    u.y = matrix.d;
    u.z = matrix.g;
    v.x = matrix.b;
    v.y = matrix.e;
    v.z = matrix.h;
    dir.x = matrix.c;
    dir.y = matrix.f;
    dir.z = matrix.i;
    generateMatrix();
} 

Vector3 Camera::transform(Vector3 v)
{
    <span class="cpp-comment">/*
    Transformation from coordinate system 1 (base 1) to coordinate system 2 (base 2):
        
    vector v = coordinates of point p in base 1 (column vector)
    matrix A = the 3 vectors representing coordinates of unit vectors of base 2 in base 1 (3 column vectors in matrix)
    vector w = coordinates of point p in base 2(column vector)
    
    Then: v = A * w
          w = A^(-1) * v
    
    Now: base 1 = worldspace, base 2 = cameraspace
    v = coordinates of point in worldspace (the given v )
    A = the matrix from the camera: the coordinates of the camera vectors in worldspace
    w = coordinates of point in cameraspace
    
    So our transformation is w = A^(-1) * v, where v is the parameter given to the function, and A = perspective matrix of camera
    
    All this text to describe only one line of code…
    */</span>
    
    <span class="cpp-keyword">return</span> invCamMatrix * v;  
}

<span class="cpp-comment">/*
uses the transform function of the camera, to project a point on screen, stores result in x and y (screen coordinates)
returns 1 if point is legal, 0 if point is behind camera, outside screen, …
also stores z value of the point in camera coordinates in z
*/</span>
<span class="cpp-keyword">bool</span> Camera::projectOnScreen(Vector3 point, <span class="cpp-keyword">int</span> &amp; x, <span class="cpp-keyword">int</span> &amp; y, Scalar &amp; z)
{
    <span class="cpp-comment">//First transformation: position</span>
    Vector3 a = point - pos;
    
    <span class="cpp-comment">//Second transformation: rotation</span>
    Vector3 b = transform(a);
    
    <span class="cpp-comment">//Third transformation: Projection on screen</span>
    <span class="cpp-comment">//be warned: if b.z is too small, you get integer imprecisions, so don't make near clipping plane too small    </span>
    <span class="cpp-keyword">int</span> px = <span class="cpp-keyword">int</span>(w / <span class="cpp-number">2</span>.<span class="cpp-number">0</span> + w * b.x / b.z);
    <span class="cpp-keyword">int</span> py = <span class="cpp-keyword">int</span>(h / <span class="cpp-number">2</span>.<span class="cpp-number">0</span> - h * b.y / b.z); <span class="cpp-comment">//inversed: y should be "up", while in screen coordinates it's down</span>
    <span class="cpp-keyword">if</span>(onScreen(px, py) &amp;&amp; b.z &gt;= nearClip)
    {
        x = px;
        y = py;
        z = b.z;
        <span class="cpp-keyword">return</span> <span class="cpp-number">1</span>;
    }
    <span class="cpp-keyword">else</span>
    {
        x = px;
        y = py;
        z = b.z;
        <span class="cpp-keyword">return</span> <span class="cpp-number">0</span>;
    }        
}

<span class="cpp-keyword">bool</span> Camera::projectOnScreen(Vector3 point, <span class="cpp-keyword">int</span> &amp; x, <span class="cpp-keyword">int</span> &amp; y)
{
    Scalar z;
    <span class="cpp-keyword">return</span> projectOnScreen(point, x, y, z);       
} 

<span class="cpp-keyword">bool</span> Camera::camSpaceToScreen(Vector3 point, <span class="cpp-keyword">int</span> &amp; x, <span class="cpp-keyword">int</span> &amp; y)
{
    <span class="cpp-comment">//be warned: if point.z is too small, you get integer imprecisions, so don't make near clipping plane too small</span>
    <span class="cpp-keyword">int</span> px = <span class="cpp-keyword">int</span>(w / <span class="cpp-number">2</span>.<span class="cpp-number">0</span> + w * point.x / point.z);
    <span class="cpp-keyword">int</span> py = <span class="cpp-keyword">int</span>(h / <span class="cpp-number">2</span>.<span class="cpp-number">0</span> - h * point.y / point.z); <span class="cpp-comment">//inversed: y should be "up", while in screen coordinates it's down</span>
    <span class="cpp-keyword">if</span>(onScreen(px, py) &amp;&amp; point.z &gt;= nearClip)
    {
        x = px;
        y = py;
        <span class="cpp-keyword">return</span> <span class="cpp-number">1</span>;
    }
    <span class="cpp-keyword">else</span>
    {
        x = px;
        y = py;
        <span class="cpp-keyword">return</span> <span class="cpp-number">0</span>;
    }       
}    


<span class="cpp-comment">//Auxiliary Functions</span>


<span class="cpp-comment">//Swap between radians and degrees</span>
Scalar radToDeg(Scalar rad)
{
    <span class="cpp-keyword">return</span> <span class="cpp-number">360</span>.<span class="cpp-number">0</span> * rad / (<span class="cpp-number">3</span>.<span class="cpp-number">14159</span> * <span class="cpp-number">2</span>.<span class="cpp-number">0</span>);
} 

Scalar degToRad(Scalar deg)
{
    <span class="cpp-keyword">return</span> (<span class="cpp-number">3</span>.<span class="cpp-number">14159</span> * <span class="cpp-number">2</span>.<span class="cpp-number">0</span>) * deg / <span class="cpp-number">360</span>.<span class="cpp-number">0</span>;
}    

<span class="cpp-comment">//TO DO:</span>
<span class="cpp-comment">//Z-buffer</span>
<span class="cpp-comment">//drawLine and disk functions that use the zbuffer</span>

</pre></div><!–ENDSCRIPT–>

I get the folowing errors:

——————–Configuration: Wolfenstein raycaster - Win32 Debug——————–
Compiling…
main.cpp
Q3DMath.cpp
QuickCG.cpp
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.cpp(744) : error C4716: 'Camera::resetSkewU' : must return a value
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.cpp(755) : error C4716: 'Camera::resetSkewV' : must return a value
Error executing cl.exe.

Wolfenstein raycaster.exe - 2 error(s), 0 warning(s)


could someone help?
______________________________My website: Quest Networks
Advertisement
It's just like it says: Those methods return a Vector3, and you don't have them returning anything. They should probably by void type.
[sub]My spoon is too big.[/sub]
I dont really understand what you mean. instead of them being a vector3 type, I should just change that void? wouldnt the game run differently or not at all if I did that?

*EDIT* I just did that, and I get many more errors.
______________________________My website: Quest Networks
...

you're going to have to tell us the new errors if you want us to help.
I thought there would simply be a way to fix it by leaving it as vector3. I got this code off the internet as part of a tutorial, and I havent changed anything. Why would it work then but not now? anyways, here is the new errors:(by the way, there are other places that use vector3, would they report errors too?)

--------------------Configuration: Wolfenstein raycaster - Win32 Debug--------------------
Compiling...
Q3DMath.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(737) : error C2556: 'void __thiscall Camera::resetSkewU(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkewU(
void)'
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(174) : see declaration of 'resetSkewU'
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(737) : error C2371: 'resetSkewU' : redefinition; different basic types
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(174) : see declaration of 'resetSkewU'
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(748) : error C2556: 'void __thiscall Camera::resetSkewV(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkewV(
void)'
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(175) : see declaration of 'resetSkewV'
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(748) : error C2371: 'resetSkewV' : redefinition; different basic types
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(175) : see declaration of 'resetSkewV'
Error executing cl.exe.

Wolfenstein raycaster.exe - 4 error(s), 0 warning(s)



______________________________My website: Quest Networks
Quote:Original post by jakpandora
I thought there would simply be a way to fix it by leaving it as vector3. I got this code off the internet as part of a tutorial, and I havent changed anything. Why would it work then but not now? anyways, here is the new errors:(by the way, there are other places that use vector3, would they report errors too?)

--------------------Configuration: Wolfenstein raycaster - Win32 Debug--------------------
Compiling...
Q3DMath.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(737) : error C2556: 'void __thiscall Camera::resetSkewU(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkewU(
void)'
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(174) : see declaration of 'resetSkewU'
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(737) : error C2371: 'resetSkewU' : redefinition; different basic types
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(174) : see declaration of 'resetSkewU'
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(748) : error C2556: 'void __thiscall Camera::resetSkewV(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkewV(
void)'
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(175) : see declaration of 'resetSkewV'
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(748) : error C2371: 'resetSkewV' : redefinition; different basic types
c:\program files\microsoft visual studio\myprojects\wolfenstein raycaster\q3dmath.h(175) : see declaration of 'resetSkewV'
Error executing cl.exe.

Wolfenstein raycaster.exe - 4 error(s), 0 warning(s)


That's because you only changed the definition of the function to void. You also need to change the declaration to void as well. The two must match.

This topic is closed to new replies.

Advertisement