home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Graphics / SPD / Sources / teapot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-10  |  16.0 KB  |  656 lines  |  [TEXT/R*ch]

  1. /*
  2.  * teapot.c - Tessellate the famous teapot into triangular patches, and sit the
  3.  *    object on top of a checkerboard which is meshed to the same degree.  In
  4.  *    other words, the number of squares on the checkerboard is the same as
  5.  *    the amount of meshing for each of the 32 patches on the teapot, with
  6.  *    each mesh quadrilateral on the teapot further split into two triangles.
  7.  *    Two light sources.
  8.  *
  9.  *    Note that the teapot should always be rendered as a double sided object
  10.  *    (since for some patches both sides can be seen).  (See IEEE CG&A
  11.  *    January 1987 for a history of the teapot.  Note that their vertex list
  12.  *    has duplicates, e.g. 93 and 271, as well as unused vertices, e.g.
  13.  *    205,206,216,223).  Also, note that the bottom (the last four patches)
  14.  *    is not flat - blame Frank Crow, not me.
  15.  *
  16.  * Author:  Eric Haines, 3D/Eye, Inc.
  17.  *
  18.  * size_factor determines the number of objects output.
  19.  *    Total patches = 32*2*n*n - 8*n     [degenerates are deleted]
  20.  *    Total squares = n*n
  21.  *
  22.  *    size_factor    # patches    # squares
  23.  *         1            56             1        [has more degenerates!]
  24.  *         2           240             4
  25.  *         3           552             9
  26.  *
  27.  *        12          9120           144
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <math.h>
  32. #include <stdlib.h>    /* atoi */
  33. #include "def.h"
  34. #include "drv.h"    /* display_close() */
  35. #include "lib.h"
  36.  
  37. static int size_factor = 6 ;
  38. static int raytracer_format = OUTPUT_RT_DEFAULT;
  39. static int output_format    = OUTPUT_CURVES;
  40.  
  41. #ifdef OUTPUT_TO_FILE
  42. static FILE * stdout_file = NULL;
  43. #else
  44. #define stdout_file stdout
  45. #endif /* OUTPUT_TO_FILE */
  46.  
  47. /* comment out the next line to generate all patches except the bottom,
  48.  * i.e. the original Newell teapot
  49.  */
  50. #define BOTTOM
  51.  
  52. #ifdef    BOTTOM
  53. #define    NUM_PATCHES    32
  54. #else
  55. #define    NUM_PATCHES    28
  56. #endif
  57.  
  58.  
  59. static    int    Patches[32][4][4] = {
  60. /* rim */
  61. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  62. 3, 16, 17, 18, 7, 19, 20, 21, 11, 22, 23, 24, 15, 25, 26, 27,
  63. 18, 28, 29, 30, 21, 31, 32, 33, 24, 34, 35, 36, 27, 37, 38, 39,
  64. 30, 40, 41, 0, 33, 42, 43, 4, 36, 44, 45, 8, 39, 46, 47, 12,
  65. /* body */
  66. 12, 13, 14, 15, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  67. 15, 25, 26, 27, 51, 60, 61, 62, 55, 63, 64, 65, 59, 66, 67, 68,
  68. 27, 37, 38, 39, 62, 69, 70, 71, 65, 72, 73, 74, 68, 75, 76, 77,
  69. 39, 46, 47, 12, 71, 78, 79, 48, 74, 80, 81, 52, 77, 82, 83, 56,
  70. 56, 57, 58, 59, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  71. 59, 66, 67, 68, 87, 96, 97, 98, 91, 99, 100, 101, 95, 102, 103, 104,
  72. 68, 75, 76, 77, 98, 105, 106, 107, 101, 108, 109, 110, 104, 111, 112, 113,
  73. 77, 82, 83, 56, 107, 114, 115, 84, 110, 116, 117, 88, 113, 118, 119, 92,
  74. /* handle */
  75. 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
  76. 123, 136, 137, 120, 127, 138, 139, 124, 131, 140, 141, 128, 135, 142, 143, 132,
  77. 132, 133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 151, 68, 152, 153, 154,
  78. 135, 142, 143, 132, 147, 155, 156, 144, 151, 157, 158, 148, 154, 159, 160, 68,
  79. /* spout */
  80. 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
  81. 164, 177, 178, 161, 168, 179, 180, 165, 172, 181, 182, 169, 176, 183, 184, 173,
  82. 173, 174, 175, 176, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
  83. 176, 183, 184, 173, 188, 197, 198, 185, 192, 199, 200, 189, 196, 201, 202, 193,
  84. /* lid */
  85. 203, 203, 203, 203, 204, 205, 206, 207, 208, 208, 208, 208, 209, 210, 211, 212,
  86. 203, 203, 203, 203, 207, 213, 214, 215, 208, 208, 208, 208, 212, 216, 217, 218,
  87. 203, 203, 203, 203, 215, 219, 220, 221, 208, 208, 208, 208, 218, 222, 223, 224,
  88. 203, 203, 203, 203, 221, 225, 226, 204, 208, 208, 208, 208, 224, 227, 228, 209,
  89. 209, 210, 211, 212, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240,
  90. 212, 216, 217, 218, 232, 241, 242, 243, 236, 244, 245, 246, 240, 247, 248, 249,
  91. 218, 222, 223, 224, 243, 250, 251, 252, 246, 253, 254, 255, 249, 256, 257, 258,
  92. 224, 227, 228, 209, 252, 259, 260, 229, 255, 261, 262, 233, 258, 263, 264, 237,
  93. /* bottom */
  94. 265, 265, 265, 265, 266, 267, 268, 269, 270, 271, 272, 273, 92, 119, 118, 113,
  95. 265, 265, 265, 265, 269, 274, 275, 276, 273, 277, 278, 279, 113, 112, 111, 104,
  96. 265, 265, 265, 265, 276, 280, 281, 282, 279, 283, 284, 285, 104, 103, 102, 95,
  97. 265, 265, 265, 265, 282, 286, 287, 266, 285, 288, 289, 270, 95, 94, 93, 92
  98. } ;
  99.  
  100. static    COORD3    Verts[290] = {
  101.  1.4, 0, 2.4,
  102.  1.4, -0.784, 2.4,
  103.  0.784, -1.4, 2.4,
  104.  0, -1.4, 2.4,
  105.  1.3375, 0, 2.53125,
  106.  1.3375, -0.749, 2.53125,
  107.  0.749, -1.3375, 2.53125,
  108.  0, -1.3375, 2.53125,
  109.  1.4375, 0, 2.53125,
  110.  1.4375, -0.805, 2.53125,
  111.  0.805, -1.4375, 2.53125,
  112.  0, -1.4375, 2.53125,
  113.  1.5, 0, 2.4,
  114.  1.5, -0.84, 2.4,
  115.  0.84, -1.5, 2.4,
  116.  0, -1.5, 2.4,
  117.  -0.784, -1.4, 2.4,
  118.  -1.4, -0.784, 2.4,
  119.  -1.4, 0, 2.4,
  120.  -0.749, -1.3375, 2.53125,
  121.  -1.3375, -0.749, 2.53125,
  122.  -1.3375, 0, 2.53125,
  123.  -0.805, -1.4375, 2.53125,
  124.  -1.4375, -0.805, 2.53125,
  125.  -1.4375, 0, 2.53125,
  126.  -0.84, -1.5, 2.4,
  127.  -1.5, -0.84, 2.4,
  128.  -1.5, 0, 2.4,
  129.  -1.4, 0.784, 2.4,
  130.  -0.784, 1.4, 2.4,
  131.  0, 1.4, 2.4,
  132.  -1.3375, 0.749, 2.53125,
  133.  -0.749, 1.3375, 2.53125,
  134.  0, 1.3375, 2.53125,
  135.  -1.4375, 0.805, 2.53125,
  136.  -0.805, 1.4375, 2.53125,
  137.  0, 1.4375, 2.53125,
  138.  -1.5, 0.84, 2.4,
  139.  -0.84, 1.5, 2.4,
  140.  0, 1.5, 2.4,
  141.  0.784, 1.4, 2.4,
  142.  1.4, 0.784, 2.4,
  143.  0.749, 1.3375, 2.53125,
  144.  1.3375, 0.749, 2.53125,
  145.  0.805, 1.4375, 2.53125,
  146.  1.4375, 0.805, 2.53125,
  147.  0.84, 1.5, 2.4,
  148.  1.5, 0.84, 2.4,
  149.  1.75, 0, 1.875,
  150.  1.75, -0.98, 1.875,
  151.  0.98, -1.75, 1.875,
  152.  0, -1.75, 1.875,
  153.  2, 0, 1.35,
  154.  2, -1.12, 1.35,
  155.  1.12, -2, 1.35,
  156.  0, -2, 1.35,
  157.  2, 0, 0.9,
  158.  2, -1.12, 0.9,
  159.  1.12, -2, 0.9,
  160.  0, -2, 0.9,
  161.  -0.98, -1.75, 1.875,
  162.  -1.75, -0.98, 1.875,
  163.  -1.75, 0, 1.875,
  164.  -1.12, -2, 1.35,
  165.  -2, -1.12, 1.35,
  166.  -2, 0, 1.35,
  167.  -1.12, -2, 0.9,
  168.  -2, -1.12, 0.9,
  169.  -2, 0, 0.9,
  170.  -1.75, 0.98, 1.875,
  171.  -0.98, 1.75, 1.875,
  172.  0, 1.75, 1.875,
  173.  -2, 1.12, 1.35,
  174.  -1.12, 2, 1.35,
  175.  0, 2, 1.35,
  176.  -2, 1.12, 0.9,
  177.  -1.12, 2, 0.9,
  178.  0, 2, 0.9,
  179.  0.98, 1.75, 1.875,
  180.  1.75, 0.98, 1.875,
  181.  1.12, 2, 1.35,
  182.  2, 1.12, 1.35,
  183.  1.12, 2, 0.9,
  184.  2, 1.12, 0.9,
  185.  2, 0, 0.45,
  186.  2, -1.12, 0.45,
  187.  1.12, -2, 0.45,
  188.  0, -2, 0.45,
  189.  1.5, 0, 0.225,
  190.  1.5, -0.84, 0.225,
  191.  0.84, -1.5, 0.225,
  192.  0, -1.5, 0.225,
  193.  1.5, 0, 0.15,
  194.  1.5, -0.84, 0.15,
  195.  0.84, -1.5, 0.15,
  196.  0, -1.5, 0.15,
  197.  -1.12, -2, 0.45,
  198.  -2, -1.12, 0.45,
  199.  -2, 0, 0.45,
  200.  -0.84, -1.5, 0.225,
  201.  -1.5, -0.84, 0.225,
  202.  -1.5, 0, 0.225,
  203.  -0.84, -1.5, 0.15,
  204.  -1.5, -0.84, 0.15,
  205.  -1.5, 0, 0.15,
  206.  -2, 1.12, 0.45,
  207.  -1.12, 2, 0.45,
  208.  0, 2, 0.45,
  209.  -1.5, 0.84, 0.225,
  210.  -0.84, 1.5, 0.225,
  211.  0, 1.5, 0.225,
  212.  -1.5, 0.84, 0.15,
  213.  -0.84, 1.5, 0.15,
  214.  0, 1.5, 0.15,
  215.  1.12, 2, 0.45,
  216.  2, 1.12, 0.45,
  217.  0.84, 1.5, 0.225,
  218.  1.5, 0.84, 0.225,
  219.  0.84, 1.5, 0.15,
  220.  1.5, 0.84, 0.15,
  221.  -1.6, 0, 2.025,
  222.  -1.6, -0.3, 2.025,
  223.  -1.5, -0.3, 2.25,
  224.  -1.5, 0, 2.25,
  225.  -2.3, 0, 2.025,
  226.  -2.3, -0.3, 2.025,
  227.  -2.5, -0.3, 2.25,
  228.  -2.5, 0, 2.25,
  229.  -2.7, 0, 2.025,
  230.  -2.7, -0.3, 2.025,
  231.  -3, -0.3, 2.25,
  232.  -3, 0, 2.25,
  233.  -2.7, 0, 1.8,
  234.  -2.7, -0.3, 1.8,
  235.  -3, -0.3, 1.8,
  236.  -3, 0, 1.8,
  237.  -1.5, 0.3, 2.25,
  238.  -1.6, 0.3, 2.025,
  239.  -2.5, 0.3, 2.25,
  240.  -2.3, 0.3, 2.025,
  241.  -3, 0.3, 2.25,
  242.  -2.7, 0.3, 2.025,
  243.  -3, 0.3, 1.8,
  244.  -2.7, 0.3, 1.8,
  245.  -2.7, 0, 1.575,
  246.  -2.7, -0.3, 1.575,
  247.  -3, -0.3, 1.35,
  248.  -3, 0, 1.35,
  249.  -2.5, 0, 1.125,
  250.  -2.5, -0.3, 1.125,
  251.  -2.65, -0.3, 0.9375,
  252.  -2.65, 0, 0.9375,
  253.  -2, -0.3, 0.9,
  254.  -1.9, -0.3, 0.6,
  255.  -1.9, 0, 0.6,
  256.  -3, 0.3, 1.35,
  257.  -2.7, 0.3, 1.575,
  258.  -2.65, 0.3, 0.9375,
  259.  -2.5, 0.3, 1.125,
  260.  -1.9, 0.3, 0.6,
  261.  -2, 0.3, 0.9,
  262.  1.7, 0, 1.425,
  263.  1.7, -0.66, 1.425,
  264.  1.7, -0.66, 0.6,
  265.  1.7, 0, 0.6,
  266.  2.6, 0, 1.425,
  267.  2.6, -0.66, 1.425,
  268.  3.1, -0.66, 0.825,
  269.  3.1, 0, 0.825,
  270.  2.3, 0, 2.1,
  271.  2.3, -0.25, 2.1,
  272.  2.4, -0.25, 2.025,
  273.  2.4, 0, 2.025,
  274.  2.7, 0, 2.4,
  275.  2.7, -0.25, 2.4,
  276.  3.3, -0.25, 2.4,
  277.  3.3, 0, 2.4,
  278.  1.7, 0.66, 0.6,
  279.  1.7, 0.66, 1.425,
  280.  3.1, 0.66, 0.825,
  281.  2.6, 0.66, 1.425,
  282.  2.4, 0.25, 2.025,
  283.  2.3, 0.25, 2.1,
  284.  3.3, 0.25, 2.4,
  285.  2.7, 0.25, 2.4,
  286.  2.8, 0, 2.475,
  287.  2.8, -0.25, 2.475,
  288.  3.525, -0.25, 2.49375,
  289.  3.525, 0, 2.49375,
  290.  2.9, 0, 2.475,
  291.  2.9, -0.15, 2.475,
  292.  3.45, -0.15, 2.5125,
  293.  3.45, 0, 2.5125,
  294.  2.8, 0, 2.4,
  295.  2.8, -0.15, 2.4,
  296.  3.2, -0.15, 2.4,
  297.  3.2, 0, 2.4,
  298.  3.525, 0.25, 2.49375,
  299.  2.8, 0.25, 2.475,
  300.  3.45, 0.15, 2.5125,
  301.  2.9, 0.15, 2.475,
  302.  3.2, 0.15, 2.4,
  303.  2.8, 0.15, 2.4,
  304.  0, 0, 3.15,
  305.  0.8, 0, 3.15,
  306.  0.8, -0.45, 3.15,
  307.  0.45, -0.8, 3.15,
  308.  0, -0.8, 3.15,
  309.  0, 0, 2.85,
  310.  0.2, 0, 2.7,
  311.  0.2, -0.112, 2.7,
  312.  0.112, -0.2, 2.7,
  313.  0, -0.2, 2.7,
  314.  -0.45, -0.8, 3.15,
  315.  -0.8, -0.45, 3.15,
  316.  -0.8, 0, 3.15,
  317.  -0.112, -0.2, 2.7,
  318.  -0.2, -0.112, 2.7,
  319.  -0.2, 0, 2.7,
  320.  -0.8, 0.45, 3.15,
  321.  -0.45, 0.8, 3.15,
  322.  0, 0.8, 3.15,
  323.  -0.2, 0.112, 2.7,
  324.  -0.112, 0.2, 2.7,
  325.  0, 0.2, 2.7,
  326.  0.45, 0.8, 3.15,
  327.  0.8, 0.45, 3.15,
  328.  0.112, 0.2, 2.7,
  329.  0.2, 0.112, 2.7,
  330.  0.4, 0, 2.55,
  331.  0.4, -0.224, 2.55,
  332.  0.224, -0.4, 2.55,
  333.  0, -0.4, 2.55,
  334.  1.3, 0, 2.55,
  335.  1.3, -0.728, 2.55,
  336.  0.728, -1.3, 2.55,
  337.  0, -1.3, 2.55,
  338.  1.3, 0, 2.4,
  339.  1.3, -0.728, 2.4,
  340.  0.728, -1.3, 2.4,
  341.  0, -1.3, 2.4,
  342.  -0.224, -0.4, 2.55,
  343.  -0.4, -0.224, 2.55,
  344.  -0.4, 0, 2.55,
  345.  -0.728, -1.3, 2.55,
  346.  -1.3, -0.728, 2.55,
  347.  -1.3, 0, 2.55,
  348.  -0.728, -1.3, 2.4,
  349.  -1.3, -0.728, 2.4,
  350.  -1.3, 0, 2.4,
  351.  -0.4, 0.224, 2.55,
  352.  -0.224, 0.4, 2.55,
  353.  0, 0.4, 2.55,
  354.  -1.3, 0.728, 2.55,
  355.  -0.728, 1.3, 2.55,
  356.  0, 1.3, 2.55,
  357.  -1.3, 0.728, 2.4,
  358.  -0.728, 1.3, 2.4,
  359.  0, 1.3, 2.4,
  360.  0.224, 0.4, 2.55,
  361.  0.4, 0.224, 2.55,
  362.  0.728, 1.3, 2.55,
  363.  1.3, 0.728, 2.55,
  364.  0.728, 1.3, 2.4,
  365.  1.3, 0.728, 2.4,
  366.  0, 0, 0,
  367.  1.425, 0, 0,
  368.  1.425, 0.798, 0,
  369.  0.798, 1.425, 0,
  370.  0, 1.425, 0,
  371.  1.5, 0, 0.075,
  372.  1.5, 0.84, 0.075,
  373.  0.84, 1.5, 0.075,
  374.  0, 1.5, 0.075,
  375.  -0.798, 1.425, 0,
  376.  -1.425, 0.798, 0,
  377.  -1.425, 0, 0,
  378.  -0.84, 1.5, 0.075,
  379.  -1.5, 0.84, 0.075,
  380.  -1.5, 0, 0.075,
  381.  -1.425, -0.798, 0,
  382.  -0.798, -1.425, 0,
  383.  0, -1.425, 0,
  384.  -1.5, -0.84, 0.075,
  385.  -0.84, -1.5, 0.075,
  386.  0, -1.5, 0.075,
  387.  0.798, -1.425, 0,
  388.  1.425, -0.798, 0,
  389.  0.84, -1.5, 0.075,
  390.  1.5, -0.84, 0.075
  391. } ;
  392.  
  393.  
  394. /* at the center of the lid's handle and at bottom are cusp points -
  395.  * check if normal is (0 0 0), if so, check that polygon is not degenerate.
  396.  * If degenerate, return FALSE, else set normal.
  397.  */
  398. int    check_for_cusp( tot_vert, vert, norm )
  399. int    tot_vert ;
  400. COORD3    vert[] ;
  401. COORD3    norm[] ;
  402. {
  403. int    count, i, nv ;
  404.  
  405.     for ( count = 0, i = tot_vert ; i-- ; ) {
  406.     /* check if vertex is at cusp */
  407.     if ( IS_VAL_ALMOST_ZERO( vert[i][X], 0.0001 ) &&
  408.          IS_VAL_ALMOST_ZERO( vert[i][Y], 0.0001 ) ) {
  409.         count++ ;
  410.         nv = i ;
  411.     }
  412.     }
  413.  
  414.     if ( count > 1 ) {
  415.     /* degenerate */
  416.     return( FALSE ) ;
  417.     }
  418.     if ( count == 1 ) {
  419.     /* check if point is somewhere above the middle of the teapot */
  420.     if ( vert[nv][Z] > 1.5 ) {
  421.         /* cusp at lid */
  422.         SET_COORD3( norm[nv], 0.0, 0.0, 1.0 ) ;
  423.     } else {
  424.         /* cusp at bottom */
  425.         SET_COORD3( norm[nv], 0.0, 0.0, -1.0 ) ;
  426.     }
  427.     }
  428.     return( TRUE ) ;
  429. }
  430.  
  431.  
  432. points_from_basis( tot_vert, s, t, mgm, vert, norm )
  433. int    tot_vert ;
  434. double    s[] ;
  435. double    t[] ;
  436. MATRIX    mgm[3] ;
  437. COORD3    vert[] ;
  438. COORD3    norm[] ;
  439. {
  440. int    i, num_vert, p ;
  441. double    sval, tval, dsval, dtval, sxyz, txyz ;
  442. COORD3    sdir, tdir ;
  443. COORD4    sp, tp, dsp, dtp, tcoord ;
  444.  
  445.     for ( num_vert = 0 ; num_vert < tot_vert ; num_vert++ ) {
  446.  
  447.     sxyz = s[num_vert] ;
  448.     txyz = t[num_vert] ;
  449.  
  450.     /* get power vectors and their derivatives */
  451.     for ( p = 4, sval = tval = 1.0 ; p-- ; ) {
  452.         sp[p] = sval ;
  453.         tp[p] = tval ;
  454.         sval *= sxyz ;
  455.         tval *= txyz ;
  456.  
  457.         if ( p == 3 ) {
  458.         dsp[p] = dtp[p] = 0.0 ;
  459.         dsval = dtval = 1.0 ;
  460.         } else {
  461.         dsp[p] = dsval * (double)(3-p) ;
  462.         dtp[p] = dtval * (double)(3-p) ;
  463.         dsval *= sxyz ;
  464.         dtval *= txyz ;
  465.         }
  466.     }
  467.  
  468.     /* do for x,y,z */
  469.     for ( i = 0 ; i < 3 ; i++ ) {
  470.         /* multiply power vectors times matrix to get value */
  471.         lib_transform_coord( tcoord, sp, mgm[i] ) ;
  472.         vert[num_vert][i] = DOT4( tcoord, tp ) ;
  473.  
  474.         /* get s and t tangent vectors */
  475.         lib_transform_coord( tcoord, dsp, mgm[i] ) ;
  476.         sdir[i] = DOT4( tcoord, tp ) ;
  477.  
  478.         lib_transform_coord( tcoord, sp, mgm[i] ) ;
  479.         tdir[i] = DOT4( tcoord, dtp ) ;
  480.     }
  481.  
  482.     /* find normal */
  483.     CROSS( norm[num_vert], tdir, sdir ) ;
  484.     (void)lib_normalize_vector( norm[num_vert] ) ;
  485.     }
  486. }
  487.  
  488. /* Compute points on each spline surface of teapot by brute force.
  489.  * Forward differencing would be faster, but this is compact & simple.
  490.  */
  491. output_teapot()
  492. {
  493. /* bezier form */
  494. static MATRIX ms = { -1.0,  3.0, -3.0,  1.0,
  495.               3.0, -6.0,  3.0,  0.0,
  496.              -3.0,  3.0,  0.0,  0.0,
  497.               1.0,  0.0,  0.0,  0.0 } ;
  498. int    surf, i, r, c, sstep, tstep, num_tri, num_vert, num_tri_vert ;
  499. double    s[3], t[3] ;
  500. COORD3    vert[4], norm[4] ;
  501. COORD3    obj_color ;
  502. MATRIX    mst, g, mgm[3], tmtx ;
  503.  
  504.     SET_COORD3( obj_color, 1.0, 0.5, 0.1 ) ;
  505.     lib_output_color(NULL, obj_color, 0.0, 0.75, 0.25, 0.25, 5.0, 0.0, 0.0 ) ;
  506.  
  507.     lib_transpose_matrix( mst, ms ) ;
  508.  
  509.     for ( surf = 0 ; surf < NUM_PATCHES ; surf++ ) {
  510.  
  511.     /* get M * G * M matrix for x,y,z */
  512.     for ( i = 0 ; i < 3 ; i++ ) {
  513.         /* get control patches */
  514.         for ( r = 0 ; r < 4 ; r++ ) {
  515.         for ( c = 0 ; c < 4 ; c++ ) {
  516.             g[r][c] = Verts[Patches[surf][r][c]][i] ;
  517.         }
  518.         }
  519.  
  520.         lib_matrix_multiply( tmtx, ms, g ) ;
  521.         lib_matrix_multiply( mgm[i], tmtx, mst ) ;
  522.     }
  523.  
  524.     /* step along, get points, and output */
  525.     for ( sstep = 0 ; sstep < size_factor ; sstep++ ) {
  526.         for ( tstep = 0 ; tstep < size_factor ; tstep++ ) {
  527.         for ( num_tri = 0 ; num_tri < 2 ; num_tri++ ) {
  528.             for ( num_vert = 0 ; num_vert < 3 ; num_vert++ ) {
  529.             num_tri_vert = ( num_vert + num_tri * 2 ) % 4 ;
  530.             /* trickiness: add 1 to sstep if 1 or 2 */
  531.             s[num_vert] = (double)(sstep + (num_tri_vert/2 ? 1:0) )
  532.                     / (double)size_factor ;
  533.             /* trickiness: add 1 to tstep if 2 or 3 */
  534.             t[num_vert] = (double)(tstep + (num_tri_vert%3 ? 1:0) )
  535.                     / (double)size_factor ;
  536.             }
  537.             points_from_basis( 3, s, t, mgm, vert, norm ) ;
  538.             /* don't output degenerate polygons */
  539.             if ( check_for_cusp( 3, vert, norm ) ) {
  540.             lib_output_polypatch( 3, vert, norm ) ;
  541.             PLATFORM_MULTITASK();
  542.             }
  543.         }
  544.         }
  545.     }
  546.     }
  547. }
  548.  
  549. loc_to_square( sstep, tstep, vert )
  550. int    sstep ;
  551. int    tstep ;
  552. COORD3    vert[4] ;
  553. {
  554. int    i ;
  555.  
  556.     for ( i = 0 ; i < 4 ; i++ ) {
  557.     /* vertex 0 & 3 are x.low, 1 & 2 are x.high */
  558.     vert[i][X] = 4.0 * ( 2.0 * (double)(sstep + (i%3 ? 1 : 0) ) /
  559.         (double)size_factor - 1.0 ) ;
  560.  
  561.     /* vertex 0 & 1 are y.low, 2 & 3 are y.high */
  562.     vert[i][Y] = 4.0 * ( 2.0 * (double)(tstep + (i/2 ? 1 : 0) ) /
  563.         (double)size_factor - 1.0 ) ;
  564.  
  565.     vert[i][Z] = 0.0 ;
  566.     }
  567. }
  568.  
  569. output_checkerboard()
  570. {
  571. int    sstep, tstep ;
  572. COORD3    vert[4] ;
  573. COORD3    obj_color ;
  574.  
  575.     SET_COORD3( obj_color, 1.0, 1.0, 1.0 ) ;
  576.     lib_output_color(NULL, obj_color, 0.0, 0.5, 0.5, 0.5, 15.0, 0.0, 0.0 ) ;
  577.     for ( sstep = 0 ; sstep < size_factor ; sstep++ ) {
  578.     for ( tstep = 0 ; tstep < size_factor ; tstep++ ) {
  579.         if ( ( sstep + tstep ) % 2 ) {
  580.         loc_to_square( sstep, tstep, vert ) ;
  581.         lib_output_polygon( 4, vert ) ;
  582.         }
  583.     }
  584.     }
  585.  
  586.     SET_COORD3( obj_color, 0.5, 0.5, 0.5 ) ;
  587.     lib_output_color(NULL, obj_color, 0.0, 0.5, 0.5, 0.5, 15.0, 0.0, 0.0 ) ;
  588.     for ( sstep = 0 ; sstep < size_factor ; sstep++ ) {
  589.     for ( tstep = 0 ; tstep < size_factor ; tstep++ ) {
  590.         if ( !(( sstep + tstep ) % 2) ) {
  591.         loc_to_square( sstep, tstep, vert ) ;
  592.         lib_output_polygon( 4, vert ) ;
  593.         }
  594.     }
  595.     }
  596. }
  597.  
  598.  
  599. int
  600. main(argc,argv)
  601.     int argc;
  602.     char *argv[];
  603. {
  604.     double lscale;
  605.     COORD3 back_color;
  606.     COORD3 from, at, up;
  607.     COORD4 light;
  608.  
  609.     PLATFORM_INIT(SPD_TEAPOT);
  610.  
  611.     /* Start by defining which raytracer we will be using */
  612.     if ( lib_gen_get_opts( argc, argv,
  613.             &size_factor, &raytracer_format, &output_format ) ) {
  614.     return EXIT_FAIL;
  615.     }
  616.     if ( lib_open( raytracer_format, "Teapot.out" ) ) {
  617.     return EXIT_FAIL;
  618.     }
  619.  
  620.     lib_set_polygonalization(3, 3);
  621.     if ( size_factor == 1 ) {
  622.     fprintf(stderr,
  623.       "warning: a size of 1 is not supported - use at your own risk\n" ) ;
  624.     }
  625.  
  626.     /* output background color - UNC sky blue */
  627.     /* NOTE: Do this BEFORE lib_output_viewpoint(), for display_init() */
  628.     SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
  629.     lib_output_background_color( back_color ) ;
  630.  
  631.     /* output viewpoint */
  632.     SET_COORD3( from, 4.86, 7.2, 5.4 ) ;
  633.     SET_COORD3( at, 0.0, 0.0, 0.0 ) ;
  634.     SET_COORD3( up, 0.0, 0.0, 1.0 ) ;
  635.     lib_output_viewpoint( from, at, up, 45.0, 1.0, 1.0, 512, 512 ) ;
  636.  
  637.     /* For raytracers that don't scale the light intensity, we will do
  638.        it for them */
  639.     lscale = (raytracer_format == OUTPUT_NFF ||
  640.           raytracer_format == OUTPUT_RTRACE ? 1.0 : 1.0 / sqrt(2.0));
  641.  
  642.     /* output light sources */
  643.     SET_COORD4( light, -3.1, 9.8, 12.1, lscale ) ;
  644.     lib_output_light( light ) ;
  645.     SET_COORD4( light, 11.3, 5.1, 8.8, lscale ) ;
  646.     lib_output_light( light ) ;
  647.  
  648.     output_checkerboard() ;
  649.     output_teapot() ;
  650.  
  651.     lib_close();
  652.  
  653.     PLATFORM_SHUTDOWN();
  654.     return EXIT_SUCCESS;
  655. }
  656.