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.

402 lines
9.9 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. #include <math.h>
  43. const float point_fudge = .000001;
  44. class Point {
  45. public:
  46. inline Point operator=(Point a);
  47. inline Point operator=(GLfloat *a);
  48. inline Point operator+(Point a);
  49. inline Point operator+=(Point a);
  50. inline Point operator-(Point a);
  51. // This takes a cross-product
  52. inline Point operator*(Point b);
  53. inline Point operator*(GLfloat b);
  54. inline Point operator*=(GLfloat b);
  55. inline Point operator/(GLfloat b);
  56. inline Point operator/=(GLfloat b);
  57. inline GLfloat& operator[](int index);
  58. inline void set(GLfloat x, GLfloat y, GLfloat z, GLfloat w = 1.0);
  59. inline GLfloat dist(Point b);
  60. inline GLfloat dot(Point b);
  61. inline GLfloat dot(GLfloat x, GLfloat y, GLfloat z);
  62. inline GLfloat mag();
  63. inline GLfloat magsquared();
  64. inline Point unit();
  65. inline void unitize();
  66. inline Point scale(Point p);
  67. // Angle is in RADIANS
  68. inline Point rotate(Point axis, GLfloat angle);
  69. inline Point rotate(Point axis, GLfloat c, GLfloat s);
  70. inline void rotate_self(Point axis, GLfloat c, GLfloat s);
  71. Point rotate_abouty(GLfloat c, GLfloat s);
  72. Point rotate_aboutz(GLfloat c, GLfloat s);
  73. // Returns point projected through proj_pt into XY plane
  74. // Does nothing if proj_pt - *this is parallel to XY plane
  75. inline Point project(Point proj_pt);
  76. inline void project_self(Point proj_pt);
  77. inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz);
  78. inline Point project_direction(Point direction);
  79. inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z);
  80. // This projects (px, py, pz) into this in direction (dx, dy, dz)
  81. inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  82. GLfloat x, GLfloat y, GLfloat z);
  83. // Returns point projected through light and refracted into XY
  84. // plane.
  85. // N is normal at point (ie normal at *this)
  86. // I is the index of refraction
  87. inline Point refract(Point light, Point N, GLfloat I);
  88. void refract_self(Point light, Point N, GLfloat I);
  89. Point refract_direction(Point light, Point N, GLfloat I);
  90. inline void glvertex();
  91. inline void glnormal();
  92. void print();
  93. void print(const char *format);
  94. GLfloat pt[4];
  95. private:
  96. };
  97. POINT_EXTERN Point val;
  98. #define DOT(a, b) (a.pt[0]*b.pt[0] + a.pt[1]*b.pt[1] + a.pt[2]*b.pt[2])
  99. #define THIS_DOT(b) (pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2])
  100. inline Point Point::operator=(Point a)
  101. {
  102. pt[0] = a.pt[0];
  103. pt[1] = a.pt[1];
  104. pt[2] = a.pt[2];
  105. pt[3] = a.pt[3];
  106. return *this;
  107. }
  108. inline Point Point::operator=(GLfloat *a)
  109. {
  110. pt[0] = a[0];
  111. pt[1] = a[1];
  112. pt[2] = a[2];
  113. pt[3] = 1;
  114. return *this;
  115. }
  116. inline Point Point::operator+(Point a)
  117. {
  118. val.pt[0] = pt[0] + a.pt[0];
  119. val.pt[1] = pt[1] + a.pt[1];
  120. val.pt[2] = pt[2] + a.pt[2];
  121. return val;
  122. }
  123. inline Point Point::operator+=(Point a)
  124. {
  125. pt[0] += a.pt[0];
  126. pt[1] += a.pt[1];
  127. pt[2] += a.pt[2];
  128. return *this;
  129. }
  130. inline Point Point::operator-(Point a)
  131. {
  132. val.pt[0] = pt[0] - a.pt[0];
  133. val.pt[1] = pt[1] - a.pt[1];
  134. val.pt[2] = pt[2] - a.pt[2];
  135. return val;
  136. }
  137. inline Point Point::operator*(Point b)
  138. {
  139. val.pt[0] = pt[1]*b.pt[2] - b.pt[1]*pt[2];
  140. val.pt[1] = pt[2]*b.pt[0] - b.pt[2]*pt[0];
  141. val.pt[2] = pt[0]*b.pt[1] - pt[1]*b.pt[0];
  142. return val;
  143. }
  144. inline Point Point::operator*(GLfloat b)
  145. {
  146. val.pt[0] = pt[0] * b;
  147. val.pt[1] = pt[1] * b;
  148. val.pt[2] = pt[2] * b;
  149. return val;
  150. }
  151. inline Point Point::operator*=(GLfloat b)
  152. {
  153. pt[0] *= b;
  154. pt[1] *= b;
  155. pt[2] *= b;
  156. return *this;
  157. }
  158. inline Point Point::operator/(GLfloat b)
  159. {
  160. val.pt[0] = pt[0] / b;
  161. val.pt[1] = pt[1] / b;
  162. val.pt[2] = pt[2] / b;
  163. return val;
  164. }
  165. inline Point Point::operator/=(GLfloat b)
  166. {
  167. pt[0] /= b;
  168. pt[1] /= b;
  169. pt[2] /= b;
  170. return *this;
  171. }
  172. inline GLfloat& Point::operator[](int index)
  173. {
  174. return pt[index];
  175. }
  176. inline void Point::set(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  177. {
  178. pt[0] = x;
  179. pt[1] = y;
  180. pt[2] = z;
  181. pt[3] = w;
  182. }
  183. inline GLfloat Point::dist(Point b)
  184. {
  185. return (*this - b).mag();
  186. }
  187. inline GLfloat Point::dot(Point b)
  188. {
  189. return pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2];
  190. }
  191. inline GLfloat Point::dot(GLfloat x, GLfloat y, GLfloat z)
  192. {
  193. return pt[0]*x + pt[1]*y + pt[2]*z;
  194. }
  195. inline GLfloat Point::mag()
  196. {
  197. return sqrt(pt[0]*pt[0] + pt[1]*pt[1] +
  198. pt[2]*pt[2]);
  199. }
  200. inline GLfloat Point::magsquared()
  201. {
  202. return pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2];
  203. }
  204. inline Point Point::unit()
  205. {
  206. GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
  207. val.pt[0] = pt[0] / m;
  208. val.pt[1] = pt[1] / m;
  209. val.pt[2] = pt[2] / m;
  210. return val;
  211. }
  212. inline void Point::unitize()
  213. {
  214. GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
  215. pt[0] /= m;
  216. pt[1] /= m;
  217. pt[2] /= m;
  218. }
  219. inline Point Point::scale(Point p)
  220. {
  221. val.pt[0] = pt[0] * p.pt[0];
  222. val.pt[1] = pt[1] * p.pt[1];
  223. val.pt[2] = pt[2] * p.pt[2];
  224. return val;
  225. }
  226. inline Point Point::rotate(Point axis, GLfloat angle)
  227. {
  228. return rotate(axis, cos(angle), sin(angle));
  229. }
  230. inline Point Point::rotate(Point axis, GLfloat c, GLfloat s)
  231. {
  232. float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
  233. float tx, ty;
  234. tx = t*x;
  235. /* Taking advantage of inside info that this is a common case */
  236. if (y == 0.0) {
  237. val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(-s*z) + pt[2]*(tx*z);
  238. val.pt[1] = pt[0]*(s*z) + pt[1]*c + pt[2]*(-s*x);
  239. val.pt[2] = pt[0]*(tx*z) + pt[1]*s*x + pt[2]*(t*z*z + c);
  240. } else {
  241. ty = t*y;
  242. val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(tx*y - s*z) +
  243. pt[2]*(tx*z + s*y);
  244. val.pt[1] = pt[0]*(tx*y + s*z) + pt[1]*(ty*y + c) +
  245. pt[2]*(ty*z - s*x);
  246. val.pt[2] = pt[0]*(tx*z - s*y) + pt[1]*(ty*z + s*x) +
  247. pt[2]*(t*z*z + c);
  248. }
  249. return val;
  250. }
  251. inline void Point::rotate_self(Point axis, GLfloat c, GLfloat s)
  252. {
  253. float Px, Py, Pz;
  254. float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
  255. float tx, ty;
  256. tx = t*x;
  257. Px = pt[0];
  258. Py = pt[1];
  259. Pz = pt[2];
  260. /* Taking advantage of inside info that this is a common case */
  261. if (!y) {
  262. pt[0] = Px*(tx*x + c) + Py*(-s*z) + Pz*(tx*z);
  263. pt[1] = Px*(s*z) + Py*c + Pz*(-s*x);
  264. pt[2] = Px*(tx*z) + Py*s*x + Pz*(t*z*z + c);
  265. } else {
  266. ty = t*y;
  267. pt[0] = Px*(tx*x + c) + Py*(tx*y - s*z) +
  268. Pz*(tx*z + s*y);
  269. pt[1] = Px*(tx*y + s*z) + Py*(ty*y + c) +
  270. Pz*(ty*z - s*x);
  271. pt[2] = Px*(tx*z - s*y) + Py*(ty*z + s*x) +
  272. Pz*(t*z*z + c);
  273. }
  274. }
  275. inline void Point::glvertex()
  276. {
  277. glVertex3fv(pt);
  278. }
  279. inline void Point::glnormal()
  280. {
  281. glNormal3fv(pt);
  282. }
  283. inline Point Point::project(Point proj_pt)
  284. {
  285. GLfloat dirx = pt[0] - proj_pt.pt[0],
  286. diry = pt[1] - proj_pt.pt[1],
  287. dirz = pt[2] - proj_pt.pt[2];
  288. GLfloat t;
  289. if (fabs(dirz) < point_fudge) val = *this;
  290. else {
  291. t = -proj_pt.pt[2] / dirz;
  292. val.pt[0] = proj_pt.pt[0] + dirx*t;
  293. val.pt[1] = proj_pt.pt[1] + diry*t;
  294. val.pt[2] = 0.0;
  295. }
  296. return val;
  297. }
  298. // This naively assumes that proj_pt[z] != this->pt[z]
  299. inline void Point::project_self(Point proj_pt)
  300. {
  301. GLfloat dirx = pt[0] - proj_pt.pt[0],
  302. diry = pt[1] - proj_pt.pt[1],
  303. dirz = pt[2] - proj_pt.pt[2];
  304. GLfloat t;
  305. t = -proj_pt.pt[2] / dirz;
  306. pt[0] = proj_pt.pt[0] + dirx*t;
  307. pt[1] = proj_pt.pt[1] + diry*t;
  308. pt[2] = 0.0;
  309. }
  310. inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz)
  311. {
  312. GLfloat dirx = pt[0] - px,
  313. diry = pt[1] - py,
  314. dirz = pt[2] - pz, t;
  315. t = -pz / dirz;
  316. pt[0] = px + dirx*t;
  317. pt[1] = py + diry*t;
  318. pt[2] = 0.0;
  319. }
  320. inline Point Point::project_direction(Point direction) {
  321. GLfloat t;
  322. t = -pt[2] / direction.pt[2];
  323. val.pt[0] = pt[0] + direction.pt[0]*t;
  324. val.pt[1] = pt[1] + direction.pt[1]*t;
  325. val.pt[2] = 0;
  326. return val;
  327. }
  328. inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z)
  329. {
  330. GLfloat t;
  331. t = -pt[2] / z;
  332. val.pt[0] = pt[0] + x*t;
  333. val.pt[1] = pt[1] + y*t;
  334. val.pt[2] = 0;
  335. return val;
  336. }
  337. inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  338. GLfloat dx, GLfloat dy, GLfloat dz)
  339. {
  340. GLfloat t = -pz / dz;
  341. pt[0] = px + dx*t;
  342. pt[1] = py + dy*t;
  343. pt[2] = 0;
  344. }
  345. #undef POINT_EXTERN
  346. #endif