/ecere/src/gfx/3D/Vector3D.ec

https://github.com/redj/ecere-sdk · C · 365 lines · 284 code · 35 blank · 46 comment · 7 complexity · 6480cb2b704d1ee43e9718b88dffd068 MD5 · raw file

  1. namespace gfx3D;
  2. import "Display"
  3. public struct Vector3D
  4. {
  5. double x, y, z;
  6. void Add(const Vector3D vector1, const Vector3D vector2)
  7. {
  8. x = vector1.x + vector2.x;
  9. y = vector1.y + vector2.y;
  10. z = vector1.z + vector2.z;
  11. }
  12. void Subtract(const Vector3D vector1, const Vector3D vector2)
  13. {
  14. x = vector1.x - vector2.x;
  15. y = vector1.y - vector2.y;
  16. z = vector1.z - vector2.z;
  17. }
  18. void Scale(const Vector3D vector1, double s)
  19. {
  20. x = vector1.x * s;
  21. y = vector1.y * s;
  22. z = vector1.z * s;
  23. }
  24. double DotProduct(const Vector3D vector2)
  25. {
  26. return x * vector2.x + y * vector2.y + z * vector2.z;
  27. }
  28. double DotProductf(const Vector3Df vector2)
  29. {
  30. return x * vector2.x + y * vector2.y + z * vector2.z;
  31. }
  32. void CrossProduct(const Vector3D vector1, const Vector3D vector2)
  33. {
  34. x = vector1.y * vector2.z - vector1.z * vector2.y;
  35. y = vector1.z * vector2.x - vector1.x * vector2.z;
  36. z = vector1.x * vector2.y - vector1.y * vector2.x;
  37. }
  38. void Normalize(const Vector3D source)
  39. {
  40. double m = source.length; // FIXME -- get should be fine with const objects
  41. if(m)
  42. {
  43. x = source.x/m;
  44. y = source.y/m;
  45. z = source.z/m;
  46. }
  47. else
  48. x = y = z = 0;
  49. }
  50. void MultMatrix(const Vector3D source, const Matrix matrix)
  51. {
  52. x = source.x * matrix.m[0][0] + source.y * matrix.m[1][0] + source.z * matrix.m[2][0] + matrix.m[3][0];
  53. y = source.x * matrix.m[0][1] + source.y * matrix.m[1][1] + source.z * matrix.m[2][1] + matrix.m[3][1];
  54. z = source.x * matrix.m[0][2] + source.y * matrix.m[1][2] + source.z * matrix.m[2][2] + matrix.m[3][2];
  55. }
  56. void MultMatrixf(const Vector3Df source, const Matrix matrix)
  57. {
  58. x = source.x * matrix.m[0][0] + source.y * matrix.m[1][0] + source.z * matrix.m[2][0] + matrix.m[3][0];
  59. y = source.x * matrix.m[0][1] + source.y * matrix.m[1][1] + source.z * matrix.m[2][1] + matrix.m[3][1];
  60. z = source.x * matrix.m[0][2] + source.y * matrix.m[1][2] + source.z * matrix.m[2][2] + matrix.m[3][2];
  61. }
  62. void MultQuaternion(const Vector3D s, const Quaternion quat)
  63. {
  64. Vector3D v { quat.x, quat.y, quat.z };
  65. double w = quat.w, a = w*w - (v.x*v.x+v.y*v.y+v.z*v.z) /*DotProduct(v)*/, dotVS = v.x*s.x+v.y*s.y+v.z*s.z /*v.DotProduct(s)*/;
  66. Vector3D cross
  67. {
  68. s.y * v.z - s.z * v.y,
  69. s.z * v.x - s.x * v.z,
  70. s.x * v.y - s.y * v.x
  71. };
  72. //cross.CrossProduct(s, v);
  73. x = (float)(2 * dotVS * v.x + a * s.x + 2 * w * cross.x);
  74. y = (float)(2 * dotVS * v.y + a * s.y + 2 * w * cross.y);
  75. z = (float)(2 * dotVS * v.z + a * s.z + 2 * w * cross.z);
  76. }
  77. void DivideMatrix(const Vector3D source, const Matrix matrix)
  78. {
  79. /*
  80. solve(
  81. {
  82. vectorX=sourceX*m00+sourceY*m10+sourceZ*m20+m30,
  83. vectorY=sourceZ*m01+sourceY*m11+sourceZ*m21+m31,
  84. vectorZ=sourceX*m02+sourceY*m12+sourceZ*m22+m32
  85. }, { sourceX, sourceY, sourceZ });
  86. */
  87. double var1 =
  88. matrix.m[2][0] * matrix.m[0][2] * matrix.m[1][1]
  89. - matrix.m[0][2] * matrix.m[2][1] * matrix.m[1][0]
  90. - matrix.m[2][2] * matrix.m[0][0] * matrix.m[1][1]
  91. - matrix.m[0][2] * matrix.m[0][1] * matrix.m[1][0]
  92. + matrix.m[2][1] * matrix.m[0][0] * matrix.m[1][2]
  93. + matrix.m[0][1] * matrix.m[0][0] * matrix.m[1][2];
  94. x = (
  95. - matrix.m[2][2] * source.x * matrix.m[1][1]
  96. + matrix.m[2][2] * matrix.m[1][0] * source.y
  97. - matrix.m[2][2] * matrix.m[1][0] * matrix.m[3][1]
  98. + matrix.m[2][2] * matrix.m[3][0] * matrix.m[1][1]
  99. - matrix.m[2][0] * matrix.m[3][2] * matrix.m[1][1]
  100. + source.x * matrix.m[2][1] * matrix.m[1][2]
  101. + source.x * matrix.m[0][1] * matrix.m[1][2]
  102. - matrix.m[1][0] * matrix.m[0][1] * source.z
  103. + matrix.m[1][0] * matrix.m[2][1] * matrix.m[3][2]
  104. + matrix.m[1][0] * matrix.m[0][1] * matrix.m[3][2]
  105. - matrix.m[1][0] * matrix.m[2][1] * source.z
  106. - matrix.m[3][0] * matrix.m[2][1] * matrix.m[1][2]
  107. - matrix.m[2][0] * matrix.m[1][2] * source.y
  108. + matrix.m[2][0] * matrix.m[1][2] * matrix.m[3][1]
  109. + matrix.m[2][0] * source.z * matrix.m[1][1]
  110. - matrix.m[3][0] * matrix.m[0][1] * matrix.m[1][2]
  111. ) / var1;
  112. y = - (
  113. - matrix.m[2][0] * matrix.m[0][2] * source.y
  114. + matrix.m[2][1] * matrix.m[0][0] * matrix.m[3][2]
  115. + matrix.m[2][0] * matrix.m[0][2] * matrix.m[3][1]
  116. + matrix.m[0][1] * matrix.m[0][0] * matrix.m[3][2]
  117. - matrix.m[2][1] * matrix.m[0][0] * source.z
  118. - matrix.m[0][2] * matrix.m[2][1] * matrix.m[3][0]
  119. + matrix.m[0][2] * matrix.m[0][1] * source.x
  120. - matrix.m[0][2] * matrix.m[0][1] * matrix.m[3][0]
  121. + matrix.m[0][2] * matrix.m[2][1] * source.x
  122. + matrix.m[2][2] * matrix.m[0][0] * source.y
  123. - matrix.m[0][1] * matrix.m[0][0] * source.z
  124. - matrix.m[2][2] * matrix.m[0][0] * matrix.m[3][1]
  125. ) / var1;
  126. z = (
  127. source.x * matrix.m[0][2] * matrix.m[1][1]
  128. + matrix.m[0][0] * matrix.m[3][2] * matrix.m[1][1]
  129. + matrix.m[0][0] * matrix.m[1][2] * source.y
  130. - matrix.m[0][0] * matrix.m[1][2] * matrix.m[3][1]
  131. - matrix.m[0][0] * source.z * matrix.m[1][1]
  132. - matrix.m[1][0] * matrix.m[0][2] * source.y
  133. + matrix.m[1][0] * matrix.m[0][2] * matrix.m[3][1]
  134. - matrix.m[3][0] * matrix.m[0][2] * matrix.m[1][1]
  135. ) / var1;
  136. }
  137. property double length { get { return (double)sqrt(x * x + y * y + z * z); } };
  138. property double lengthApprox
  139. {
  140. get
  141. {
  142. double ix = Abs(x), iy = Abs(y), iz = Abs(z);
  143. double tmp;
  144. if(ix < iy) { tmp = ix; ix = iy; iy = tmp; }
  145. if(ix < iz) { tmp = ix; ix = iz; iz = tmp; }
  146. if(iz > iy) { iz = iy; }
  147. return ix + (iz/2);
  148. }
  149. }
  150. };
  151. public /*inline */float FastInvSqrt(float x)
  152. {
  153. union { float f; uint u; } i;
  154. float halfX = x / 2;
  155. i.f = x;
  156. i.u = 0x5f375a86 - (i.u >> 1);
  157. x = i.f;
  158. return x * (1.5f - (halfX * x * x));
  159. }
  160. public /*inline */double FastInvSqrtDouble(double x)
  161. {
  162. union { double d; uint64 u; } i;
  163. double halfX = x / 2;
  164. i.d = x;
  165. i.u = 0x5fe6eb50c7b537a9LL - (i.u >> 1);
  166. x = i.d;
  167. return x * (1.5 - (halfX * x * x));
  168. }
  169. public struct Vector3Df
  170. {
  171. float x, y, z;
  172. void Add(const Vector3Df vector1, const Vector3Df vector2)
  173. {
  174. x = vector1.x + vector2.x;
  175. y = vector1.y + vector2.y;
  176. z = vector1.z + vector2.z;
  177. }
  178. void Subtract(const Vector3Df vector1, const Vector3Df vector2)
  179. {
  180. x = vector1.x - vector2.x;
  181. y = vector1.y - vector2.y;
  182. z = vector1.z - vector2.z;
  183. }
  184. void Scale(const Vector3Df vector1, float s)
  185. {
  186. x = vector1.x * s;
  187. y = vector1.y * s;
  188. z = vector1.z * s;
  189. }
  190. double DotProduct(const Vector3Df vector2)
  191. {
  192. return (double)x * (double)vector2.x + (double)y * (double)vector2.y + (double)z * (double)vector2.z;
  193. }
  194. void CrossProduct(const Vector3Df vector1, const Vector3Df vector2)
  195. {
  196. x = vector1.y * vector2.z - vector1.z * vector2.y;
  197. y = vector1.z * vector2.x - vector1.x * vector2.z;
  198. z = vector1.x * vector2.y - vector1.y * vector2.x;
  199. }
  200. void Normalize(const Vector3Df source)
  201. {
  202. /*
  203. float m = source.length;
  204. if(m)
  205. {
  206. x = source.x/m;
  207. y = source.y/m;
  208. z = source.z/m;
  209. }
  210. else
  211. x = y = z = 0;
  212. */
  213. float i = FastInvSqrt(source.x * source.x + source.y * source.y + source.z * source.z);
  214. x = source.x * i;
  215. y = source.y * i;
  216. z = source.z * i;
  217. }
  218. void MultMatrix(const Vector3Df source, const Matrix matrix)
  219. {
  220. x = (float)(source.x * matrix.m[0][0] + source.y * matrix.m[1][0] + source.z * matrix.m[2][0] + matrix.m[3][0]);
  221. y = (float)(source.x * matrix.m[0][1] + source.y * matrix.m[1][1] + source.z * matrix.m[2][1] + matrix.m[3][1]);
  222. z = (float)(source.x * matrix.m[0][2] + source.y * matrix.m[1][2] + source.z * matrix.m[2][2] + matrix.m[3][2]);
  223. }
  224. void MultQuaternion(const Vector3Df source, const Quaternion quat)
  225. {
  226. Vector3D s { source.x, source.y, source.z };
  227. Vector3D v { quat.x, quat.y, quat.z };
  228. double w = quat.w, a = w*w - (v.x*v.x+v.y*v.y+v.z*v.z) /*DotProduct(v)*/, dotVS = v.x*s.x+v.y*s.y+v.z*s.z /*v.DotProduct(s)*/;
  229. Vector3D cross
  230. {
  231. s.y * v.z - s.z * v.y,
  232. s.z * v.x - s.x * v.z,
  233. s.x * v.y - s.y * v.x
  234. };
  235. //cross.CrossProduct(s, v);
  236. x = (float)(2 * dotVS * v.x + a * s.x + 2 * w * cross.x);
  237. y = (float)(2 * dotVS * v.y + a * s.y + 2 * w * cross.y);
  238. z = (float)(2 * dotVS * v.z + a * s.z + 2 * w * cross.z);
  239. }
  240. void DivideMatrix(const Vector3Df source, const Matrix matrix)
  241. {
  242. /*
  243. solve(
  244. {
  245. vectorX=sourceX*m00+sourceY*m10+sourceZ*m20+m30,
  246. vectorY=sourceZ*m01+sourceY*m11+sourceZ*m21+m31,
  247. vectorZ=sourceX*m02+sourceY*m12+sourceZ*m22+m32
  248. }, { sourceX, sourceY, sourceZ });
  249. */
  250. float var1 = (float)(
  251. matrix.m[2][0] * matrix.m[0][2] * matrix.m[1][1]
  252. - matrix.m[0][2] * matrix.m[2][1] * matrix.m[1][0]
  253. - matrix.m[2][2] * matrix.m[0][0] * matrix.m[1][1]
  254. - matrix.m[0][2] * matrix.m[0][1] * matrix.m[1][0]
  255. + matrix.m[2][1] * matrix.m[0][0] * matrix.m[1][2]
  256. + matrix.m[0][1] * matrix.m[0][0] * matrix.m[1][2]);
  257. x = (float)(
  258. - matrix.m[2][2] * source.x * matrix.m[1][1]
  259. + matrix.m[2][2] * matrix.m[1][0] * source.y
  260. - matrix.m[2][2] * matrix.m[1][0] * matrix.m[3][1]
  261. + matrix.m[2][2] * matrix.m[3][0] * matrix.m[1][1]
  262. - matrix.m[2][0] * matrix.m[3][2] * matrix.m[1][1]
  263. + source.x * matrix.m[2][1] * matrix.m[1][2]
  264. + source.x * matrix.m[0][1] * matrix.m[1][2]
  265. - matrix.m[1][0] * matrix.m[0][1] * source.z
  266. + matrix.m[1][0] * matrix.m[2][1] * matrix.m[3][2]
  267. + matrix.m[1][0] * matrix.m[0][1] * matrix.m[3][2]
  268. - matrix.m[1][0] * matrix.m[2][1] * source.z
  269. - matrix.m[3][0] * matrix.m[2][1] * matrix.m[1][2]
  270. - matrix.m[2][0] * matrix.m[1][2] * source.y
  271. + matrix.m[2][0] * matrix.m[1][2] * matrix.m[3][1]
  272. + matrix.m[2][0] * source.z * matrix.m[1][1]
  273. - matrix.m[3][0] * matrix.m[0][1] * matrix.m[1][2]
  274. ) / var1;
  275. y = - (float)(
  276. - matrix.m[2][0] * matrix.m[0][2] * source.y
  277. + matrix.m[2][1] * matrix.m[0][0] * matrix.m[3][2]
  278. + matrix.m[2][0] * matrix.m[0][2] * matrix.m[3][1]
  279. + matrix.m[0][1] * matrix.m[0][0] * matrix.m[3][2]
  280. - matrix.m[2][1] * matrix.m[0][0] * source.z
  281. - matrix.m[0][2] * matrix.m[2][1] * matrix.m[3][0]
  282. + matrix.m[0][2] * matrix.m[0][1] * source.x
  283. - matrix.m[0][2] * matrix.m[0][1] * matrix.m[3][0]
  284. + matrix.m[0][2] * matrix.m[2][1] * source.x
  285. + matrix.m[2][2] * matrix.m[0][0] * source.y
  286. - matrix.m[0][1] * matrix.m[0][0] * source.z
  287. - matrix.m[2][2] * matrix.m[0][0] * matrix.m[3][1]
  288. ) / var1;
  289. z = (float)(
  290. source.x * matrix.m[0][2] * matrix.m[1][1]
  291. + matrix.m[0][0] * matrix.m[3][2] * matrix.m[1][1]
  292. + matrix.m[0][0] * matrix.m[1][2] * source.y
  293. - matrix.m[0][0] * matrix.m[1][2] * matrix.m[3][1]
  294. - matrix.m[0][0] * source.z * matrix.m[1][1]
  295. - matrix.m[1][0] * matrix.m[0][2] * source.y
  296. + matrix.m[1][0] * matrix.m[0][2] * matrix.m[3][1]
  297. - matrix.m[3][0] * matrix.m[0][2] * matrix.m[1][1]
  298. ) / var1;
  299. }
  300. property float length { get { return (float)sqrt(x * x + y * y + z * z); } };
  301. property float lengthApprox
  302. {
  303. get
  304. {
  305. float ix = Abs(x), iy = Abs(y), iz = Abs(z);
  306. float tmp;
  307. if(ix < iy) { tmp = ix; ix = iy; iy = tmp; }
  308. if(ix < iz) { tmp = ix; ix = iz; iz = tmp; }
  309. if(iz > iy) { iz = iy; }
  310. return ix + (iz/2);
  311. }
  312. }
  313. /*
  314. property Vector3D
  315. {
  316. get
  317. {
  318. value.x = (double) x;
  319. value.y = (double) y;
  320. value.z = (double) z;
  321. }
  322. set
  323. {
  324. x = (float) value.x;
  325. y = (float) value.y;
  326. z = (float) value.z;
  327. }
  328. }
  329. */
  330. };