This topic is 5459 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have been wroking on a raycaster. there are a few bugs in it, however, and I need to know how to fix it. although there are mutltiple files to the project, the bugs occur in the following one:
#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;
}

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 ]  =  [ b e h ]                                                    //
// [ g h i ]     [ c f i ]                                                    //
////////////////////////////////////////////////////////////////////////////////
void Matrix3::transpose()
{
b += d; d = b - d; b -= d; //swap b and d
c += g; g = c - g; c -= g; //swap c and g
f += h; h = f - h; f -= h; //swap f and h
}

Matrix3 transpose(Matrix3 A)
{
A.transpose();
return A;
}

Scalar Matrix3::determinant()
{
Scalar det = a * e * i
+ b * f * g
+ d * h * c
- g * e * c
- d * b * i
- h * f * a;

return det;
}

Scalar determinant(Matrix3 A)
{
return A.determinant();
}

//Inverse of a 3x3 matrix
void Matrix3::inverse()
{
/*
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
*/

Scalar det = determinant();
Matrix3 B;

//included in these calculations: minor, cofactor (changed signs), transpose (by the order of "="), division through determinant
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;

*this = B;
}

Matrix3 inverse(Matrix3 A)
{
A.inverse();
return A;
}

Matrix3 operator+(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;
return A;
}

//Subtract two matrices
Matrix3 operator-(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;
return A;
}

//Multiply a matrix with a scalar
Matrix3 operator*(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;
return A;
}

//Multiply a matrix with a scalar
Matrix3 operator*(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;
return A;
}

//Divide a matrix through a scalar
Matrix3 operator/(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;
return A;
}

//Multiply a matrix with a column vector, resulting in a column vector
Vector3 operator*(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;
return w;
}

//Multiply a vector with a row matrix, resulting in a row vector
Vector3 operator*(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;
return w;
}

//Multiply a 3x3 matrix with a 3x3 matrix
Matrix3 operator*(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;
return C;
}

//Camera functions

/*
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.
*/
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;
this->nearClip = nearClip;
this->farClip = farClip;
generateMatrix();
}

//Construct a camera with default parameters
Camera::Camera()
{
pos.x = 0.0;
pos.y = 0.0;
pos.z = 0.0;
u.x = 1.0;
u.y = 0.0;
u.z = 0.0;
v.x = 0.0;
v.y = 1.0;
v.z = 0.0;
dir.x = 0.0;
dir.y = 0.0;
dir.z = 1.0;
nearClip = 0.1;
farClip = 1000000.0;
generateMatrix();
}

Vector3 Camera::getU()
{
return u;
}
Vector3 Camera::getV()
{
return v;
}
Vector3 Camera::getDir()
{
return dir;
}
Vector3 Camera::getPos()
{
return pos;
}

void Camera::setU(Vector3 newU)
{
u = newU;
generateMatrix();
}
void Camera::setV(Vector3 newV)
{
v = newV;
generateMatrix();
}

void Camera::setDir(Vector3 newDir)
{
dir = newDir;
generateMatrix();
}

void Camera::setPos(Vector3 newPos)
{
pos = newPos;
}

void Camera::move(Vector3 offset)
{
pos = pos + offset;
}

void Camera::rotate(Vector3 axis, Scalar angle)
{
u = rotateAroundArbitrary(u, axis, angle);
v = rotateAroundArbitrary(v, axis, angle);
dir = rotateAroundArbitrary(dir, axis, angle);
generateMatrix();
}

//Look in a certain direction.
void Camera::setLookDir(Vector3 newDir)
{
Vector3 axis = cross(dir, newDir);
if(axis.length() == 0) return;

Scalar angle = vectorAngle(dir, newDir);
if(angle != 0) rotate(axis, angle);
}

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

Scalar Camera::getDist(Vector3 point)
{
return distance(pos, point);
}

//Set the distance to a point
void Camera::setDist(Vector3 point, Scalar dist)
{
Scalar currentDist = distance(pos, point);
move(currentDist * normalize(point - pos));
}

void Camera::zoom(Scalar a)
{
//increasing length of dir or decreasing length of the plane (u and v) = zoom IN
u = u / a;
v = v / a;
generateMatrix();
}

void Camera::zoomU(Scalar a)
{
u = u / a;
generateMatrix();
}

void Camera::zoomV(Scalar a)
{
v = v / a;
generateMatrix();
}

Scalar Camera::getZoomU()
{
return(dir.length() / u.length());
}

Scalar Camera::getZoomV()
{
return(dir.length() / v.length());
}

void Camera::setZoomU(Scalar a)
{
u = u / (a / getZoomU());
generateMatrix();
}

void Camera::setZoomV(Scalar a)
{
v = v / (a / getZoomV());
generateMatrix();
}

Scalar Camera::getFOVU()
{
return(2.0 * atan2(u.length(), dir.length()));
}

Scalar Camera::getFOVV()
{
return(2.0 * atan2(v.length(), dir.length()));
}

void Camera::setFOVU(Scalar angle)
{
setZoomU(1.0 / tan(angle / 2.0));
}

void Camera::setFOVV(Scalar angle)
{
setZoomV(1.0 / tan(angle / 2.0));
}

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

/*
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 -----+-----> 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
*/
Scalar Camera::getYaw()
{
//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
return(atan2(dir.x, dir.z));
}

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

//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
//When rolled, yawPlanet will give very annoying rotation, so for a spacegame or flight simulator you'll want to use yawSpace instead.
void Camera::yawPlanet(Scalar angle)
{
rotate(Vector3(0,1,0), angle);
}

//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")
void Camera::yawSpace(Scalar angle)
{
rotate(v, angle);
}

/*
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°
*/
Scalar Camera::getPitch()
{
//Project dir on the XZ plane
//Then find angle between dir and projected dir
//With atan2: angle of the point (lengthof2Dvector(dir.x, dir.z), dir.y)
return atan2(dir.y, sqrt(dir.x * dir.x + dir.z * dir.z));
}

/*
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
*/
void Camera::setPitch(Scalar angle)
{
Scalar currentAngle = getPitch();
//to change pitch, you have to rotate around the horizontal vector of the camera
rotate(u, angle - currentAngle);
}

//pitches the camera over a certain amount
void Camera::pitch(Scalar angle)
{
rotate(u, angle);
}

/*
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.
*/
Scalar Camera::getRoll()
{
//roll is the angle between the plane (world_up, camera_dir) and the plane (camera_up, camera_dir)
//the angle between two planes is the angle between their normals
//the normals are gotten with cross products
//the vectorAngle function uses acos and dot product
Scalar roll = vectorAngle(cross(Vector3(0, 1, 0), dir), cross(v, dir));
if(u.y < 0) roll = -roll;
return roll;
}

void Camera::setRoll(Scalar angle)
{
Scalar currentAngle = getRoll();
//to change roll, you have to rotate around the direction vector of the camera
rotate(dir, angle - currentAngle);
}

//rolls the camera by rotating it around the direction vector (only makes sense in space or for "shaking" effects)
void Camera::roll(Scalar angle)
{
rotate(dir, angle);
}

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

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

//get and set screen ratios of the camera (ratio of length of u and v, e.g. 4:3, 16:9, 640:480, ...)
Scalar Camera::getRatioUV()
{
return u.length() / v.length();
}

Scalar Camera::getRatioVU()
{
return v.length() / u.length();
}

//changes V
void Camera::setRatioUV(Scalar ratio)
{
v.normalize();
v = v * u.length() / ratio;
generateMatrix();
}

//changes U
void Camera::setRatioVU(Scalar ratio)
{
u.normalize();
u = u * v.length() / ratio;
generateMatrix();
}

//scale U, V and Dir without changing what you see
Scalar Camera::getScale()
{
return dir.length();
}
void Camera::setScale(Scalar dirLength)
{
scale(dir.length() / dirLength);
}

void Camera::scale(Scalar factor)
{
dir = dir * factor;
u = u * factor;
v = v * factor;
generateMatrix();
}

void Camera::generateMatrix()
{
//the cameraMatrix is generated, this is the matrix with 3 column vectors: u, v and dir
//it has to be generated everytime u, v or dir are changed
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;

//this is the inverse of the camMatrix, to use for transformations
invCamMatrix = inverse(camMatrix);
}

Matrix3 Camera::getMatrix()
{
return camMatrix;
}

Matrix3 Camera::getInvMatrix()
{
return invCamMatrix;
}

void Camera::setMatrix(Matrix3 matrix)
{
//to make sure the vectors and the matrix are according to each other, set the vectors to the given matrix
//and then use generateMatrix with these new vectors
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)
{
/*
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...
*/

return invCamMatrix * v;
}

/*
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
*/
bool Camera::projectOnScreen(Vector3 point, int & x, int & y, Scalar & z)
{
//First transformation: position
Vector3 a = point - pos;

//Second transformation: rotation
Vector3 b = transform(a);

//Third transformation: Projection on screen
//be warned: if b.z is too small, you get integer imprecisions, so don't make near clipping plane too small
int px = int(w / 2.0 + w * b.x / b.z);
int py = int(h / 2.0 - h * b.y / b.z); //inversed: y should be "up", while in screen coordinates it's down
if(onScreen(px, py) && b.z >= nearClip)
{
x = px;
y = py;
z = b.z;
return 1;
}
else
{
x = px;
y = py;
z = b.z;
return 0;
}
}

bool Camera::projectOnScreen(Vector3 point, int & x, int & y)
{
Scalar z;
return projectOnScreen(point, x, y, z);
}

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

//Auxiliary Functions

{
return 360.0 * rad / (3.14159 * 2.0);
}

{
return (3.14159 * 2.0) * deg / 360.0;
}

//TO DO:
//Z-buffer
//drawLine and disk functions that use the zbuffer


I get the following errors: --------------------Configuration: Wolfenstein raycaster - Win32 Debug-------------------- Compiling... Q3DMath.cpp C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(736) : error C2143: syntax error : missing ';' before 'tag::id' C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(736) : error C2501: 'scalar' : missing storage-class or type specifiers C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(736) : fatal error C1004: unexpected end of file found Error executing cl.exe. Wolfenstein raycaster.exe - 3 error(s), 0 warning(s) could someone tell me whats wrong? also odd is the fact that last time I compiled the project, I was having different errors, something to do with scalar. could someone tell me if those are ok also?

##### Share on other sites
all the errors occur on line 736, no body is going to count the lines to find where the error is. Maybe you can go into VS, go to the line with the error on it and post that line here. I'm sure you would get a lot more help.

btw how much of that is your code? maybe the original source may be of help.

##### Share on other sites
indeed, friend. i plugged that into dev-c++, and on line 736 you have typed ' Scalar ' - however it seems you use it two different ways - ' Scalar ' & ' scalar ' in the preceeding function. perhaps double checking that would help - are they separate return types ?.
line 736 =
Scalar Camera::getRatioVU(){    return v.length() / u.length();} <-- line 736

hope that helps.
<edit::> as compared to
scalar Camera::resetSkewV() { /* insert function here */ }

##### Share on other sites
what do you need a 3d vector for in a wolfenstein like game anyway?

##### Share on other sites
It looks like your return types for the functions resetSkewU and resetSkewV are wrong. It seems you need to change 'scalar' to 'Scalar' if you intend to return a scalar value. But it doesnt seem you even return anything at the moment in those functions, so perhaps they should just return void.

Kyle

##### Share on other sites
all of the code I have posted is not mine, and got it off of a site as part of a tutorial. I was more interested in focusing on the content of the game instead of programming most of it, so I found a raycasting tutorial(I dont even remeber the site anymore, sorry) I will check out the scalar thing(though this is exaclty how I got it online. I cut and pasted it) is there any way to find line 736 without counting every single line?

*EDIT* there were only two places where SCALAR was lower case and not capital. when I changed them to capital, I got more errors:

--------------------Configuration: Wolfenstein raycaster - Win32 Debug--------------------
Compiling...
Q3DMath.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(737) : error C2556: 'double __thiscall Camera::resetSkewU(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkew
U(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: 'double __thiscall Camera::resetSkewV(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkew
V(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)

##### Share on other sites
Quote:
 Original post by jakpandora...though this is exaclty how I got it online. I cut and pasted it...

famous last words there buddy,

in VS.NET you can enable line numbers (at the left of the document), they are also displayed at the bottom of the document (Ln _ Col _ Ch _) and i believe there is also a goto line dialog somewhere in there.

The errors, random copying/pasting and random editing related. You changed the definition but didn't change the prototype/declaration.

btw by copying and pasting you are never going to learn how to do it yourself, and as you have just seen most of the time it doesn't work.

##### Share on other sites
I know ill never learn, I never really wanted to learn the code in this file. it was never even taught in the tutorial. and it wasnt simply random copy and pasting. I copied the whole file and put everything where its supposed to go. and I use mscv C++ 6.0, not .NET. and from what I can see, there is only a prototyype.

##### Share on other sites
well, since you aren't a coder i'm not sure what you can do. but i'll spare you the lecture.
Quote:
 C:\Program Files\Microsoft Visual Studio\MyProjects\Wolfenstein raycaster\Q3DMath.cpp(737) : error C2556: 'double __thiscall Camera::resetSkewU(void)' : overloaded function differs only by return type from 'class Vector3 __thiscall Camera::resetSkewU(void)'

this, and all the others that refer to the bold section, means that you (or whomever you got this from) attempted to overload an operator by return type only, without changing the parameters. because you are using VC6, it won't compile because VC6 doesn't support partial-variable specialization (or whatever its called). you can overload a function in VC6 by changing the return type and parameters, something you probably don't want to do. however, a simpler solution would be to find a different compiler that does support that. and check the function definitions of those referenced (i didn't go through it).
also, as an after thought, you might want to check the headers for exactly what 'scalar' and 'Scalar' actually reference, perhaps they are valid. i'm assuming they're typdef floats or something.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 15
• 22
• 16
• 13
• 14