Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
9.4 KiB

  1. /*
  2. * (c) Copyright 1993, Silicon Graphics, Inc.
  3. * ALL RIGHTS RESERVED
  4. * Permission to use, copy, modify, and distribute this software for
  5. * any purpose and without fee is hereby granted, provided that the above
  6. * copyright notice appear in all copies and that both the copyright notice
  7. * and this permission notice appear in supporting documentation, and that
  8. * the name of Silicon Graphics, Inc. not be used in advertising
  9. * or publicity pertaining to distribution of the software without specific,
  10. * written prior permission.
  11. *
  12. * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13. * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14. * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15. * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
  16. * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17. * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18. * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19. * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20. * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
  21. * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22. * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23. * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24. *
  25. * US Government Users Restricted Rights
  26. * Use, duplication, or disclosure by the Government is subject to
  27. * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28. * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29. * clause at DFARS 252.227-7013 and/or in similar or successor
  30. * clauses in the FAR or the DOD or NASA FAR Supplement.
  31. * Unpublished-- rights reserved under the copyright laws of the
  32. * United States. Contractor/manufacturer is Silicon Graphics,
  33. * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
  34. *
  35. * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36. */
  37. #ifndef POINT_H
  38. #define POINT_H
  39. #ifndef POINT_EXTERN
  40. #define POINT_EXTERN extern
  41. #endif
  42. const float point_fudge = .000001;
  43. class Point {
  44. public:
  45. inline Point operator=(Point a);
  46. inline Point operator=(GLfloat *a);
  47. inline Point operator+(Point a);
  48. inline Point operator+=(Point a);
  49. inline Point operator-(Point a);
  50. // This takes a cross-product
  51. inline Point operator*(Point b);
  52. inline Point operator*(GLfloat b);
  53. inline Point operator/(GLfloat b);
  54. inline Point operator/=(GLfloat b);
  55. inline GLfloat& operator[](int index);
  56. inline GLfloat dist(Point b);
  57. inline GLfloat dot(Point b);
  58. inline GLfloat mag();
  59. inline GLfloat magsquared();
  60. inline Point unit();
  61. inline void unitize();
  62. // Angle is in RADIANS
  63. inline Point rotate(Point axis, GLfloat angle);
  64. inline Point rotate(Point axis, GLfloat c, GLfloat s);
  65. inline void rotate_self(Point axis, GLfloat c, GLfloat s);
  66. Point rotate_abouty(GLfloat c, GLfloat s);
  67. // Returns point projected through proj_pt into XY plane
  68. // Does nothing if proj_pt - *this is parallel to XY plane
  69. inline Point project(Point proj_pt);
  70. inline void project_self(Point proj_pt);
  71. inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz);
  72. inline Point project_direction(Point direction);
  73. inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z);
  74. // This projects (px, py, pz) into this in direction (dx, dy, dz)
  75. inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  76. GLfloat x, GLfloat y, GLfloat z);
  77. // Returns point projected through light and refracted into XY
  78. // plane.
  79. // N is normal at point (ie normal at *this)
  80. // I is the index of refraction
  81. inline Point refract(Point light, Point N, GLfloat I);
  82. void refract_self(Point light, Point N, GLfloat I);
  83. Point refract_direction(Point light, Point N, GLfloat I);
  84. inline void glvertex();
  85. inline void glnormal();
  86. void print();
  87. void print(const char *format);
  88. GLfloat pt[4];
  89. private:
  90. };
  91. POINT_EXTERN Point val;
  92. #define DOT(a, b) (a.pt[0]*b.pt[0] + a.pt[1]*b.pt[1] + a.pt[2]*b.pt[2])
  93. #define THIS_DOT(b) (pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2])
  94. inline Point Point::operator=(Point a)
  95. {
  96. pt[0] = a.pt[0];
  97. pt[1] = a.pt[1];
  98. pt[2] = a.pt[2];
  99. pt[3] = a.pt[3];
  100. return *this;
  101. }
  102. inline Point Point::operator=(GLfloat *a)
  103. {
  104. pt[0] = a[0];
  105. pt[1] = a[1];
  106. pt[2] = a[2];
  107. pt[3] = 1;
  108. return *this;
  109. }
  110. inline Point Point::operator+(Point a)
  111. {
  112. val.pt[0] = pt[0] + a.pt[0];
  113. val.pt[1] = pt[1] + a.pt[1];
  114. val.pt[2] = pt[2] + a.pt[2];
  115. return val;
  116. }
  117. inline Point Point::operator+=(Point a)
  118. {
  119. pt[0] += a.pt[0];
  120. pt[1] += a.pt[1];
  121. pt[2] += a.pt[2];
  122. return *this;
  123. }
  124. inline Point Point::operator-(Point a)
  125. {
  126. val.pt[0] = pt[0] - a.pt[0];
  127. val.pt[1] = pt[1] - a.pt[1];
  128. val.pt[2] = pt[2] - a.pt[2];
  129. return val;
  130. }
  131. inline Point Point::operator*(Point b)
  132. {
  133. val.pt[0] = pt[1]*b.pt[2] - b.pt[1]*pt[2];
  134. val.pt[1] = pt[2]*b.pt[0] - b.pt[2]*pt[0];
  135. val.pt[2] = pt[0]*b.pt[1] - pt[1]*b.pt[0];
  136. return val;
  137. }
  138. inline Point Point::operator*(GLfloat b)
  139. {
  140. val.pt[0] = pt[0] * b;
  141. val.pt[1] = pt[1] * b;
  142. val.pt[2] = pt[2] * b;
  143. return val;
  144. }
  145. inline Point Point::operator/(GLfloat b)
  146. {
  147. val.pt[0] = pt[0] / b;
  148. val.pt[1] = pt[1] / b;
  149. val.pt[2] = pt[2] / b;
  150. return val;
  151. }
  152. inline Point Point::operator/=(GLfloat b)
  153. {
  154. pt[0] /= b;
  155. pt[1] /= b;
  156. pt[2] /= b;
  157. return *this;
  158. }
  159. inline GLfloat& Point::operator[](int index)
  160. {
  161. return pt[index];
  162. }
  163. inline GLfloat Point::dist(Point b)
  164. {
  165. return (*this - b).mag();
  166. }
  167. inline GLfloat Point::dot(Point b)
  168. {
  169. return pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2];
  170. }
  171. inline GLfloat Point::mag()
  172. {
  173. return (GLfloat)sqrt((float)(pt[0]*pt[0] + pt[1]*pt[1] +
  174. pt[2]*pt[2]));
  175. }
  176. inline GLfloat Point::magsquared()
  177. {
  178. return pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2];
  179. }
  180. inline Point Point::unit()
  181. {
  182. GLfloat m = (GLfloat)sqrt((float)(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]));
  183. val.pt[0] = pt[0] / m;
  184. val.pt[1] = pt[1] / m;
  185. val.pt[2] = pt[2] / m;
  186. return val;
  187. }
  188. inline void Point::unitize()
  189. {
  190. GLfloat m = (GLfloat)sqrt((float)(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]));
  191. pt[0] /= m;
  192. pt[1] /= m;
  193. pt[2] /= m;
  194. }
  195. inline Point Point::rotate(Point axis, GLfloat angle)
  196. {
  197. return rotate(axis, (GLfloat)cos((float)angle), (GLfloat)sin((float)angle));
  198. }
  199. inline Point Point::rotate(Point axis, GLfloat c, GLfloat s)
  200. {
  201. float x = (float)axis.pt[0], y = (float)axis.pt[1], z = (float)axis.pt[2], t = (float)(1.0 - c);
  202. float tx, ty;
  203. tx = t*x;
  204. /* Taking advantage of inside info that this is a common case */
  205. if (y == 0.0) {
  206. val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(-s*z) + pt[2]*(tx*z);
  207. val.pt[1] = pt[0]*(s*z) + pt[1]*c + pt[2]*(-s*x);
  208. val.pt[2] = pt[0]*(tx*z) + pt[1]*s*x + pt[2]*(t*z*z + c);
  209. } else {
  210. ty = t*y;
  211. val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(tx*y - s*z) +
  212. pt[2]*(tx*z + s*y);
  213. val.pt[1] = pt[0]*(tx*y + s*z) + pt[1]*(ty*y + c) +
  214. pt[2]*(ty*z - s*x);
  215. val.pt[2] = pt[0]*(tx*z - s*y) + pt[1]*(ty*z + s*x) +
  216. pt[2]*(t*z*z + c);
  217. }
  218. return val;
  219. }
  220. inline void Point::rotate_self(Point axis, GLfloat c, GLfloat s)
  221. {
  222. float Px, Py, Pz;
  223. float x = (float)axis.pt[0], y = (float)axis.pt[1], z = (float)axis.pt[2], t = (float)(1.0 - c);
  224. float tx, ty;
  225. tx = t*x;
  226. Px = pt[0];
  227. Py = pt[1];
  228. Pz = pt[2];
  229. /* Taking advantage of inside info that this is a common case */
  230. if (!y) {
  231. pt[0] = Px*(tx*x + c) + Py*(-s*z) + Pz*(tx*z);
  232. pt[1] = Px*(s*z) + Py*c + Pz*(-s*x);
  233. pt[2] = Px*(tx*z) + Py*s*x + Pz*(t*z*z + c);
  234. } else {
  235. ty = t*y;
  236. pt[0] = Px*(tx*x + c) + Py*(tx*y - s*z) +
  237. Pz*(tx*z + s*y);
  238. pt[1] = Px*(tx*y + s*z) + Py*(ty*y + c) +
  239. Pz*(ty*z - s*x);
  240. pt[2] = Px*(tx*z - s*y) + Py*(ty*z + s*x) +
  241. Pz*(t*z*z + c);
  242. }
  243. }
  244. inline void Point::glvertex()
  245. {
  246. glVertex3fv(pt);
  247. }
  248. inline void Point::glnormal()
  249. {
  250. glNormal3fv(pt);
  251. }
  252. inline Point Point::project(Point proj_pt)
  253. {
  254. GLfloat dirx = pt[0] - proj_pt.pt[0],
  255. diry = pt[1] - proj_pt.pt[1],
  256. dirz = pt[2] - proj_pt.pt[2];
  257. GLfloat t;
  258. if (fabs(dirz) < point_fudge) val = *this;
  259. else {
  260. t = -proj_pt.pt[2] / dirz;
  261. val.pt[0] = proj_pt.pt[0] + dirx*t;
  262. val.pt[1] = proj_pt.pt[1] + diry*t;
  263. val.pt[2] = 0.0;
  264. }
  265. return val;
  266. }
  267. // This naively assumes that proj_pt[z] != this->pt[z]
  268. inline void Point::project_self(Point proj_pt)
  269. {
  270. GLfloat dirx = pt[0] - proj_pt.pt[0],
  271. diry = pt[1] - proj_pt.pt[1],
  272. dirz = pt[2] - proj_pt.pt[2];
  273. GLfloat t;
  274. t = -proj_pt.pt[2] / dirz;
  275. pt[0] = proj_pt.pt[0] + dirx*t;
  276. pt[1] = proj_pt.pt[1] + diry*t;
  277. pt[2] = 0.0;
  278. }
  279. inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz)
  280. {
  281. GLfloat dirx = pt[0] - px,
  282. diry = pt[1] - py,
  283. dirz = pt[2] - pz, t;
  284. t = -pz / dirz;
  285. pt[0] = px + dirx*t;
  286. pt[1] = py + diry*t;
  287. pt[2] = 0.0;
  288. }
  289. inline Point Point::project_direction(Point direction) {
  290. GLfloat t;
  291. t = -pt[2] / direction.pt[2];
  292. val.pt[0] = pt[0] + direction.pt[0]*t;
  293. val.pt[1] = pt[1] + direction.pt[1]*t;
  294. val.pt[2] = 0;
  295. return val;
  296. }
  297. inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z)
  298. {
  299. GLfloat t;
  300. t = -pt[2] / z;
  301. val.pt[0] = pt[0] + x*t;
  302. val.pt[1] = pt[1] + y*t;
  303. val.pt[2] = 0;
  304. return val;
  305. }
  306. inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  307. GLfloat dx, GLfloat dy, GLfloat dz)
  308. {
  309. GLfloat t = -pz / dz;
  310. pt[0] = px + dx*t;
  311. pt[1] = py + dy*t;
  312. pt[2] = 0;
  313. }
  314. #undef POINT_EXTERN
  315. #endif