#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 ] = [ 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;
}
//Add 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;
}
//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
//Swap between radians and degrees
Scalar radToDeg(Scalar rad)
{
return 360.0 * rad / (3.14159 * 2.0);
}
Scalar degToRad(Scalar deg)
{
return (3.14159 * 2.0) * deg / 360.0;
}
//TO DO:
//Z-buffer
//drawLine and disk functions that use the zbuffer
🔒 Locked
🎮 Unity
Odd problems with raycaster...please help!
Advertisement
Original Post
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: 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?
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.
btw how much of that is your code? maybe the original source may be of help.
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 =
hope that helps.
as compared to
line 736 =
Scalar Camera::getRatioVU(){ return v.length() / u.length();} <-- line 736hope that helps.
scalar Camera::resetSkewV() { /* insert function here */ }
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
Kyle
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)
*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)
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.
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.
come on! could someone please help!
well, since you aren't a coder i'm not sure what you can do. but i'll spare you the lecture.
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.
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::resetSkew
U(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.
The author's name is Lode Vandevenne.
His GameDev.net username is Lode.
His website is http://www.student.kuleuven.ac.be/~m0216922/CG/
and it's full of great tutorials so i suggest you read more of the tutorials.
--------------------------------------------------------------
Perhaps you should read "all" of the tutorials on the site, maybe even the one on 3D Math.
this is what i changed to fix the errors using MSVC6.0
original code:
my edit:
His GameDev.net username is Lode.
His website is http://www.student.kuleuven.ac.be/~m0216922/CG/
and it's full of great tutorials so i suggest you read more of the tutorials.
--------------------------------------------------------------
Quote:
I know ill never learn, I never really wanted to learn the code in this file. it was never even taught in the tutorial.
Perhaps you should read "all" of the tutorials on the site, maybe even the one on 3D Math.
this is what i changed to fix the errors using MSVC6.0
original code:
//makes u, v and dir perpendicular by using cross product, maintains exact direction and roll if only v was skewedscalar 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 skewedscalar Camera::resetSkewV(){ Scalar oldZoomU = getZoomU(); Scalar oldZoomV = getZoomV(); v = cross(dir, u); u = cross(dir, -v); setZoomU(oldZoomU); setZoomV(oldZoomV);}my edit:
//makes u, v and dir perpendicular by using cross product, maintains exact direction and roll if only v was skewedVector3 Camera::resetSkewU(){ Scalar oldZoomU = getZoomU(); Scalar oldZoomV = getZoomV(); u = cross(dir, v); v = cross(dir, -u); setZoomU(oldZoomU); setZoomV(oldZoomV); // added due to error return u;}//makes u, v and dir perpendicular by using cross product, maintains exact direction and roll if only u was skewedVector3 Camera::resetSkewV(){ Scalar oldZoomU = getZoomU(); Scalar oldZoomV = getZoomV(); v = cross(dir, u); u = cross(dir, -v); setZoomU(oldZoomU); setZoomV(oldZoomV); //added due to error return v;}
Thank you very much! sorry if I annoyed anyone with this. ill rate you all up.
I got more errors when I changed my code to what axenation wrote.
--------------------Configuration: Wolfenstein raycaster - Win32 Debug--------------------
Compiling...
Q3DMath.cpp
Linking...
main.obj : error LNK2001: unresolved external symbol "unsigned char * inkeys" (?inkeys@@3PAEA)
main.obj : error LNK2001: unresolved external symbol "void __cdecl readKeys(void)" (?readKeys@@YAXXZ)
main.obj : error LNK2001: unresolved external symbol "void __cdecl cls(struct ColorRGB)" (?cls@@YAXUColorRGB@@@Z)
main.obj : error LNK2001: unresolved external symbol "void __cdecl redraw(void)" (?redraw@@YAXXZ)
main.obj : error LNK2001: unresolved external symbol "int __cdecl fprint(double,int,int,int,struct ColorRGB,bool,struct ColorRGB,bool,int)" (?fprint@@YAHNHHHUColorRGB@@_N01H@Z)
main.obj : error LNK2001: unresolved external symbol "float __cdecl getTime(void)" (?getTime@@YAMXZ)
main.obj : error LNK2001: unresolved external symbol "bool __cdecl verLine(int,int,int,struct ColorRGB)" (?verLine@@YA_NHHHUColorRGB@@@Z)
main.obj : error LNK2001: unresolved external symbol "struct ColorRGB __cdecl operator/(struct ColorRGB,int)" (??K@YA?AUColorRGB@@U0@H@Z)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall ColorRGB::ColorRGB(unsigned char,unsigned char,unsigned char)" (??0ColorRGB@@QAE@EEE@Z)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall ColorRGB::ColorRGB(void)" (??0ColorRGB@@QAE@XZ)
main.obj : error LNK2001: unresolved external symbol "int h" (?h@@3HA)
Q3DMath.obj : error LNK2001: unresolved external symbol "int h" (?h@@3HA)
main.obj : error LNK2001: unresolved external symbol "int w" (?w@@3HA)
Q3DMath.obj : error LNK2001: unresolved external symbol "int w" (?w@@3HA)
main.obj : error LNK2001: unresolved external symbol "bool __cdecl done(void)" (?done@@YA_NXZ)
main.obj : error LNK2001: unresolved external symbol "void
__cdecl screen(int,int,bool,char *)" (?screen@@YAXHH_NPAD@Z)
Q3DMath.obj : error LNK2001: unresolved external symbol "bool __cdecl onScreen(int,int)" (?onScreen@@YA_NHH@Z)
Debug/Wolfenstein raycaster.exe : fatal error LNK1120: 15 unresolved externals
Error executing link.exe.
Wolfenstein raycaster.exe - 18 error(s), 0 warning(s)
any help? also when I try to debug my project, I have to build it first. however, it wont build because there are errors in the code, so how am I supposed to debug?
--------------------Configuration: Wolfenstein raycaster - Win32 Debug--------------------
Compiling...
Q3DMath.cpp
Linking...
main.obj : error LNK2001: unresolved external symbol "unsigned char * inkeys" (?inkeys@@3PAEA)
main.obj : error LNK2001: unresolved external symbol "void __cdecl readKeys(void)" (?readKeys@@YAXXZ)
main.obj : error LNK2001: unresolved external symbol "void __cdecl cls(struct ColorRGB)" (?cls@@YAXUColorRGB@@@Z)
main.obj : error LNK2001: unresolved external symbol "void __cdecl redraw(void)" (?redraw@@YAXXZ)
main.obj : error LNK2001: unresolved external symbol "int __cdecl fprint(double,int,int,int,struct ColorRGB,bool,struct ColorRGB,bool,int)" (?fprint@@YAHNHHHUColorRGB@@_N01H@Z)
main.obj : error LNK2001: unresolved external symbol "float __cdecl getTime(void)" (?getTime@@YAMXZ)
main.obj : error LNK2001: unresolved external symbol "bool __cdecl verLine(int,int,int,struct ColorRGB)" (?verLine@@YA_NHHHUColorRGB@@@Z)
main.obj : error LNK2001: unresolved external symbol "struct ColorRGB __cdecl operator/(struct ColorRGB,int)" (??K@YA?AUColorRGB@@U0@H@Z)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall ColorRGB::ColorRGB(unsigned char,unsigned char,unsigned char)" (??0ColorRGB@@QAE@EEE@Z)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall ColorRGB::ColorRGB(void)" (??0ColorRGB@@QAE@XZ)
main.obj : error LNK2001: unresolved external symbol "int h" (?h@@3HA)
Q3DMath.obj : error LNK2001: unresolved external symbol "int h" (?h@@3HA)
main.obj : error LNK2001: unresolved external symbol "int w" (?w@@3HA)
Q3DMath.obj : error LNK2001: unresolved external symbol "int w" (?w@@3HA)
main.obj : error LNK2001: unresolved external symbol "bool __cdecl done(void)" (?done@@YA_NXZ)
main.obj : error LNK2001: unresolved external symbol "void
__cdecl screen(int,int,bool,char *)" (?screen@@YAXHH_NPAD@Z)
Q3DMath.obj : error LNK2001: unresolved external symbol "bool __cdecl onScreen(int,int)" (?onScreen@@YA_NHH@Z)
Debug/Wolfenstein raycaster.exe : fatal error LNK1120: 15 unresolved externals
Error executing link.exe.
Wolfenstein raycaster.exe - 18 error(s), 0 warning(s)
any help? also when I try to debug my project, I have to build it first. however, it wont build because there are errors in the code, so how am I supposed to debug?
Well, your program has compiled. It's the linking stage that it's failing at now. Basically, what is happening is that you have declared the functions prototypes, but the linker cannot find the actual code that these prototypes refer to. There's probably a library file that needs including into the project. QuickCG.lib or QuickCG.dll perhaps?
Could you give the list of all the files in the project?
Could you give the list of all the files in the project?
sure. here are al the files and the code that goes with them.
main.cpp
Q3DMath.cpp
QuickCG.cpp
Q3DMath.h
QuickCG.h
also, before you ask, I do have sdl linked to my project properly.
main.cpp
#include <math.h>#include <stdio.h>#include <iostream>#include <SDL/SDL.h>#include "QuickCG.h"#pragma comment(lib, "SDL.lib")#pragma comment(lib, "SDLmain.lib")#define mapWidth 24#define mapHeight 24int worldMap[mapWidth][mapHeight]={ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1, 1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1, 1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};Scalar rayPosX = 22, rayPosY = 12;Scalar rayDirX = -1, rayDirY = 0;Scalar posX = 22, posY = 12; //x and y start positionScalar dirX = -1, dirY = 0; //initial direction vectorScalar planeX = 0, planeY = 0.66; //the 2d raycaster version of camera planeScalar time = 0; //time of current frameScalar oldTime = 0; //time of previous frameint main(int argc, char *argv[]){ screen(640, 480, false, "Raycaster"); while(!done()) { SDL_Delay(5); //sacrifice 5 milliseconds per frame to free some CPU time for(int x = 0; x < w; x++) { //calculate ray position and direction Scalar cameraX = 2 * x / Scalar(w) - 1; //x-coordinate in camera space Scalar rayPosX = posX; Scalar rayPosY = posY; Scalar rayDirX = dirX + planeX * cameraX; Scalar rayDirY = dirY + planeY * cameraX; //which box of the map we're in int mapX = int(rayPosX); int mapY = int(rayPosY); //length of ray from current position to next x or y-side Scalar sideDistX; Scalar sideDistY; //length of ray from one x or y-side to next x or y-side Scalar deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX)); Scalar deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY)); Scalar perpWallDist; //what direction to step in x or y-direction (either +1 or -1) int stepX; int stepY; int hit = 0; //was there a wall hit? int side; //was a NS or a EW wall hit? //calculate step and initial sideDist if (rayDirX < 0) { stepX = -1; sideDistX = (rayPosX - mapX) * deltaDistX; } else { stepX = 1; sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX; } if (rayDirY < 0) { stepY = -1; sideDistY = (rayPosY - mapY) * deltaDistY; } else { stepY = 1; sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY; } //perform DDA while (hit == 0) { //jump to next map square, OR in x-direction, OR in y-direction if (sideDistX < sideDistY) { sideDistX += deltaDistX; mapX += stepX; side = 0; } else { sideDistY += deltaDistY; mapY += stepY; side = 1; } //Check if ray has hit a wall if (worldMap[mapX][mapY] > 0) hit = 1; } //Calculate distance projected on camera direction (oblique distance will give fisheye effect!) if (side == 0) perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX); else perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY); //Calculate height of line to draw on screen int lineHeight = abs(int(h / perpWallDist)); //calculate lowest and highest pixel to fill in current stripe int drawStart = -lineHeight / 2 + h / 2; if(drawStart < 0)drawStart = 0; int drawEnd = lineHeight / 2 + h / 2; if(drawEnd >= h)drawEnd = h - 1; //choose wall color ColorRGB color; switch(worldMap[mapX][mapY]) { case 1: color = RGB_Red; break; //red case 2: color = RGB_Green; break; //green case 3: color = RGB_Blue; break; //blue case 4: color = RGB_White; break; //white default: color = RGB_Yellow; break; //yellow } //give x and y sides different brightness if (side == 1) {color = color / 2;} //draw the pixels of the stripe as a vertical line verLine(x, drawStart, drawEnd, color); } //timing for input and FPS counter oldTime = time; time = getTime(); Scalar frameTime = (time - oldTime) / 1000.0; //frameTime is the time this frame has taken, in seconds fprint(1.0 / frameTime); //FPS counter redraw(); cls(); //speed modifiers Scalar moveSpeed = frameTime * 5.0; //the constant value is in squares/second Scalar rotSpeed = frameTime * 3.0; //the constant value is in radians/second readKeys(); //move forward if no wall in front of you if (inkeys[SDLK_UP]) { if(worldMap[int(posX + dirX * moveSpeed)][int(posY)] == false) posX += dirX * moveSpeed; if(worldMap[int(posX)][int(posY + dirY * moveSpeed)] == false) posY += dirY * moveSpeed; } //move backwards if no wall behind you if (inkeys[SDLK_DOWN]) { if(worldMap[int(posX - dirX * moveSpeed)][int(posY)] == false) posX -= dirX * moveSpeed; if(worldMap[int(posX)][int(posY - dirY * moveSpeed)] == false) posY -= dirY * moveSpeed; } //rotate to the right if (inkeys[SDLK_RIGHT]) { //both camera direction and camera plane must be rotated Scalar oldDirX = dirX; dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed); dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed); Scalar oldPlaneX = planeX; planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed); planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed); } //rotate to the left if (inkeys[SDLK_LEFT]) { //both camera direction and camera plane must be rotated Scalar oldDirX = dirX; dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed); dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed); Scalar oldPlaneX = planeX; planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed); planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed); } } return 0;}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 vectorsVector3 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 vectorVector3 operator-(Vector3 v){ Vector3 u; u.x = -v.x; u.y = -v.y; u.z = -v.z; return u;}//Add two vectorsVector3 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 scalarVector3 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 scalarVector3 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 scalarVector3 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 matrixvoid 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;} //Add two matricesMatrix3 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 matricesMatrix3 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 scalarMatrix3 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 scalarMatrix3 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 scalarMatrix3 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 vectorVector3 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 vectorVector3 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 matrixMatrix3 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 parametersCamera::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 pointvoid 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 skyThe plane you're standing on is the XZ plane, and Y points to the skyPitch 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 directionNOT useful for spacecrafts etc... because there's no up or down in space and X, Y and Z axes have no physical meaning thereonly 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 amountvoid Camera::pitch(Scalar angle){ rotate(u, angle);}/*Roll is only necessary for spacegames, flightsimulators or rare effects of FPS gamesRoll 0° = cam.u parallel with XZ plane, cam.v points upwardsRoll +90° = cam.v parallel with XZ plane, cam.u points downwardsRoll +-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 upwardsIn 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 skewedVector3 Camera::resetSkewU(){ Scalar oldZoomU = getZoomU(); Scalar oldZoomV = getZoomV(); u = cross(dir, v); v = cross(dir, -u); setZoomU(oldZoomU); setZoomV(oldZoomV); // added due to error return u;}//makes u, v and dir perpendicular by using cross product, maintains exact direction and roll if only u was skewedVector3 Camera::resetSkewV(){ Scalar oldZoomU = getZoomU(); Scalar oldZoomV = getZoomV(); v = cross(dir, u); u = cross(dir, -v); setZoomU(oldZoomU); setZoomV(oldZoomV); //added due to error return v;}//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 Uvoid Camera::setRatioVU(Scalar ratio){ u.normalize(); u = u * v.length() / ratio; generateMatrix();} //scale U, V and Dir without changing what you seeScalar 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//Swap between radians and degreesScalar radToDeg(Scalar rad){ return 360.0 * rad / (3.14159 * 2.0);} Scalar degToRad(Scalar deg){ return (3.14159 * 2.0) * deg / 360.0;} //TO DO://Z-buffer//drawLine and disk functions that use the zbufferQuickCG.cpp
#ifndef _quickcg_h_#define _quickcg_h_#include <SDL/SDL.h>//////////////////////////////////////////////////////////////////////////////////MIN, MAX and Scalar/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////use with care: if a or b is a function, it's executed twice!#ifndef max#define max(a,b) ((a)>(b)?(a):(b))#endif#ifndef min#define min(a,b) ((a)<(b)?(a):(b))#endif//define Scalar either as float or as double, at your choice#define Scalar double//////////////////////////////////////////////////////////////////////////////////COLOR STRUCTS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////struct ColorRGB8bit;//a color with 3 components: r, g and bstruct ColorRGB{ int r; int g; int b; ColorRGB(Uint8 r, Uint8 g, Uint8 b); ColorRGB(ColorRGB8bit color); ColorRGB();}; ColorRGB operator+(ColorRGB color, ColorRGB color2);ColorRGB operator-(ColorRGB color, ColorRGB color2);ColorRGB operator*(ColorRGB color, int a);ColorRGB operator*(int a, ColorRGB color);ColorRGB operator/(ColorRGB color, int a);bool operator==(ColorRGB color, ColorRGB color2);bool operator!=(ColorRGB color, ColorRGB color2);#define RGB_Black ColorRGB( 0, 0, 0)#define RGB_Red ColorRGB(255, 0, 0)#define RGB_Green ColorRGB( 0, 255, 0)#define RGB_Blue ColorRGB( 0, 0, 255)#define RGB_Cyan ColorRGB( 0, 255, 255)#define RGB_Magenta ColorRGB(255, 0, 255)#define RGB_Yellow ColorRGB(255, 255, 0)#define RGB_White ColorRGB(255, 255, 255) #define RGB_Gray ColorRGB(128, 128, 128)#define RGB_Grey ColorRGB(192, 192, 192)#define RGB_Maroon ColorRGB(128, 0, 0)#define RGB_Darkgreen ColorRGB( 0, 128, 0)#define RGB_Navy ColorRGB( 0, 0, 128)#define RGB_Teal ColorRGB( 0, 128, 128)#define RGB_Purple ColorRGB(128, 0, 128)#define RGB_Olive ColorRGB(128, 128, 0)//a color with 3 components: r, g and bstruct ColorRGB8bit{ Uint8 r; Uint8 g; Uint8 b; ColorRGB8bit(Uint8 r, Uint8 g, Uint8 b); ColorRGB8bit(ColorRGB color); ColorRGB8bit();}; //a color with 3 components: h, s and lstruct ColorHSL{ int h; int s; int l; ColorHSL(Uint8 h, Uint8 s, Uint8 l); ColorHSL();}; //a color with 3 components: h, s and vstruct ColorHSV{ int h; int s; int v; ColorHSV(Uint8 h, Uint8 s, Uint8 v); ColorHSV();};//////////////////////////////////////////////////////////////////////////////////GLOBAL VARIABLES//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////extern SDL_Surface *scr; //the single SDL surface usedextern int w;extern int h;extern Uint8 *inkeys;//////////////////////////////////////////////////////////////////////////////////BASIC SCREEN FUNCTIONS////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void screen(int width = 640, int height = 400, bool fullscreen = 0, char *text = " ");void lock();void unlock();void redraw();void cls(ColorRGB color = RGB_Black);void pset(int x, int y, ColorRGB color);ColorRGB pget(int x, int y);void drawBuffer(Uint32 *buffer);bool onScreen(int x, int y);//////////////////////////////////////////////////////////////////////////////////NON GRAPHICAL FUNCTIONS///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void sleep();void waitFrame(float oldTime, float mspf);bool done();void end();void readKeys();void getMouseState(int & mouseX, int & mouseY);void getMouseState(int & mouseX, int & mouseY, bool & LMB, bool & RMB);float getTime();//////////////////////////////////////////////////////////////////////////////////2D SHAPES/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////bool horLine(int y, int x1, int x2, ColorRGB color);bool verLine(int x, int y1, int y2, ColorRGB color);bool drawLine(int x1, int y1, int x2, int y2, ColorRGB color);bool drawCircle(int xc, int yc, int radius, ColorRGB color);bool drawDisk(int xc, int yc, int radius, ColorRGB color);bool drawRect(int x1, int y1, int x2, int y2, ColorRGB color);bool clipLine(int x1,int y1,int x2, int y2, int & x3, int & y3, int & x4, int & y4);//////////////////////////////////////////////////////////////////////////////////COLOR CONVERSIONS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ColorHSL RGBtoHSL(ColorRGB colorRGB);ColorRGB HSLtoRGB(ColorHSL colorHSL);ColorHSV RGBtoHSV(ColorRGB colorRGB);ColorRGB HSVtoRGB(ColorHSV colorHSV);Uint32 RGBtoINT(ColorRGB colorRGB);ColorRGB INTtoRGB(Uint32 colorINT);//////////////////////////////////////////////////////////////////////////////////BMP FUNCTIONS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int loadBMP(char *filename, ColorRGB *image, int w, int h);int loadBMP(char *filename, Uint32 *image, int w, int h);//////////////////////////////////////////////////////////////////////////////////TEXT FUNCTIONS////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////extern const bool font[256][8][8];static void inline drawLetter(unsigned char n, int x, int y, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);int print(char *text, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, int forceLength=0);int iprint(int a, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, bool orderSigns=0, int forceLength=0);int iprint(Uint32 a, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, bool orderSigns=0, int forceLength=0);int fprint(double a, int length = 0, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, bool orderSigns=0, int forceLength=0);int cprint(unsigned char n, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);//////////////////////////////////////////////////////////////////////////////////TEXT INPUT FUNCTIONS//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Uint8 getChar(char * message = "", int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);void getString(char * text, int length, char * message = "", int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);Scalar getScalar(char * message = "", int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);#endifQ3DMath.h
#ifndef __3DMATH_H__#define __3DMATH_H__#include "QuickCG.h"////////////////////////////////////////////////////////////////////////////////// [ x ] //// Vector Class [ y ] //// [ z ] //////////////////////////////////////////////////////////////////////////////////class Vector3{ public: Scalar x; Scalar y; Scalar z; Vector3(Scalar x, Scalar y, Scalar z); Vector3(); Scalar length(); void normalize(); Scalar distance(Vector3 v); Scalar dot(Vector3 v); Vector3 cross(Vector3 v);};Scalar length(Vector3 v);Vector3 normalize(Vector3 v);Scalar distance(Vector3 v, Vector3 w); Scalar dot(Vector3 v, Vector3 w);Vector3 cross(Vector3 v, Vector3 w);Vector3 operator-(Vector3 v, Vector3 w);Vector3 operator-(Vector3 v);Vector3 operator+(Vector3 v, Vector3 w);Vector3 operator*(Vector3 v, Scalar a);Vector3 operator*(Scalar a, Vector3 v);Vector3 operator/(Vector3 v, Scalar a);Scalar vectorAngle(Vector3 v, Vector3 w);Vector3 rotateAroundArbitrary(Vector3 v, Vector3 axis, Scalar angle);////////////////////////////////////////////////////////////////////////////////// [ a b c ] //// Matrix Class [ d e f ] //// [ g h i ] //////////////////////////////////////////////////////////////////////////////////class Matrix3{ public: Scalar a; Scalar b; Scalar c; Scalar d; Scalar e; Scalar f; Scalar g; Scalar h; Scalar i; Matrix3(Scalar a, Scalar b, Scalar c, Scalar d, Scalar e, Scalar f, Scalar g, Scalar h, Scalar i); Matrix3(); void transpose(); Scalar determinant(); void inverse(); };Matrix3 transpose(Matrix3 A);Scalar determinant(Matrix3 A);Matrix3 inverse(Matrix3 A);Matrix3 operator+(Matrix3 A, Matrix3 B);Matrix3 operator-(Matrix3 A, Matrix3 B);Matrix3 operator*(Matrix3 A, Scalar a);Matrix3 operator*(Scalar a, Matrix3 A);Matrix3 operator/(Matrix3 A, Scalar a);Vector3 operator*(Matrix3 A, Vector3 v);Vector3 operator*(Vector3 v, Matrix3 A);Matrix3 operator*(Matrix3 A, Matrix3 B);////////////////////////////////////////////////////////////////////////////////// [ u.x v.x dir.x ] [ pos.x ] //// Camera Class [ u.y v.y dir.y ] + [ pos.y ] //// [ u.z v.z dir.z ] [ pos.z ] //////////////////////////////////////////////////////////////////////////////////class Camera{ public: Scalar nearClip; //near clipping plane Scalar farClip; //far clipping plane 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); //Get and Set the 4 important vectors Vector3 getU(); //the "right" vector of the camera, x coordinate of screen Vector3 getV(); //the "up" vector of the camera, y coordinate of screen Vector3 getDir(); //the direction of the camera, vector that points into the screen (z direction) Vector3 getPos(); //the position of the camera in world coordinates void setDir(Vector3 newDir); void setU(Vector3 newY); void setV(Vector3 newV); void setPos(Vector3 newPos); //move and rotate with vectors void move(Vector3 offset); void rotate(Vector3 axis, Scalar angle); void setLookDir(Vector3 newDir); void lookAt(Vector3 lookAtMe); //get and set distance to a certain point Scalar getDist(Vector3 point); void setDist(Vector3 point, Scalar dist); //get and set zoom Scalar getZoomU(); Scalar getZoomV(); void setZoomU(Scalar a); void setZoomV(Scalar a); void zoom(Scalar a); void zoomU(Scalar a); void zoomV(Scalar a); //get and set FOV Scalar getFOVU(); Scalar getFOVV(); void setFOVU(Scalar angle); void setFOVV(Scalar angle); //get and set pitch, yaw and roll (these are NOT native parameters of the camera and should normally never be needed!) Scalar getYaw(); Scalar getPitch(); Scalar getRoll(); void setYaw(Scalar angle); void setPitch(Scalar angle); void setRoll(Scalar angle); void yawPlanet(Scalar angle); void yawSpace(Scalar angle); void pitch(Scalar angle); void roll(Scalar angle); //make camera orthogonal (reset skewing) Vector3 resetSkewU(); Vector3 resetSkewV(); //set screen ratio of the camera (ratio of length of u and v, e.g. 4:3, 16:9, 640:480, ...) Scalar getRatioUV(); Scalar getRatioVU(); void setRatioUV(Scalar ratio); void setRatioVU(Scalar ratio); //scale U, V and Dir without changing what you see Scalar getScale(); void setScale(Scalar dirLength); void scale(Scalar factor); //generate, get and use the camera matrix to transform points void generateMatrix(); Matrix3 getMatrix(); Matrix3 getInvMatrix(); void setMatrix(Matrix3 matrix); //sets the u, v and dir vector to given matrix (and generates the actual matrix too of course) Vector3 transform(Vector3 v); bool projectOnScreen(Vector3 point, int & x, int & y, Scalar & z); bool projectOnScreen(Vector3 point, int & x, int & y); bool camSpaceToScreen(Vector3 point, int & x, int & y); private: //the camera plane, described by the vectors u and v, is described by "z = 0" in camera space Vector3 pos; //the location of the camera Vector3 u; //horizontal vector, horizontal side of computer screen Vector3 v; //vertical "up" vector, vertical side of computer screen Vector3 dir; //direction of the camera, direction of the projection Matrix3 camMatrix; //the camera matrix, is nothing more than the column vectors u, v and dir in one matrix Matrix3 invCamMatrix; //the inverse of the camera matrix };//Auxiliary functions//swap between radians and degreesScalar radToDeg(Scalar rad);Scalar degToRad(Scalar deg);#endifQuickCG.h
#ifndef _quickcg_h_#define _quickcg_h_#include <SDL/SDL.h>//////////////////////////////////////////////////////////////////////////////////MIN, MAX and Scalar/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////use with care: if a or b is a function, it's executed twice!#ifndef max#define max(a,b) ((a)>(b)?(a):(b))#endif#ifndef min#define min(a,b) ((a)<(b)?(a):(b))#endif//define Scalar either as float or as double, at your choice#define Scalar double//////////////////////////////////////////////////////////////////////////////////COLOR STRUCTS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////struct ColorRGB8bit;//a color with 3 components: r, g and bstruct ColorRGB{ int r; int g; int b; ColorRGB(Uint8 r, Uint8 g, Uint8 b); ColorRGB(ColorRGB8bit color); ColorRGB();}; ColorRGB operator+(ColorRGB color, ColorRGB color2);ColorRGB operator-(ColorRGB color, ColorRGB color2);ColorRGB operator*(ColorRGB color, int a);ColorRGB operator*(int a, ColorRGB color);ColorRGB operator/(ColorRGB color, int a);bool operator==(ColorRGB color, ColorRGB color2);bool operator!=(ColorRGB color, ColorRGB color2);#define RGB_Black ColorRGB( 0, 0, 0)#define RGB_Red ColorRGB(255, 0, 0)#define RGB_Green ColorRGB( 0, 255, 0)#define RGB_Blue ColorRGB( 0, 0, 255)#define RGB_Cyan ColorRGB( 0, 255, 255)#define RGB_Magenta ColorRGB(255, 0, 255)#define RGB_Yellow ColorRGB(255, 255, 0)#define RGB_White ColorRGB(255, 255, 255) #define RGB_Gray ColorRGB(128, 128, 128)#define RGB_Grey ColorRGB(192, 192, 192)#define RGB_Maroon ColorRGB(128, 0, 0)#define RGB_Darkgreen ColorRGB( 0, 128, 0)#define RGB_Navy ColorRGB( 0, 0, 128)#define RGB_Teal ColorRGB( 0, 128, 128)#define RGB_Purple ColorRGB(128, 0, 128)#define RGB_Olive ColorRGB(128, 128, 0)//a color with 3 components: r, g and bstruct ColorRGB8bit{ Uint8 r; Uint8 g; Uint8 b; ColorRGB8bit(Uint8 r, Uint8 g, Uint8 b); ColorRGB8bit(ColorRGB color); ColorRGB8bit();}; //a color with 3 components: h, s and lstruct ColorHSL{ int h; int s; int l; ColorHSL(Uint8 h, Uint8 s, Uint8 l); ColorHSL();}; //a color with 3 components: h, s and vstruct ColorHSV{ int h; int s; int v; ColorHSV(Uint8 h, Uint8 s, Uint8 v); ColorHSV();};//////////////////////////////////////////////////////////////////////////////////GLOBAL VARIABLES//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////extern SDL_Surface *scr; //the single SDL surface usedextern int w;extern int h;extern Uint8 *inkeys;//////////////////////////////////////////////////////////////////////////////////BASIC SCREEN FUNCTIONS////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void screen(int width = 640, int height = 400, bool fullscreen = 0, char *text = " ");void lock();void unlock();void redraw();void cls(ColorRGB color = RGB_Black);void pset(int x, int y, ColorRGB color);ColorRGB pget(int x, int y);void drawBuffer(Uint32 *buffer);bool onScreen(int x, int y);//////////////////////////////////////////////////////////////////////////////////NON GRAPHICAL FUNCTIONS///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void sleep();void waitFrame(float oldTime, float mspf);bool done();void end();void readKeys();void getMouseState(int & mouseX, int & mouseY);void getMouseState(int & mouseX, int & mouseY, bool & LMB, bool & RMB);float getTime();//////////////////////////////////////////////////////////////////////////////////2D SHAPES/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////bool horLine(int y, int x1, int x2, ColorRGB color);bool verLine(int x, int y1, int y2, ColorRGB color);bool drawLine(int x1, int y1, int x2, int y2, ColorRGB color);bool drawCircle(int xc, int yc, int radius, ColorRGB color);bool drawDisk(int xc, int yc, int radius, ColorRGB color);bool drawRect(int x1, int y1, int x2, int y2, ColorRGB color);bool clipLine(int x1,int y1,int x2, int y2, int & x3, int & y3, int & x4, int & y4);//////////////////////////////////////////////////////////////////////////////////COLOR CONVERSIONS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ColorHSL RGBtoHSL(ColorRGB colorRGB);ColorRGB HSLtoRGB(ColorHSL colorHSL);ColorHSV RGBtoHSV(ColorRGB colorRGB);ColorRGB HSVtoRGB(ColorHSV colorHSV);Uint32 RGBtoINT(ColorRGB colorRGB);ColorRGB INTtoRGB(Uint32 colorINT);//////////////////////////////////////////////////////////////////////////////////BMP FUNCTIONS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int loadBMP(char *filename, ColorRGB *image, int w, int h);int loadBMP(char *filename, Uint32 *image, int w, int h);//////////////////////////////////////////////////////////////////////////////////TEXT FUNCTIONS////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////extern const bool font[256][8][8];static void inline drawLetter(unsigned char n, int x, int y, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);int print(char *text, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, int forceLength=0);int iprint(int a, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, bool orderSigns=0, int forceLength=0);int iprint(Uint32 a, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, bool orderSigns=0, int forceLength=0);int fprint(double a, int length = 0, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black, bool orderSigns=0, int forceLength=0);int cprint(unsigned char n, int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);//////////////////////////////////////////////////////////////////////////////////TEXT INPUT FUNCTIONS//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Uint8 getChar(char * message = "", int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);void getString(char * text, int length, char * message = "", int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);Scalar getScalar(char * message = "", int x = 0, int y = 0, ColorRGB color = RGB_White, bool bg = 0, ColorRGB color2 = RGB_Black);#endifalso, before you ask, I do have sdl linked to my project properly.
Quote:
Original post by Ajare
That QuickCG.cpp file doesn't look right at all - in fact it looks just like QuickCG.h :)
Which would describe why he got those linkers errors. The compiler couldn't complain about have the same file twice because of the two preprocessor lines at the top of the file. i'm guessing you should go to Lode's website and download the QuickCG.cpp file again. Don't copy the one stormrunner posted above. It's not complete due to the forum cutting it off.
I didnt actually. I downloaded quickCg and then just put my own main in it. however, I seem to be linking it to SDL wrong, so ill have to check out lodes site to see how to do it.
I must have really bad luck with this. when I fix everything, I get more errors.(its not exactly the one stormrunner said, but it has something to do with time)
C:\Documents and Settings\Michael\Desktop\zip files\main.cpp
[Warning] In function
any help?
C:\Documents and Settings\Michael\Desktop\zip files\main.cpp
[Warning] In function
int SDL_main(int, char**)':
166 C:\Documents and Settings\Michael\Desktop\zip files\main.cpp
_oldTime' undeclared (first use this function)any help?
could someone help?
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement