SUPER.C 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601
  1. /****************************************************************************
  2. * super.c
  3. *
  4. * This module implements functions that manipulate superellipsoids.
  5. *
  6. * Original code written by Alexander Enzmann.
  7. * Adaption to POV-Ray by Dieter Bayer [DB].
  8. *
  9. * from Persistence of Vision(tm) Ray Tracer
  10. * Copyright 1996,1999 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. * NOTICE: This source code file is provided so that users may experiment
  13. * with enhancements to POV-Ray and to port the software to platforms other
  14. * than those supported by the POV-Ray Team. There are strict rules under
  15. * which you are permitted to use this file. The rules are in the file
  16. * named POVLEGAL.DOC which should be distributed with this file.
  17. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  19. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26. /****************************************************************************
  27. *
  28. * Explanation:
  29. *
  30. * Superellipsoids are defined by the implicit equation
  31. *
  32. * f(x,y,z) = (|x|^(2/e) + |y|^(2/e))^(e/n) + |z|^(2/n) - 1
  33. *
  34. * Where e is the east/west exponent and n is the north/south exponent.
  35. *
  36. * NOTE: The exponents are precomputed and stored in the Power element.
  37. *
  38. * NOTE: Values of e and n that are close to degenerate (e.g.,
  39. * below around 0.1) appear to give the root solver fits.
  40. * Not sure quite where the problem lays just yet.
  41. *
  42. * Syntax:
  43. *
  44. * superellipsoid { <e, n> }
  45. *
  46. *
  47. * ---
  48. *
  49. * Oct 1994 : Creation.
  50. *
  51. *****************************************************************************/
  52. #include "frame.h"
  53. #include "povray.h"
  54. #include "vector.h"
  55. #include "povproto.h"
  56. #include "bbox.h"
  57. #include "matrices.h"
  58. #include "objects.h"
  59. #include "super.h"
  60. /*****************************************************************************
  61. * Local preprocessor defines
  62. ******************************************************************************/
  63. /* Minimal intersection depth for a valid intersection. */
  64. #define DEPTH_TOLERANCE 1.0e-4
  65. /* If |x| < ZERO_TOLERANCE it is regarded to be 0. */
  66. #define ZERO_TOLERANCE 1.0e-10
  67. /* This is not the signum function because SGNX(0) is 1. */
  68. #define SGNX(x) (((x) >= 0.0) ? 1.0 : -1.0)
  69. #define MIN_VALUE -1.0
  70. #define MAX_VALUE 1.0
  71. #define MAX_ITERATIONS 20
  72. #define PLANECOUNT 9
  73. /*****************************************************************************
  74. * Local typedefs
  75. ******************************************************************************/
  76. /*****************************************************************************
  77. * Static functions
  78. ******************************************************************************/
  79. static int intersect_superellipsoid (RAY *Ray, SUPERELLIPSOID *Superellipsoid, ISTACK *Depth_Stack);
  80. static int intersect_box (VECTOR P, VECTOR D, DBL *dmin, DBL *dmax);
  81. static DBL power (DBL x, DBL e);
  82. static DBL evaluate_superellipsoid (VECTOR P, SUPERELLIPSOID *Superellipsoid);
  83. static int compdists (CONST void *in_a, CONST void *in_b);
  84. static int find_ray_plane_points (VECTOR P, VECTOR D, int cnt, DBL *dists, DBL mindist, DBL maxdist);
  85. static void solve_hit1 (SUPERELLIPSOID *Super, DBL v0, VECTOR tP0, DBL v1, VECTOR tP1, VECTOR P);
  86. static int check_hit2 (SUPERELLIPSOID *Super, VECTOR P, VECTOR D, DBL t0, VECTOR P0, DBL v0, DBL t1, DBL *t, VECTOR Q);
  87. static int insert_hit (OBJECT *Object, RAY *Ray, DBL Depth, ISTACK *Depth_Stack);
  88. static int All_Superellipsoid_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  89. static int Inside_Superellipsoid (VECTOR point, OBJECT *Object);
  90. static void Superellipsoid_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  91. static SUPERELLIPSOID *Copy_Superellipsoid (OBJECT *Object);
  92. static void Translate_Superellipsoid (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  93. static void Rotate_Superellipsoid (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  94. static void Scale_Superellipsoid (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  95. static void Transform_Superellipsoid (OBJECT *Object, TRANSFORM *Trans);
  96. static void Invert_Superellipsoid (OBJECT *Object);
  97. static void Destroy_Superellipsoid (OBJECT *Object);
  98. /*****************************************************************************
  99. * Local variables
  100. ******************************************************************************/
  101. static METHODS Superellipsoid_Methods =
  102. {
  103. All_Superellipsoid_Intersections,
  104. Inside_Superellipsoid, Superellipsoid_Normal,
  105. (COPY_METHOD)Copy_Superellipsoid,
  106. Translate_Superellipsoid, Rotate_Superellipsoid,
  107. Scale_Superellipsoid, Transform_Superellipsoid, Invert_Superellipsoid, Destroy_Superellipsoid
  108. };
  109. static DBL planes[PLANECOUNT][4] =
  110. {{1, 1, 0, 0}, {1,-1, 0, 0},
  111. {1, 0, 1, 0}, {1, 0,-1, 0},
  112. {0, 1, 1, 0}, {0, 1,-1, 0},
  113. {1, 0, 0, 0},
  114. {0, 1, 0, 0},
  115. {0, 0, 1, 0}};
  116. /*****************************************************************************
  117. *
  118. * FUNCTION
  119. *
  120. * All_Superellipsoid_Intersections
  121. *
  122. * INPUT
  123. *
  124. * Object - Object
  125. * Ray - Ray
  126. * Depth_Stack - Intersection stack
  127. *
  128. * OUTPUT
  129. *
  130. * Depth_Stack
  131. *
  132. * RETURNS
  133. *
  134. * int - TRUE, if a intersection was found
  135. *
  136. * AUTHOR
  137. *
  138. * Dieter Bayer
  139. *
  140. * DESCRIPTION
  141. *
  142. * Determine ray/superellipsoid intersection and clip intersection found.
  143. *
  144. * CHANGES
  145. *
  146. * Oct 1994 : Creation.
  147. *
  148. ******************************************************************************/
  149. static int All_Superellipsoid_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  150. {
  151. Increase_Counter(stats[Ray_Superellipsoid_Tests]);
  152. if (intersect_superellipsoid(Ray, (SUPERELLIPSOID *)Object, Depth_Stack))
  153. {
  154. Increase_Counter(stats[Ray_Superellipsoid_Tests_Succeeded]);
  155. return(TRUE);
  156. }
  157. else
  158. {
  159. return(FALSE);
  160. }
  161. }
  162. /*****************************************************************************
  163. *
  164. * FUNCTION
  165. *
  166. * intersect_superellipsoid
  167. *
  168. * INPUT
  169. *
  170. * Ray - Ray
  171. * Superellipsoid - Superellipsoid
  172. * Depth_Stack - Depth stack
  173. *
  174. * OUTPUT
  175. *
  176. * Intersection
  177. *
  178. * RETURNS
  179. *
  180. * int - TRUE if intersections were found.
  181. *
  182. * AUTHOR
  183. *
  184. * Alexander Enzmann, Dieter Bayer
  185. *
  186. * DESCRIPTION
  187. *
  188. * Determine ray/superellipsoid intersection.
  189. *
  190. * CHANGES
  191. *
  192. * Oct 1994 : Creation.
  193. *
  194. ******************************************************************************/
  195. static int intersect_superellipsoid(RAY *Ray, SUPERELLIPSOID *Superellipsoid, ISTACK *Depth_Stack)
  196. {
  197. int i, cnt, Found = FALSE;
  198. DBL dists[PLANECOUNT+2];
  199. DBL t, t1, t2, v0, v1, len;
  200. VECTOR P, D, P0, P1, P2, P3;
  201. /* Transform the ray into the superellipsoid space. */
  202. MInvTransPoint(P, Ray->Initial, Superellipsoid->Trans);
  203. MInvTransDirection(D, Ray->Direction, Superellipsoid->Trans);
  204. VLength(len, D);
  205. VInverseScaleEq(D, len);
  206. /* Intersect superellipsoid's bounding box. */
  207. if (!intersect_box(P, D, &t1, &t2))
  208. {
  209. return(FALSE);
  210. }
  211. /* Test if superellipsoid lies 'behind' the ray origin. */
  212. if (t2 < DEPTH_TOLERANCE)
  213. {
  214. return(FALSE);
  215. }
  216. cnt = 0;
  217. if (t1 < DEPTH_TOLERANCE)
  218. {
  219. t1 = DEPTH_TOLERANCE;
  220. }
  221. dists[cnt++] = t1;
  222. dists[cnt++] = t2;
  223. /* Intersect ray with planes cutting superellipsoids in pieces. */
  224. cnt = find_ray_plane_points(P, D, cnt, dists, t1, t2);
  225. if (cnt <= 1)
  226. {
  227. return(FALSE);
  228. }
  229. VEvaluateRay(P0, P, dists[0], D)
  230. v0 = evaluate_superellipsoid(P0, Superellipsoid);
  231. if (fabs(v0) < ZERO_TOLERANCE)
  232. {
  233. if (insert_hit((OBJECT *)Superellipsoid, Ray, dists[0] / len, Depth_Stack))
  234. {
  235. if (Superellipsoid->Type & IS_CHILD_OBJECT)
  236. {
  237. Found = TRUE;
  238. }
  239. else
  240. {
  241. return(TRUE);
  242. }
  243. }
  244. }
  245. for (i = 1; i < cnt; i++)
  246. {
  247. VEvaluateRay(P1, P, dists[i], D)
  248. v1 = evaluate_superellipsoid(P1, Superellipsoid);
  249. if (fabs(v1) < ZERO_TOLERANCE)
  250. {
  251. if (insert_hit((OBJECT *)Superellipsoid, Ray, dists[i] / len, Depth_Stack))
  252. {
  253. if (Superellipsoid->Type & IS_CHILD_OBJECT)
  254. {
  255. Found = TRUE;
  256. }
  257. else
  258. {
  259. return(TRUE);
  260. }
  261. }
  262. }
  263. else
  264. {
  265. if (v0 * v1 < 0.0)
  266. {
  267. /* Opposite signs, there must be a root between */
  268. solve_hit1(Superellipsoid, v0, P0, v1, P1, P2);
  269. VSub(P3, P2, P);
  270. VLength(t, P3);
  271. if (insert_hit((OBJECT *)Superellipsoid, Ray, t / len, Depth_Stack))
  272. {
  273. if (Superellipsoid->Type & IS_CHILD_OBJECT)
  274. {
  275. Found = TRUE;
  276. }
  277. else
  278. {
  279. return(TRUE);
  280. }
  281. }
  282. }
  283. else
  284. {
  285. /*
  286. * Although there was no sign change, we may actually be approaching
  287. * the surface. In this case, we are being fooled by the shape of the
  288. * surface into thinking there isn't a root between sample points.
  289. */
  290. if (check_hit2(Superellipsoid, P, D, dists[i-1], P0, v0, dists[i], &t, P2))
  291. {
  292. if (insert_hit((OBJECT *)Superellipsoid, Ray, t / len, Depth_Stack))
  293. {
  294. if (Superellipsoid->Type & IS_CHILD_OBJECT)
  295. {
  296. Found = TRUE;
  297. }
  298. else
  299. {
  300. return(TRUE);
  301. }
  302. }
  303. else
  304. {
  305. break;
  306. }
  307. }
  308. }
  309. }
  310. v0 = v1;
  311. Assign_Vector(P0, P1);
  312. }
  313. return(Found);
  314. }
  315. /*****************************************************************************
  316. *
  317. * FUNCTION
  318. *
  319. * Inside_Superellipsoid
  320. *
  321. * INPUT
  322. *
  323. * IPoint - Intersection point
  324. * Object - Object
  325. *
  326. * OUTPUT
  327. *
  328. * RETURNS
  329. *
  330. * int - TRUE if inside
  331. *
  332. * AUTHOR
  333. *
  334. * Dieter Bayer
  335. *
  336. * DESCRIPTION
  337. *
  338. * Test if a point lies inside the superellipsoid.
  339. *
  340. * CHANGES
  341. *
  342. * Oct 1994 : Creation.
  343. *
  344. ******************************************************************************/
  345. static int Inside_Superellipsoid(VECTOR IPoint, OBJECT *Object)
  346. {
  347. DBL val;
  348. VECTOR P;
  349. SUPERELLIPSOID *Superellipsoid = (SUPERELLIPSOID *)Object;
  350. /* Transform the point into the superellipsoid space. */
  351. MInvTransPoint(P, IPoint, Superellipsoid->Trans);
  352. val = evaluate_superellipsoid(P, Superellipsoid);
  353. if (val < EPSILON)
  354. {
  355. return(!Test_Flag(Superellipsoid, INVERTED_FLAG));
  356. }
  357. else
  358. {
  359. return(Test_Flag(Superellipsoid, INVERTED_FLAG));
  360. }
  361. }
  362. /*****************************************************************************
  363. *
  364. * FUNCTION
  365. *
  366. * Superellipsoid_Normal
  367. *
  368. * INPUT
  369. *
  370. * Result - Normal vector
  371. * Object - Object
  372. * Inter - Intersection found
  373. *
  374. * OUTPUT
  375. *
  376. * Result
  377. *
  378. * RETURNS
  379. *
  380. * AUTHOR
  381. *
  382. * Dieter Bayer
  383. *
  384. * DESCRIPTION
  385. *
  386. * Calculate the normal of the superellipsoid in a given point.
  387. *
  388. * CHANGES
  389. *
  390. * Oct 1994 : Creation.
  391. *
  392. ******************************************************************************/
  393. static void Superellipsoid_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  394. {
  395. DBL k, x, y, z;
  396. VECTOR P, N, E;
  397. SUPERELLIPSOID *Superellipsoid = (SUPERELLIPSOID *)Object;
  398. /* Transform the point into the superellipsoid space. */
  399. MInvTransPoint(P, Inter->IPoint, Superellipsoid->Trans);
  400. Assign_Vector(E, Superellipsoid->Power);
  401. x = fabs(P[X]);
  402. y = fabs(P[Y]);
  403. z = fabs(P[Z]);
  404. k = power(power(x, E[X]) + power(y, E[X]), E[Y] - 1.0);
  405. N[X] = k * SGNX(P[X]) * power(x, E[X] - 1.0);
  406. N[Y] = k * SGNX(P[Y]) * power(y, E[X] - 1.0);
  407. N[Z] = SGNX(P[Z]) * power(z, E[Z] - 1.0);
  408. /* Transform the normalt out of the superellipsoid space. */
  409. MTransNormal(Result, N, Superellipsoid->Trans);
  410. VNormalize(Result, Result);
  411. }
  412. /*****************************************************************************
  413. *
  414. * FUNCTION
  415. *
  416. * Translate_Superellipsoid
  417. *
  418. * INPUT
  419. *
  420. * Object - Object
  421. * Vector - Translation vector
  422. *
  423. * OUTPUT
  424. *
  425. * Object
  426. *
  427. * RETURNS
  428. *
  429. * AUTHOR
  430. *
  431. * Dieter Bayer
  432. *
  433. * DESCRIPTION
  434. *
  435. * Translate a superellipsoid.
  436. *
  437. * CHANGES
  438. *
  439. * Oct 1994 : Creation.
  440. *
  441. ******************************************************************************/
  442. static void Translate_Superellipsoid(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  443. {
  444. Transform_Superellipsoid(Object, Trans);
  445. }
  446. /*****************************************************************************
  447. *
  448. * FUNCTION
  449. *
  450. * Rotate_Superellipsoid
  451. *
  452. * INPUT
  453. *
  454. * Object - Object
  455. * Vector - Rotation vector
  456. *
  457. * OUTPUT
  458. *
  459. * Object
  460. *
  461. * RETURNS
  462. *
  463. * AUTHOR
  464. *
  465. * Dieter Bayer
  466. *
  467. * DESCRIPTION
  468. *
  469. * Rotate a superellipsoid.
  470. *
  471. * CHANGES
  472. *
  473. * Oct 1994 : Creation.
  474. *
  475. ******************************************************************************/
  476. static void Rotate_Superellipsoid(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  477. {
  478. Transform_Superellipsoid(Object, Trans);
  479. }
  480. /*****************************************************************************
  481. *
  482. * FUNCTION
  483. *
  484. * Scale_Superellipsoid
  485. *
  486. * INPUT
  487. *
  488. * Object - Object
  489. * Vector - Scaling vector
  490. *
  491. * OUTPUT
  492. *
  493. * Object
  494. *
  495. * RETURNS
  496. *
  497. * AUTHOR
  498. *
  499. * Dieter Bayer
  500. *
  501. * DESCRIPTION
  502. *
  503. * Scale a superellipsoid.
  504. *
  505. * CHANGES
  506. *
  507. * Oct 1994 : Creation.
  508. *
  509. ******************************************************************************/
  510. static void Scale_Superellipsoid(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  511. {
  512. Transform_Superellipsoid(Object, Trans);
  513. }
  514. /*****************************************************************************
  515. *
  516. * FUNCTION
  517. *
  518. * Transform_Superellipsoid
  519. *
  520. * INPUT
  521. *
  522. * Object - Object
  523. * Trans - Transformation to apply
  524. *
  525. * OUTPUT
  526. *
  527. * Object
  528. *
  529. * RETURNS
  530. *
  531. * AUTHOR
  532. *
  533. * Dieter Bayer
  534. *
  535. * DESCRIPTION
  536. *
  537. * Transform a superellipsoid and recalculate its bounding box.
  538. *
  539. * CHANGES
  540. *
  541. * Oct 1994 : Creation.
  542. *
  543. ******************************************************************************/
  544. static void Transform_Superellipsoid(OBJECT *Object, TRANSFORM *Trans)
  545. {
  546. Compose_Transforms(((SUPERELLIPSOID *)Object)->Trans, Trans);
  547. Compute_Superellipsoid_BBox((SUPERELLIPSOID *)Object);
  548. }
  549. /*****************************************************************************
  550. *
  551. * FUNCTION
  552. *
  553. * Invert_Superellipsoid
  554. *
  555. * INPUT
  556. *
  557. * Object - Object
  558. *
  559. * OUTPUT
  560. *
  561. * Object
  562. *
  563. * RETURNS
  564. *
  565. * AUTHOR
  566. *
  567. * Dieter Bayer
  568. *
  569. * DESCRIPTION
  570. *
  571. * Invert a superellipsoid.
  572. *
  573. * CHANGES
  574. *
  575. * Oct 1994 : Creation.
  576. *
  577. ******************************************************************************/
  578. static void Invert_Superellipsoid(OBJECT *Object)
  579. {
  580. Invert_Flag(Object, INVERTED_FLAG);
  581. }
  582. /*****************************************************************************
  583. *
  584. * FUNCTION
  585. *
  586. * Create_Superellipsoid
  587. *
  588. * INPUT
  589. *
  590. * OUTPUT
  591. *
  592. * RETURNS
  593. *
  594. * SUPERELLIPSOID * - new superellipsoid
  595. *
  596. * AUTHOR
  597. *
  598. * Dieter Bayer
  599. *
  600. * DESCRIPTION
  601. *
  602. * Create a new superellipsoid.
  603. *
  604. * CHANGES
  605. *
  606. * Oct 1994 : Creation.
  607. *
  608. ******************************************************************************/
  609. SUPERELLIPSOID *Create_Superellipsoid()
  610. {
  611. SUPERELLIPSOID *New;
  612. New = (SUPERELLIPSOID *)POV_MALLOC(sizeof(SUPERELLIPSOID), "superellipsoid");
  613. INIT_OBJECT_FIELDS(New,SUPERELLIPSOID_OBJECT,&Superellipsoid_Methods)
  614. New->Trans = Create_Transform();
  615. Make_Vector(New->Power, 2.0, 2.0, 2.0);
  616. return(New);
  617. }
  618. /*****************************************************************************
  619. *
  620. * FUNCTION
  621. *
  622. * Copy_Superellipsoid
  623. *
  624. * INPUT
  625. *
  626. * Object - Object
  627. *
  628. * OUTPUT
  629. *
  630. * RETURNS
  631. *
  632. * void * - New superellipsoid
  633. *
  634. * AUTHOR
  635. *
  636. * Dieter Bayer
  637. *
  638. * DESCRIPTION
  639. *
  640. * Copy a superellipsoid structure.
  641. *
  642. * CHANGES
  643. *
  644. * Oct 1994 : Creation.
  645. *
  646. ******************************************************************************/
  647. static SUPERELLIPSOID *Copy_Superellipsoid(OBJECT *Object)
  648. {
  649. SUPERELLIPSOID *New, *Superellipsoid = (SUPERELLIPSOID *)Object;
  650. New = Create_Superellipsoid();
  651. /* Get rid of the transformation created in Create_Superellipsoid(). */
  652. Destroy_Transform(New->Trans);
  653. /* Copy superellipsoid. */
  654. *New = *Superellipsoid;
  655. New->Trans = Copy_Transform(Superellipsoid->Trans);
  656. return(New);
  657. }
  658. /*****************************************************************************
  659. *
  660. * FUNCTION
  661. *
  662. * Destroy_Superellipsoid
  663. *
  664. * INPUT
  665. *
  666. * Object - Object
  667. *
  668. * OUTPUT
  669. *
  670. * Object
  671. *
  672. * RETURNS
  673. *
  674. * AUTHOR
  675. *
  676. * Dieter Bayer
  677. *
  678. * DESCRIPTION
  679. *
  680. * Destroy a superellipsoid.
  681. *
  682. * CHANGES
  683. *
  684. * Oct 1994 : Creation.
  685. *
  686. ******************************************************************************/
  687. static void Destroy_Superellipsoid(OBJECT *Object)
  688. {
  689. SUPERELLIPSOID *Superellipsoid = (SUPERELLIPSOID *)Object;
  690. Destroy_Transform(Superellipsoid->Trans);
  691. POV_FREE (Object);
  692. }
  693. /*****************************************************************************
  694. *
  695. * FUNCTION
  696. *
  697. * Compute_Superellipsoid_BBox
  698. *
  699. * INPUT
  700. *
  701. * Superellipsoid - Superellipsoid
  702. *
  703. * OUTPUT
  704. *
  705. * Superellipsoid
  706. *
  707. * RETURNS
  708. *
  709. * AUTHOR
  710. *
  711. * Dieter Bayer
  712. *
  713. * DESCRIPTION
  714. *
  715. * Calculate the bounding box of a superellipsoid.
  716. *
  717. * CHANGES
  718. *
  719. * Oct 1994 : Creation.
  720. *
  721. ******************************************************************************/
  722. void Compute_Superellipsoid_BBox(SUPERELLIPSOID *Superellipsoid)
  723. {
  724. Make_BBox(Superellipsoid->BBox, -1.0001, -1.0001, -1.0001, 2.0002, 2.0002, 2.0002);
  725. Recompute_BBox(&Superellipsoid->BBox, Superellipsoid->Trans);
  726. }
  727. /*****************************************************************************
  728. *
  729. * FUNCTION
  730. *
  731. * intersect_box
  732. *
  733. * INPUT
  734. *
  735. * P, D - Ray origin and direction
  736. * dmin, dmax - Intersection depths
  737. *
  738. * OUTPUT
  739. *
  740. * dmin, dmax
  741. *
  742. * RETURNS
  743. *
  744. * int - TRUE, if hit
  745. *
  746. * AUTHOR
  747. *
  748. * Dieter Bayer
  749. *
  750. * DESCRIPTION
  751. *
  752. * Intersect a ray with an axis aligned unit box.
  753. *
  754. * CHANGES
  755. *
  756. * Oct 1994 : Creation.
  757. *
  758. ******************************************************************************/
  759. static int intersect_box(VECTOR P, VECTOR D, DBL *dmin, DBL *dmax)
  760. {
  761. DBL tmin = 0.0, tmax = 0.0;
  762. /* Left/right. */
  763. if (fabs(D[X]) > EPSILON)
  764. {
  765. if (D[X] > EPSILON)
  766. {
  767. *dmin = (MIN_VALUE - P[X]) / D[X];
  768. *dmax = (MAX_VALUE - P[X]) / D[X];
  769. if (*dmax < EPSILON) return(FALSE);
  770. }
  771. else
  772. {
  773. *dmax = (MIN_VALUE - P[X]) / D[X];
  774. if (*dmax < EPSILON) return(FALSE);
  775. *dmin = (MAX_VALUE - P[X]) / D[X];
  776. }
  777. if (*dmin > *dmax) return(FALSE);
  778. }
  779. else
  780. {
  781. if ((P[X] < MIN_VALUE) || (P[X] > MAX_VALUE))
  782. {
  783. return(FALSE);
  784. }
  785. *dmin = -BOUND_HUGE;
  786. *dmax = BOUND_HUGE;
  787. }
  788. /* Top/bottom. */
  789. if (fabs(D[Y]) > EPSILON)
  790. {
  791. if (D[Y] > EPSILON)
  792. {
  793. tmin = (MIN_VALUE - P[Y]) / D[Y];
  794. tmax = (MAX_VALUE - P[Y]) / D[Y];
  795. }
  796. else
  797. {
  798. tmax = (MIN_VALUE - P[Y]) / D[Y];
  799. tmin = (MAX_VALUE - P[Y]) / D[Y];
  800. }
  801. if (tmax < *dmax)
  802. {
  803. if (tmax < EPSILON) return(FALSE);
  804. if (tmin > *dmin)
  805. {
  806. if (tmin > tmax) return(FALSE);
  807. *dmin = tmin;
  808. }
  809. else
  810. {
  811. if (*dmin > tmax) return(FALSE);
  812. }
  813. *dmax = tmax;
  814. }
  815. else
  816. {
  817. if (tmin > *dmin)
  818. {
  819. if (tmin > *dmax) return(FALSE);
  820. *dmin = tmin;
  821. }
  822. }
  823. }
  824. else
  825. {
  826. if ((P[Y] < MIN_VALUE) || (P[Y] > MAX_VALUE))
  827. {
  828. return(FALSE);
  829. }
  830. }
  831. /* Front/back. */
  832. if (fabs(D[Z]) > EPSILON)
  833. {
  834. if (D[Z] > EPSILON)
  835. {
  836. tmin = (MIN_VALUE - P[Z]) / D[Z];
  837. tmax = (MAX_VALUE - P[Z]) / D[Z];
  838. }
  839. else
  840. {
  841. tmax = (MIN_VALUE - P[Z]) / D[Z];
  842. tmin = (MAX_VALUE - P[Z]) / D[Z];
  843. }
  844. if (tmax < *dmax)
  845. {
  846. if (tmax < EPSILON) return(FALSE);
  847. if (tmin > *dmin)
  848. {
  849. if (tmin > tmax) return(FALSE);
  850. *dmin = tmin;
  851. }
  852. else
  853. {
  854. if (*dmin > tmax) return(FALSE);
  855. }
  856. *dmax = tmax;
  857. }
  858. else
  859. {
  860. if (tmin > *dmin)
  861. {
  862. if (tmin > *dmax) return(FALSE);
  863. *dmin = tmin;
  864. }
  865. }
  866. }
  867. else
  868. {
  869. if ((P[Z] < MIN_VALUE) || (P[Z] > MAX_VALUE))
  870. {
  871. return(FALSE);
  872. }
  873. }
  874. *dmin = tmin;
  875. *dmax = tmax;
  876. return(TRUE);
  877. }
  878. /*****************************************************************************
  879. *
  880. * FUNCTION
  881. *
  882. * evaluate_superellipsoid
  883. *
  884. * INPUT
  885. *
  886. * P - Point to evaluate
  887. * Superellipsoid - Pointer to superellipsoid
  888. *
  889. * OUTPUT
  890. *
  891. * RETURNS
  892. *
  893. * DBL
  894. *
  895. * AUTHOR
  896. *
  897. * Dieter Bayer
  898. *
  899. * DESCRIPTION
  900. *
  901. * Get superellipsoid value in the given point.
  902. *
  903. * CHANGES
  904. *
  905. * Oct 1994 : Creation.
  906. *
  907. ******************************************************************************/
  908. static DBL evaluate_superellipsoid(VECTOR P, SUPERELLIPSOID *Superellipsoid)
  909. {
  910. VECTOR V1;
  911. V1[X] = power(fabs(P[X]), Superellipsoid->Power[X]);
  912. V1[Y] = power(fabs(P[Y]), Superellipsoid->Power[X]);
  913. V1[Z] = power(fabs(P[Z]), Superellipsoid->Power[Z]);
  914. return(power(V1[X] + V1[Y], Superellipsoid->Power[Y]) + V1[Z] - 1.0);
  915. }
  916. /*****************************************************************************
  917. *
  918. * FUNCTION
  919. *
  920. * power
  921. *
  922. * INPUT
  923. *
  924. * x - Argument
  925. * e - Power
  926. *
  927. * OUTPUT
  928. *
  929. * RETURNS
  930. *
  931. * DBL
  932. *
  933. * AUTHOR
  934. *
  935. * Dieter Bayer
  936. *
  937. * DESCRIPTION
  938. *
  939. * Raise x to the power of e.
  940. *
  941. * CHANGES
  942. *
  943. * Oct 1994 : Creation.
  944. *
  945. ******************************************************************************/
  946. static DBL power(DBL x, DBL e)
  947. {
  948. register int i;
  949. register DBL b;
  950. b = x;
  951. i = (int)e;
  952. /* Test if we have an integer power. */
  953. if (e == (DBL)i)
  954. {
  955. switch (i)
  956. {
  957. case 0: return(1.0);
  958. case 1: return(b);
  959. case 2: return(Sqr(b));
  960. case 3: return(Sqr(b) * b);
  961. case 4: b *= b; return(Sqr(b));
  962. case 5: b *= b; return(Sqr(b) * x);
  963. case 6: b *= b; return(Sqr(b) * b);
  964. default: return(pow(x, e));
  965. }
  966. }
  967. else
  968. {
  969. return(pow(x, e));
  970. }
  971. }
  972. /*****************************************************************************
  973. *
  974. * FUNCTION
  975. *
  976. * insert_hit
  977. *
  978. * INPUT
  979. *
  980. * Object - Object
  981. * Ray - Ray
  982. * Depth - Intersection depth
  983. * Depth_Stack - Intersection stack
  984. *
  985. * OUTPUT
  986. *
  987. * Depth_Stack
  988. *
  989. * RETURNS
  990. *
  991. * int - TRUE, if intersection is valid
  992. *
  993. * AUTHOR
  994. *
  995. * Dieter Bayer
  996. *
  997. * DESCRIPTION
  998. *
  999. * Push an intersection onto the depth stack if it is valid.
  1000. *
  1001. * CHANGES
  1002. *
  1003. * Nov 1994 : Creation.
  1004. *
  1005. ******************************************************************************/
  1006. static int insert_hit(OBJECT *Object, RAY *Ray, DBL Depth, ISTACK *Depth_Stack)
  1007. {
  1008. VECTOR IPoint;
  1009. if ((Depth > DEPTH_TOLERANCE) && (Depth < Max_Distance))
  1010. {
  1011. VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  1012. if (Point_In_Clip(IPoint, Object->Clip))
  1013. {
  1014. push_entry(Depth, IPoint, Object, Depth_Stack);
  1015. return(TRUE);
  1016. }
  1017. }
  1018. return(FALSE);
  1019. }
  1020. /*****************************************************************************
  1021. *
  1022. * FUNCTION
  1023. *
  1024. * compdists
  1025. *
  1026. * INPUT
  1027. *
  1028. * OUTPUT
  1029. *
  1030. * RETURNS
  1031. *
  1032. * AUTHOR
  1033. *
  1034. * Alexander Enzmann
  1035. *
  1036. * DESCRIPTION
  1037. *
  1038. * Compare two slabs.
  1039. *
  1040. * CHANGES
  1041. *
  1042. * Nov 1994 : Creation.
  1043. *
  1044. ******************************************************************************/
  1045. static int compdists(CONST void *in_a, CONST void *in_b)
  1046. {
  1047. DBL a, b;
  1048. a = *((DBL *)in_a);
  1049. b = *((DBL *)in_b);
  1050. if (a < b)
  1051. {
  1052. return(-1);
  1053. }
  1054. if (a == b)
  1055. {
  1056. return(0);
  1057. }
  1058. else
  1059. {
  1060. return(1);
  1061. }
  1062. }
  1063. /*****************************************************************************
  1064. *
  1065. * FUNCTION
  1066. *
  1067. * find_ray_plane_points
  1068. *
  1069. * INPUT
  1070. *
  1071. * OUTPUT
  1072. *
  1073. * RETURNS
  1074. *
  1075. * AUTHOR
  1076. *
  1077. * Alexander Enzmann
  1078. *
  1079. * DESCRIPTION
  1080. *
  1081. * Find all the places where the ray intersects the set of
  1082. * subdividing planes through the superquadric. Return the
  1083. * number of valid hits (within the bounding box).
  1084. *
  1085. * CHANGES
  1086. *
  1087. * Nov 1994 : Creation.
  1088. *
  1089. ******************************************************************************/
  1090. static int find_ray_plane_points(VECTOR P, VECTOR D, int cnt, DBL *dists, DBL mindist, DBL maxdist)
  1091. {
  1092. int i;
  1093. DBL t, d;
  1094. /* Since min and max dist are the distance to two of the bounding planes
  1095. we are considering, there is a high probablity of missing them due to
  1096. round off error. Therefore we adjust min and max. */
  1097. t = EPSILON * (maxdist - mindist);
  1098. mindist -= t;
  1099. maxdist += t;
  1100. /* Check the sets of planes that cut apart the superquadric. */
  1101. for (i = 0; i < PLANECOUNT; i++)
  1102. {
  1103. d = (D[0] * planes[i][0] + D[1] * planes[i][1] + D[2] * planes[i][2]);
  1104. if (fabs(d) < EPSILON)
  1105. {
  1106. /* Can't possibly get a hit for this combination of ray and plane. */
  1107. continue;
  1108. }
  1109. t = (planes[i][3] - (P[0] * planes[i][0] + P[1] * planes[i][1] + P[2] * planes[i][2])) / d;
  1110. if ((t >= mindist) && (t <= maxdist))
  1111. {
  1112. dists[cnt++] = t;
  1113. }
  1114. }
  1115. /* Sort the results for further processing. */
  1116. QSORT((void *)(dists), (size_t)cnt, sizeof(DBL), compdists);
  1117. return(cnt);
  1118. }
  1119. /*****************************************************************************
  1120. *
  1121. * FUNCTION
  1122. *
  1123. * solve_hit1
  1124. *
  1125. * INPUT
  1126. *
  1127. * OUTPUT
  1128. *
  1129. * RETURNS
  1130. *
  1131. * AUTHOR
  1132. *
  1133. * Alexander Enzmann
  1134. *
  1135. * DESCRIPTION
  1136. *
  1137. * Home in on the root of a superquadric using a combination of
  1138. * secant and bisection methods. This routine requires that
  1139. * the sign of the function be different at P0 and P1, it will
  1140. * fail drastically if this isn't the case.
  1141. *
  1142. * CHANGES
  1143. *
  1144. * Nov 1994 : Creation.
  1145. *
  1146. ******************************************************************************/
  1147. static void solve_hit1(SUPERELLIPSOID *Super, DBL v0, VECTOR tP0, DBL v1, VECTOR tP1, VECTOR P)
  1148. {
  1149. int i;
  1150. DBL x, v2, v3;
  1151. VECTOR P0, P1, P2, P3;
  1152. Assign_Vector(P0, tP0);
  1153. Assign_Vector(P1, tP1);
  1154. /* The sign of v0 and v1 changes between P0 and P1, this
  1155. means there is an intersection point in there somewhere. */
  1156. for (i = 0; i < MAX_ITERATIONS; i++)
  1157. {
  1158. if (fabs(v0) < ZERO_TOLERANCE)
  1159. {
  1160. /* Near point is close enough to an intersection - just use it. */
  1161. Assign_Vector(P, P0);
  1162. break;
  1163. }
  1164. if (fabs(v1) < ZERO_TOLERANCE)
  1165. {
  1166. /* Far point is close enough to an intersection. */
  1167. Assign_Vector(P, P1);
  1168. break;
  1169. }
  1170. /* Look at the chord connecting P0 and P1. */
  1171. /* Assume a line between the points. */
  1172. x = fabs(v0) / fabs(v1 - v0);
  1173. VSub(P2, P1, P0);
  1174. VAddScaled(P2, P0, x, P2);
  1175. v2 = evaluate_superellipsoid(P2, Super);
  1176. /* Look at the midpoint between P0 and P1. */
  1177. VSub(P3, P1, P0);
  1178. VAddScaled(P3, P0, 0.5, P3);
  1179. v3 = evaluate_superellipsoid(P3, Super);
  1180. if (v0 * v2 > 0.0)
  1181. {
  1182. if (v1 * v2 > 0.0)
  1183. {
  1184. /* This should be impossible, since v0 and v1 were opposite signs,
  1185. v2 must be either 0 or opposite in sign to either v0 or v1. */
  1186. Error("internal failure in function solve_sq_hit1: %d, %g, %g, %g", i, v0, v1, v2);
  1187. }
  1188. else
  1189. {
  1190. if (v0 * v3 > 0.0)
  1191. {
  1192. if (x < 0.5)
  1193. {
  1194. Assign_Vector(P0, P3);
  1195. }
  1196. else
  1197. {
  1198. Assign_Vector(P0, P2);
  1199. }
  1200. }
  1201. else
  1202. {
  1203. /* We can move both ends. */
  1204. Assign_Vector(P0, P2);
  1205. Assign_Vector(P1, P3);
  1206. }
  1207. }
  1208. }
  1209. else
  1210. {
  1211. if (v0 * v3 > 0.0)
  1212. {
  1213. /* We can move both ends. */
  1214. Assign_Vector(P0, P3);
  1215. Assign_Vector(P1, P2);
  1216. }
  1217. else
  1218. {
  1219. if (x < 0.5)
  1220. {
  1221. Assign_Vector(P1, P2);
  1222. }
  1223. else
  1224. {
  1225. Assign_Vector(P1, P3);
  1226. }
  1227. }
  1228. }
  1229. }
  1230. if (i == MAX_ITERATIONS)
  1231. {
  1232. /* The loop never quite closed in on the result - just use the point
  1233. closest to zero. This really shouldn't happen since the max number
  1234. of iterations is enough to converge with straight bisection. */
  1235. if (fabs(v0) < fabs(v1))
  1236. {
  1237. Assign_Vector(P, P0);
  1238. }
  1239. else
  1240. {
  1241. Assign_Vector(P, P1);
  1242. }
  1243. }
  1244. }
  1245. /*****************************************************************************
  1246. *
  1247. * FUNCTION
  1248. *
  1249. * check_hit2
  1250. *
  1251. * INPUT
  1252. *
  1253. * OUTPUT
  1254. *
  1255. * RETURNS
  1256. *
  1257. * AUTHOR
  1258. *
  1259. * Alexander Enzmann
  1260. *
  1261. * DESCRIPTION
  1262. *
  1263. * Try to find the root of a superquadric using Newtons method.
  1264. *
  1265. * CHANGES
  1266. *
  1267. * Nov 1994 : Creation.
  1268. *
  1269. ******************************************************************************/
  1270. static int check_hit2(SUPERELLIPSOID *Super, VECTOR P, VECTOR D, DBL t0, VECTOR P0, DBL v0, DBL t1, DBL *t, VECTOR Q)
  1271. {
  1272. int i;
  1273. DBL dt0, dt1, v1, deltat, maxdelta;
  1274. VECTOR P1;
  1275. dt0 = t0;
  1276. dt1 = t0 + 0.0001 * (t1 - t0);
  1277. maxdelta = t1 - t0;
  1278. for (i = 0; (dt0 < t1) && (i < MAX_ITERATIONS); i++)
  1279. {
  1280. VEvaluateRay(P1, P, dt1, D)
  1281. v1 = evaluate_superellipsoid(P1, Super);
  1282. if (v0 * v1 < 0)
  1283. {
  1284. /* Found a crossing point, go back and use normal root solving. */
  1285. solve_hit1(Super, v0, P0, v1, P1, Q);
  1286. VSub(P0, Q, P);
  1287. VLength(*t, P0);
  1288. return(TRUE);
  1289. }
  1290. else
  1291. {
  1292. if (fabs(v1) < ZERO_TOLERANCE)
  1293. {
  1294. VEvaluateRay(Q, P, dt1, D)
  1295. *t = dt1;
  1296. return(TRUE);
  1297. }
  1298. else
  1299. {
  1300. if (((v0 > 0.0) && (v1 > v0)) || ((v0 < 0.0) && (v1 < v0)))
  1301. {
  1302. /* We definitely failed */
  1303. break;
  1304. }
  1305. else
  1306. {
  1307. if (v1 == v0)
  1308. {
  1309. break;
  1310. }
  1311. else
  1312. {
  1313. deltat = v1 * (dt1 - dt0) / (v1 - v0);
  1314. }
  1315. }
  1316. }
  1317. }
  1318. if (fabs(deltat) > maxdelta)
  1319. {
  1320. break;
  1321. }
  1322. v0 = v1;
  1323. dt0 = dt1;
  1324. dt1 -= deltat;
  1325. }
  1326. return(FALSE);
  1327. }