/* QuickCG Copyright (c) 2004-2007, Lode Vandevenne All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __3DMATH_H__ #define __3DMATH_H__ #include "quickcg.h" //////////////////////////////////////////////////////////////////////////////// // [ x ] // // Vector Class [ y ] // // [ z ] // //////////////////////////////////////////////////////////////////////////////// class Vector3 { public: double x; double y; double z; Vector3(double x, double y, double z); Vector3(); double length() const; void normalize(); double distance(const Vector3& v) const; double dot(const Vector3& v) const; Vector3 cross(const Vector3& v) const; }; double length(const Vector3& v); Vector3 normalize(const Vector3& v); double distance(const Vector3& v, const Vector3& w); double dot(const Vector3& v, const Vector3& w); Vector3 cross(const Vector3& v, const Vector3& w); Vector3 operator-(const Vector3& v, const Vector3& w); Vector3 operator-(const Vector3& v); Vector3 operator+(const Vector3& v, const Vector3& w); Vector3 operator*(const Vector3& v, double a); Vector3 operator*(double a, const Vector3& v); Vector3 operator/(const Vector3& v, double a); double vectorAngle(const Vector3& v, const Vector3& w); Vector3 rotateAroundArbitrary(const Vector3& v, const Vector3& axis, double angle); //////////////////////////////////////////////////////////////////////////////// // [ a b c ] // // Matrix Class [ d e f ] // // [ g h i ] // //////////////////////////////////////////////////////////////////////////////// class Matrix3 { public: double a; double b; double c; double d; double e; double f; double g; double h; double i; Matrix3(double a, double b, double c, double d, double e, double f, double g, double h, double i); Matrix3(); void transpose(); double determinant() const; void invert(); }; Matrix3 transpose(const Matrix3& A); double determinant(const Matrix3& A); Matrix3 inverse(const Matrix3& A); Matrix3 operator+(const Matrix3& A, const Matrix3& B); Matrix3 operator-(const Matrix3& A, const Matrix3& B); Matrix3 operator*(const Matrix3& A, double a); Matrix3 operator*(double a, const Matrix3& A); Matrix3 operator/(const Matrix3& A, double a); Vector3 operator*(const Matrix3& A, const Vector3& v); Vector3 operator*(const Vector3& v, const Matrix3& A); Matrix3 operator*(const Matrix3& A, const 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: double nearClip; //near clipping plane double farClip; //far clipping plane Camera(); Camera(double posx, double posy, double posz, double ux, double uy, double uz, double vx, double vy, double vz, double dirx, double diry, double dirz, double nearClip, double 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(const Vector3& newDir); void setU(const Vector3& newY); void setV(const Vector3& newV); void setPos(const Vector3& newPos); //move and rotate with vectors void move(const Vector3& offset); void rotate(const Vector3& axis, double angle); void setLookDir(const Vector3& newDir); void lookAt(const Vector3& lookAtMe); //get and set distance to a certain point double getDist(const Vector3& point); void setDist(const Vector3& point, double dist); //get and set zoom double getZoomU(); double getZoomV(); void setZoomU(double a); void setZoomV(double a); void zoom(double a); void zoomU(double a); void zoomV(double a); //get and set FOV double getFOVU(); double getFOVV(); void setFOVU(double angle); void setFOVV(double angle); //get and set pitch, yaw and roll (these are NOT native parameters of the camera and should normally never be needed!) double getYaw(); double getPitch(); double getRoll(); void setYaw(double angle); void setPitch(double angle); void setRoll(double angle); void yawPlanet(double angle); void yawSpace(double angle); void pitch(double angle); void roll(double angle); //make camera orthogonal (reset skewing) void resetSkewU(); void resetSkewV(); //set screen ratio of the camera (ratio of length of u and v, e.g. 4:3, 16:9, 640:480, ...) double getRatioUV(); double getRatioVU(); void setRatioUV(double ratio); void setRatioVU(double ratio); //scale U, V and Dir without changing what you see double getScale(); void setScale(double dirLength); void scale(double factor); //generate, get and use the camera matrix to transform points void generateMatrix(); Matrix3 getMatrix(); Matrix3 getInvMatrix(); void setMatrix(const Matrix3& matrix); //sets the u, v and dir vector to given matrix (and generates the actual matrix too of course) Vector3 transform(const Vector3& v); bool projectOnScreen(const Vector3& point, int & x, int & y, double & z); bool projectOnScreen(const Vector3& point, int & x, int & y); bool camSpaceToScreen(const 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 degrees double radToDeg(double rad); double degToRad(double deg); #endif