NORMAL.C 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /****************************************************************************
  2. * normal.c
  3. *
  4. * This module implements solid texturing functions that perturb the surface
  5. * normal to create a bumpy effect.
  6. *
  7. * from Persistence of Vision(tm) Ray Tracer
  8. * Copyright 1996,1999 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. * NOTICE: This source code file is provided so that users may experiment
  11. * with enhancements to POV-Ray and to port the software to platforms other
  12. * than those supported by the POV-Ray Team. There are strict rules under
  13. * which you are permitted to use this file. The rules are in the file
  14. * named POVLEGAL.DOC which should be distributed with this file.
  15. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  17. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24. /*
  25. * Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3,
  26. * "An Image Synthesizer" By Ken Perlin.
  27. *
  28. * Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley)
  29. */
  30. #include "frame.h"
  31. #include "vector.h"
  32. #include "povproto.h"
  33. #include "texture.h"
  34. #include "image.h"
  35. #include "matrices.h"
  36. #include "normal.h"
  37. #include "povray.h"
  38. #include "txttest.h"
  39. #include "pigment.h"
  40. /*****************************************************************************
  41. * Local preprocessor defines
  42. ******************************************************************************/
  43. /*****************************************************************************
  44. * Local typedefs
  45. ******************************************************************************/
  46. /*****************************************************************************
  47. * Local constants
  48. ******************************************************************************/
  49. static CONST
  50. VECTOR Pyramid_Vect [4]= {{ 0.942809041,-0.333333333, 0.0},
  51. {-0.471404521,-0.333333333, 0.816496581},
  52. {-0.471404521,-0.333333333,-0.816496581},
  53. { 0.0 , 1.0 , 0.0}};
  54. /*****************************************************************************
  55. * Static functions
  56. ******************************************************************************/
  57. static void ripples (VECTOR EPoint, TNORMAL *Tnormal, VECTOR Vector);
  58. static void waves (VECTOR EPoint, TNORMAL *Tnormal, VECTOR Vector);
  59. static void bumps (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal);
  60. static void dents (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal);
  61. static void wrinkles (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal);
  62. static void quilted (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal);
  63. static DBL Hermite_Cubic (DBL T1,UV_VECT UV1,UV_VECT UV2);
  64. static DBL Do_Slope_Map (DBL value, BLEND_MAP *Blend_Map);
  65. static void Do_Average_Normals (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal);
  66. /*****************************************************************************
  67. *
  68. * FUNCTION
  69. *
  70. * ripples
  71. *
  72. * INPUT
  73. *
  74. * OUTPUT
  75. *
  76. * RETURNS
  77. *
  78. * AUTHOR
  79. *
  80. * POV-Ray Team
  81. *
  82. * DESCRIPTION
  83. *
  84. * CHANGES
  85. *
  86. ******************************************************************************/
  87. static void ripples (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
  88. {
  89. register unsigned int i;
  90. register DBL length, scalar, index;
  91. VECTOR point;
  92. for (i = 0 ; i < Number_Of_Waves ; i++)
  93. {
  94. VSub (point, EPoint, Wave_Sources[i]);
  95. VLength (length, point);
  96. if (length == 0.0)
  97. length = 1.0;
  98. index = length * Tnormal->Frequency + Tnormal->Phase;
  99. scalar = cycloidal(index) * Tnormal ->Amount;
  100. VAddScaledEq(normal, scalar / (length * (DBL)Number_Of_Waves), point);
  101. }
  102. }
  103. /*****************************************************************************
  104. *
  105. * FUNCTION
  106. *
  107. * waves
  108. *
  109. * INPUT
  110. *
  111. * OUTPUT
  112. *
  113. * RETURNS
  114. *
  115. * AUTHOR
  116. *
  117. * POV-Ray Team
  118. *
  119. * DESCRIPTION
  120. *
  121. * CHANGES
  122. *
  123. ******************************************************************************/
  124. static void waves (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
  125. {
  126. register unsigned int i;
  127. register DBL length, scalar, index, sinValue ;
  128. VECTOR point;
  129. for (i = 0 ; i < Number_Of_Waves ; i++)
  130. {
  131. VSub (point, EPoint, Wave_Sources[i]);
  132. VLength (length, point);
  133. if (length == 0.0)
  134. {
  135. length = 1.0;
  136. }
  137. index = length * Tnormal->Frequency * frequency[i] + Tnormal->Phase;
  138. sinValue = cycloidal(index);
  139. scalar = sinValue * Tnormal->Amount / frequency[i];
  140. VAddScaledEq(normal, scalar / (length * (DBL)Number_Of_Waves), point);
  141. }
  142. }
  143. /*****************************************************************************
  144. *
  145. * FUNCTION
  146. *
  147. * bumps
  148. *
  149. * INPUT
  150. *
  151. * OUTPUT
  152. *
  153. * RETURNS
  154. *
  155. * AUTHOR
  156. *
  157. * POV-Ray Team
  158. *
  159. * DESCRIPTION
  160. *
  161. * CHANGES
  162. *
  163. ******************************************************************************/
  164. static void bumps (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
  165. {
  166. VECTOR bump_turb;
  167. /* Get normal displacement value. */
  168. DNoise (bump_turb, EPoint);
  169. /* Displace "normal". */
  170. VAddScaledEq(normal, Tnormal->Amount, bump_turb);
  171. }
  172. /*****************************************************************************
  173. *
  174. * FUNCTION
  175. *
  176. * INPUT
  177. *
  178. * OUTPUT
  179. *
  180. * RETURNS
  181. *
  182. * AUTHOR
  183. *
  184. * POV-Ray Team
  185. *
  186. * DESCRIPTION
  187. * Dents is similar to bumps, but uses noise() to control the amount of
  188. * dnoise() perturbation of the object normal...
  189. *
  190. * CHANGES
  191. *
  192. ******************************************************************************/
  193. static void dents (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
  194. {
  195. DBL noise;
  196. VECTOR stucco_turb;
  197. noise = Noise (EPoint);
  198. noise = noise * noise * noise * Tnormal->Amount;
  199. /* Get normal displacement value. */
  200. DNoise(stucco_turb, EPoint);
  201. /* Displace "normal". */
  202. VAddScaledEq(normal, noise, stucco_turb);
  203. }
  204. /*****************************************************************************
  205. *
  206. * FUNCTION
  207. *
  208. * INPUT
  209. *
  210. * OUTPUT
  211. *
  212. * RETURNS
  213. *
  214. * AUTHOR
  215. *
  216. * POV-Ray Team
  217. *
  218. * DESCRIPTION
  219. *
  220. * Wrinkles - This is my implementation of the dented() routine, using
  221. * a surface iterative fractal derived from DTurbulence.
  222. *
  223. * This is a 3-D version (thanks to DNoise()...) of the usual version
  224. * using the singular Noise()...
  225. *
  226. * Seems to look a lot like wrinkles, however... (hmmm)
  227. *
  228. * Idea garnered from the April 89 Byte Graphics Supplement on RenderMan,
  229. * refined from "The RenderMan Companion, by Steve Upstill of Pixar,
  230. * (C) 1990 Addison-Wesley.
  231. *
  232. * CHANGES
  233. *
  234. ******************************************************************************/
  235. static void wrinkles (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
  236. {
  237. register int i;
  238. register DBL scale = 1.0;
  239. VECTOR result, value, value2;
  240. Make_Vector(result, 0.0, 0.0, 0.0);
  241. for (i = 0; i < 10; scale *= 2.0, i++)
  242. {
  243. VScale(value2,EPoint,scale);
  244. DNoise(value, value2);
  245. result[X] += fabs(value[X] / scale);
  246. result[Y] += fabs(value[Y] / scale);
  247. result[Z] += fabs(value[Z] / scale);
  248. }
  249. /* Displace "normal". */
  250. VAddScaledEq(normal, Tnormal->Amount, result);
  251. }
  252. /*****************************************************************************
  253. *
  254. * FUNCTION
  255. *
  256. * quilted
  257. *
  258. * INPUT
  259. *
  260. * OUTPUT
  261. *
  262. * RETURNS
  263. *
  264. * AUTHOR
  265. *
  266. * Dan Farmer '94
  267. *
  268. * DESCRIPTION
  269. *
  270. * CHANGES
  271. *
  272. ******************************************************************************/
  273. static void quilted (VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
  274. {
  275. VECTOR value;
  276. DBL t;
  277. value[X] = EPoint[X]-FLOOR(EPoint[X])-0.5;
  278. value[Y] = EPoint[Y]-FLOOR(EPoint[Y])-0.5;
  279. value[Z] = EPoint[Z]-FLOOR(EPoint[Z])-0.5;
  280. t = sqrt(value[X]*value[X]+value[Y]*value[Y]+value[Z]*value[Z]);
  281. t = quilt_cubic(t, Tnormal->Vals.Quilted.Control0, Tnormal->Vals.Quilted.Control1);
  282. value[X] *= t;
  283. value[Y] *= t;
  284. value[Z] *= t;
  285. VAddScaledEq (normal, Tnormal->Amount,value);
  286. }
  287. /*****************************************************************************
  288. *
  289. * FUNCTION
  290. *
  291. * Create_Tnormal
  292. *
  293. * INPUT
  294. *
  295. * OUTPUT
  296. *
  297. * RETURNS
  298. *
  299. * pointer to the created Tnormal
  300. *
  301. * AUTHOR
  302. *
  303. * POV-Ray Team
  304. *
  305. * DESCRIPTION : Allocate memory for new Tnormal and initialize it to
  306. * system default values.
  307. *
  308. * CHANGES
  309. *
  310. ******************************************************************************/
  311. TNORMAL *Create_Tnormal ()
  312. {
  313. TNORMAL *New;
  314. New = (TNORMAL *)POV_MALLOC(sizeof(TNORMAL), "normal");
  315. Init_TPat_Fields((TPATTERN *)New);
  316. New->Amount = 0.5;
  317. return (New);
  318. }
  319. /*****************************************************************************
  320. *
  321. * FUNCTION
  322. *
  323. * Copy_Tnormal
  324. *
  325. * INPUT
  326. *
  327. * OUTPUT
  328. *
  329. * RETURNS
  330. *
  331. * AUTHOR
  332. *
  333. * POV-Ray Team
  334. *
  335. * DESCRIPTION
  336. *
  337. * CHANGES
  338. *
  339. ******************************************************************************/
  340. TNORMAL *Copy_Tnormal (TNORMAL *Old)
  341. {
  342. TNORMAL *New;
  343. if (Old != NULL)
  344. {
  345. New = Create_Tnormal();
  346. Copy_TPat_Fields ((TPATTERN *)New, (TPATTERN *)Old);
  347. New->Amount = Old->Amount;
  348. }
  349. else
  350. {
  351. New = NULL;
  352. }
  353. return (New);
  354. }
  355. /*****************************************************************************
  356. *
  357. * FUNCTION
  358. *
  359. * Destroy_Tnormal
  360. *
  361. * INPUT
  362. *
  363. * OUTPUT
  364. *
  365. * RETURNS
  366. *
  367. * AUTHOR
  368. *
  369. * POV-Ray Team
  370. *
  371. * DESCRIPTION
  372. *
  373. * CHANGES
  374. *
  375. ******************************************************************************/
  376. void Destroy_Tnormal(TNORMAL *Tnormal)
  377. {
  378. if (Tnormal != NULL)
  379. {
  380. Destroy_TPat_Fields ((TPATTERN *)Tnormal);
  381. POV_FREE(Tnormal);
  382. }
  383. }
  384. /*****************************************************************************
  385. *
  386. * FUNCTION
  387. *
  388. * Post_Tnormal
  389. *
  390. * INPUT
  391. *
  392. * OUTPUT
  393. *
  394. * RETURNS
  395. *
  396. * AUTHOR
  397. *
  398. * POV-Ray Team
  399. *
  400. * DESCRIPTION
  401. *
  402. * CHANGES
  403. *
  404. ******************************************************************************/
  405. void Post_Tnormal (TNORMAL *Tnormal)
  406. {
  407. int i;
  408. BLEND_MAP *Map;
  409. if (Tnormal != NULL)
  410. {
  411. if (Tnormal->Flags & POST_DONE)
  412. {
  413. return;
  414. }
  415. if (Tnormal->Type == NO_PATTERN)
  416. {
  417. Error("No normal type given.");
  418. }
  419. Tnormal->Flags |= POST_DONE;
  420. if ((Map = Tnormal->Blend_Map) != NULL)
  421. {
  422. for (i = 0; i < Map->Number_Of_Entries; i++)
  423. {
  424. switch (Map->Type)
  425. {
  426. case PIGMENT_TYPE:
  427. Post_Pigment(Map->Blend_Map_Entries[i].Vals.Pigment);
  428. break;
  429. case NORMAL_TYPE:
  430. Post_Tnormal(Map->Blend_Map_Entries[i].Vals.Tnormal);
  431. break;
  432. case TEXTURE_TYPE:
  433. Post_Textures(Map->Blend_Map_Entries[i].Vals.Texture);
  434. break;
  435. case SLOPE_TYPE:
  436. case COLOUR_TYPE:
  437. case PATTERN_TYPE:
  438. break;
  439. default:
  440. Error("Unknown pattern type in Post_Tnormal.");
  441. }
  442. }
  443. }
  444. }
  445. }
  446. /*****************************************************************************
  447. *
  448. * FUNCTION
  449. *
  450. * Perturb_Normal
  451. *
  452. * INPUT
  453. *
  454. * OUTPUT
  455. *
  456. * RETURNS
  457. *
  458. * AUTHOR
  459. *
  460. * POV-Ray Team
  461. *
  462. * DESCRIPTION
  463. *
  464. * CHANGES
  465. *
  466. ******************************************************************************/
  467. #define DELTA 0.02
  468. void Perturb_Normal(VECTOR Layer_Normal, TNORMAL *Tnormal, VECTOR EPoint)
  469. {
  470. VECTOR TPoint,P1;
  471. DBL value1,value2,Amount;
  472. int i;
  473. BLEND_MAP *Blend_Map;
  474. BLEND_MAP_ENTRY *Prev, *Cur;
  475. if (Tnormal==NULL)
  476. {
  477. return;
  478. }
  479. /* If normal_map present, use it and return */
  480. if ((Blend_Map=Tnormal->Blend_Map) != NULL)
  481. {
  482. if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type != AVERAGE_PATTERN))
  483. {
  484. value1 = Evaluate_TPat((TPATTERN *)Tnormal,EPoint);
  485. Search_Blend_Map (value1,Blend_Map,&Prev,&Cur);
  486. Assign_Vector(P1,Layer_Normal);
  487. Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);
  488. Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint);
  489. if (Prev != Cur)
  490. {
  491. Perturb_Normal(P1,Prev->Vals.Tnormal,TPoint);
  492. value2 = (value1-Prev->value)/(Cur->value-Prev->value);
  493. value1 = 1.0-value2;
  494. VLinComb2(Layer_Normal,value1,P1,value2,Layer_Normal)
  495. }
  496. VNormalizeEq(Layer_Normal);
  497. return;
  498. }
  499. }
  500. /* No normal_map. */
  501. if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN)
  502. {
  503. Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);
  504. switch (Tnormal->Type)
  505. {
  506. case BITMAP_PATTERN: bump_map (TPoint, Tnormal, Layer_Normal); break;
  507. case BUMPS_PATTERN: bumps (TPoint, Tnormal, Layer_Normal); break;
  508. case DENTS_PATTERN: dents (TPoint, Tnormal, Layer_Normal); break;
  509. case RIPPLES_PATTERN:ripples (TPoint, Tnormal, Layer_Normal); break;
  510. case WAVES_PATTERN: waves (TPoint, Tnormal, Layer_Normal); break;
  511. case WRINKLES_PATTERN:wrinkles (TPoint, Tnormal, Layer_Normal);break;
  512. case QUILTED_PATTERN:quilted (TPoint, Tnormal, Layer_Normal); break;
  513. case AVERAGE_PATTERN: Do_Average_Normals (TPoint, Tnormal, Layer_Normal); break;
  514. default:
  515. Error("Normal pattern not yet implemented.");
  516. }
  517. }
  518. else
  519. {
  520. Amount=Tnormal->Amount * -5.0; /*fudge factor*/
  521. /* Note, even though DELTA and Pyramid_Vect are constants, we may later
  522. make DELTA a user-defined parameter. Good optimising compilers
  523. should merge the constants anyway. */
  524. for(i=0; i<=3; i++)
  525. {
  526. VAddScaled(P1,EPoint,DELTA,Pyramid_Vect[i]);
  527. value1 = Do_Slope_Map(Evaluate_TPat((TPATTERN *)Tnormal,P1),Blend_Map);
  528. VAddScaledEq(Layer_Normal,value1*Amount,Pyramid_Vect[i]);
  529. }
  530. }
  531. VNormalizeEq(Layer_Normal);
  532. }
  533. /*****************************************************************************
  534. *
  535. * FUNCTION
  536. *
  537. * INPUT
  538. *
  539. * OUTPUT
  540. *
  541. * RETURNS
  542. *
  543. * AUTHOR
  544. *
  545. * DESCRIPTION
  546. *
  547. * CHANGES
  548. *
  549. ******************************************************************************/
  550. static DBL Do_Slope_Map (DBL value,BLEND_MAP *Blend_Map)
  551. {
  552. DBL Result;
  553. BLEND_MAP_ENTRY *Prev, *Cur;
  554. if (Blend_Map == NULL)
  555. {
  556. return(value);
  557. }
  558. Search_Blend_Map (value,Blend_Map,&Prev,&Cur);
  559. if (Prev == Cur)
  560. {
  561. return(Cur->Vals.Point_Slope[0]);
  562. }
  563. Result = (value-Prev->value)/(Cur->value-Prev->value);
  564. return(Hermite_Cubic(Result,Prev->Vals.Point_Slope,Cur->Vals.Point_Slope));
  565. }
  566. /*****************************************************************************
  567. *
  568. * FUNCTION
  569. *
  570. * INPUT
  571. *
  572. * OUTPUT
  573. *
  574. * RETURNS
  575. *
  576. * AUTHOR
  577. *
  578. * DESCRIPTION
  579. *
  580. * CHANGES
  581. *
  582. ******************************************************************************/
  583. #define S1 UV1[1]
  584. #define S2 UV2[1]
  585. #define P1 UV1[0]
  586. #define P2 UV2[0]
  587. static DBL Hermite_Cubic(DBL T1,UV_VECT UV1,UV_VECT UV2)
  588. {
  589. DBL TT=T1*T1;
  590. DBL TTT=TT*T1;
  591. DBL rv; /* simplified equation for poor Symantec */
  592. rv = TTT*(S1+S2+2.0*(P1-P2));
  593. rv += -TT*(2.0*S1+S2+3.0*(P1-P2));
  594. rv += T1*S1 +P1;
  595. return (rv);
  596. }
  597. /*****************************************************************************
  598. *
  599. * FUNCTION
  600. *
  601. * INPUT
  602. *
  603. * OUTPUT
  604. *
  605. * RETURNS
  606. *
  607. * AUTHOR
  608. *
  609. * DESCRIPTION
  610. *
  611. * CHANGES
  612. *
  613. ******************************************************************************/
  614. static void Do_Average_Normals (VECTOR EPoint,TNORMAL *Tnormal,VECTOR normal)
  615. {
  616. int i;
  617. BLEND_MAP *Map = Tnormal->Blend_Map;
  618. SNGL Value;
  619. SNGL Total = 0.0;
  620. VECTOR V1,V2;
  621. Make_Vector (V1, 0.0, 0.0, 0.0);
  622. for (i = 0; i < Map->Number_Of_Entries; i++)
  623. {
  624. Value = Map->Blend_Map_Entries[i].value;
  625. Assign_Vector(V2,normal);
  626. Perturb_Normal(V2,Map->Blend_Map_Entries[i].Vals.Tnormal,EPoint);
  627. VAddScaledEq(V1,Value,V2);
  628. Total += Value;
  629. }
  630. VInverseScale(normal,V1,Total);
  631. }