/* * Util.cpp * * Copyright (C) 1999 Stephen F. White * 2004 Wu Qingwei * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file "COPYING" for details); if * not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ #include "stdafx.h" #include "Util.h" #include "Matrix.h" #include "TheApp.h" #include float boxCorners[8][3] = { { -1.0f, -1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { 1.0f, 1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, }; int boxIndices[24] = { TLF, BLF, BRF, TRF, // front TRF, BRF, BRB, TRB, // right side TRB, BRB, BLB, TLB, // back TLB, BLB, BLF, TLF, // left side TLB, TLF, TRF, TRB, // top BLF, BLB, BRB, BRF, // bottom }; float boxNormals[6][3] = { { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f }, { -1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, }; float boxTexCoords[4][2] = { { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 1.0f }, }; float spereCorners[6][3] = { { 0.0f, 1.0f,0.0f }, { 0.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, { 0.0f, -0.0f, -1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f,1.0f }, }; float CylinderCorners[6][3] = { { 0.0f, 1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, { 0.0f, -0.0f, -1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, }; float ConeCorners[5][3] = { { 0.0f, 1.0f, 0.0f }, { 1.0f, -1.0f, 0.0f }, {-1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 1.0f }, { 0.0f, -1.0f, -1.0f } }; void Util::DrawBox(float sizeX, float sizeY, float sizeZ) { glPushMatrix(); glScalef(sizeX, sizeY, sizeZ); glBegin(GL_QUADS); for (int i = 0; i < 24; i++) { glNormal3fv( boxNormals[i / 4] ); glTexCoord2fv( boxTexCoords[i % 4] ); glVertex3fv( boxCorners[boxIndices[i]] ); } glEnd(); glPopMatrix(); } // // IntersectSphere // // intersect a ray in 3-space (x1, y1, z1)->(x2, y2, z2) with a unit sphere // at the origin return the nearest point Vec3f Util::IntersectSphere(float x1, float y1, float z1, float x2, float y2, float z2) { float i = x2 - x1; float j = y2 - y1; float k = z2 - z1; float a = i * i + j * j + k * k; float b = 2 * i * x1 + 2 * j * y1 + 2 * k * z1; float c = x1 * x1 + y1 * y1 + z1 * z1 - 1; if (a == 0.0f) return Vec3f(0.0f, 0.0f, 0.0f); float t = -b + (float) sqrt(b * b - 4.0f * a * c) / 2.0f * a; return Vec3f(x1 + t * i, y1 + t * j, z1 + t * k); } // // IntersectLines() // // return "true" if the given 2D lines (x1, y1) - (x2, y2) and // (x3, y3) - (x4, y4) intersect // bool Util::IntersectLines(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { int denom = (x4 - x3) * (y2 - y1) - (y4 - y3) * (x2 - x1); int num = (y3 - y1) * (x2 - x1) - (x3 - x1) * (y2 - y1); float p2 = (float) num / (float) denom; float p1; if (x1 != x2) { p1 = (x3 + p2 * (x4 - x3) - x1) / (x2 - x1); } else if (y1 != y2) { p1 = (y3 + p2 * (y4 - y3) - y1) / (y2 - y1); } else { return false; } return p1 >= 0.0f && p1 <= 1.0f && p2 >= 0.0f && p2 <= 1.0f; } float Util::grayFromColor(const float r, const float g, const float b) { return (r + g + b) / 3.0; } void Util::myGlColor3f(float r, float g, float b) { if (TheApp->isAnaglyphStereo()) { float gray = Util::grayFromColor(r, g, b); glColor3f(gray, gray, gray); } else glColor3f(r, g, b); } void Util::myGlColor4f(float r, float g, float b, float a) { if (TheApp->isAnaglyphStereo()) { float gray = Util::grayFromColor(r, g, b); glColor4f(gray, gray, gray, a); } else glColor4f(r, g, b, a); } void Util::myGlColor3fv(const float *c) { if (TheApp->isAnaglyphStereo()) { float gray = Util::grayFromColor(c[0], c[1], c[2]); glColor3f(gray, gray, gray); } else glColor3fv(c); } void Util::myGlColor4fv(const float *c) { if (TheApp->isAnaglyphStereo()) { float gray = Util::grayFromColor(c[0], c[1], c[2]); glColor4f(gray, gray, gray, c[3]); } else glColor4fv(c); } void Util::myGlMaterialfv(GLenum face, GLenum pname, const float *c) { float has4Colors = false; if (TheApp->isAnaglyphStereo()) switch (pname) { case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_EMISSION: case GL_AMBIENT_AND_DIFFUSE: has4Colors = true; break; case GL_COLOR_INDEXES: // GL_COLOR_INDEXES not supported yet assert(false); } if (has4Colors) { float gray = Util::grayFromColor(c[0], c[1], c[2]); float color[4] = { gray, gray, gray, c[3] }; glMaterialfv(face, pname, color); } else glMaterialfv(face, pname, c); }