home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WW3DKit / RIBTorus.m < prev    next >
Encoding:
Text File  |  1995-05-13  |  12.1 KB  |  401 lines

  1. // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
  2. // see COPYRIGHT for reuse legalities
  3. //
  4.  
  5. #import "RIBTorus.h"
  6. #import <stdio.h>
  7.  
  8.  
  9. @implementation RIBTorus
  10.  
  11. + initialize { return [RIBTorus setVersion:1], self; }
  12.  
  13. - (BOOL)hasBoundingBox { return YES; }
  14.  
  15. - init
  16. {
  17.   [super init];
  18.  
  19.   majorRadius = 1.0;
  20.   minorRadius = 0.5;
  21.   phiMin = 0.0;
  22.   phiMax =  360.0;
  23.   
  24.   return self;
  25. }
  26.  
  27. - setMajorRadius:(RtFloat)newMajorRadius minorRadius:(RtFloat)newMinorRadius
  28.      phiMin:(RtFloat)newPhiMin phiMax:(RtFloat)newPhiMax
  29.      thetaMax:(RtFloat)newThetaMax 
  30.      n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
  31.      printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
  32. {  
  33.    majorRadius = newMajorRadius;
  34.    minorRadius = newMinorRadius;
  35.    phiMin = newPhiMin;
  36.    phiMax = newPhiMax;
  37.    thetaMax = newThetaMax;
  38.    [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
  39.  
  40.    dirtyBoundingBox = TRUE;
  41.   
  42.    return self;
  43. }
  44.  
  45. - setMajorRadius:(RtFloat)newMajorRadius { majorRadius = newMajorRadius; dirtyBoundingBox = TRUE; return self; }
  46. - setMinorRadius:(RtFloat)newMinorRadius { minorRadius = newMinorRadius; dirtyBoundingBox = TRUE; return self; }
  47. - setPhiMin:(RtFloat)newPhiMin { phiMin = newPhiMin; dirtyBoundingBox = TRUE; return self; }
  48. - setPhiMax:(RtFloat)newPhiMax { phiMax = newPhiMax; dirtyBoundingBox = TRUE; return self; }
  49.  
  50. - (RtFloat)majorRadius { return majorRadius; } 
  51. - (RtFloat)minorRadius { return minorRadius; } 
  52. - (RtFloat)phiMin { return phiMin; }
  53. - (RtFloat)phiMax { return phiMax; }
  54.  
  55. - (BOOL)hasboundingBox { return YES; }
  56.  
  57. - calculateBoundingBoxStartingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
  58. {
  59.   // WAVE: FILL ME IN CORRECTLY!!!
  60.   boundingBox[0] =  -1.0 *  (majorRadius + minorRadius);
  61.   boundingBox[1] = majorRadius + minorRadius;
  62.  
  63.   if (thetaMax >= 270.0)
  64.   {  boundingBox[2] =  -1.0 *  (majorRadius + minorRadius);
  65.      boundingBox[3] = majorRadius + minorRadius;
  66.   }
  67.   else
  68.   {  if (thetaMax >= 180.0)
  69.      {  boundingBox[2] = (majorRadius + minorRadius) * sin((double)(toRadians((thetaMax))));
  70.         boundingBox[3] = (majorRadius + minorRadius);
  71.      }
  72.      else
  73.      {  if (thetaMax >= 90.0)
  74.         {  boundingBox[2] = 0.0;
  75.            boundingBox[3] = (majorRadius + minorRadius);
  76.         }
  77.         else
  78.         {  boundingBox[2] = 0.0;
  79.            boundingBox[3] = (majorRadius + minorRadius) * sin((double)(toRadians((thetaMax))));
  80.         }
  81.      }
  82.   }
  83.  
  84.   boundingBox[4] = -1.0 * minorRadius;
  85.   boundingBox[5] = minorRadius;
  86.   dirtyBoundingBox = FALSE; 
  87.  
  88.   return self;
  89. }
  90.  
  91. - renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
  92. {
  93.   RiTorusV(majorRadius, minorRadius, phiMin, phiMax, thetaMax, n, tokens, parms);
  94.  
  95.   return self;
  96. }
  97.  
  98. - (BOOL)theSameAs:otherRIBCommand
  99. {
  100.   if (minorRadius != [otherRIBCommand minorRadius])
  101.   {  return NO;
  102.   }
  103.   if (majorRadius != [otherRIBCommand majorRadius])
  104.   {  return NO;
  105.   }
  106.   if (phiMin != [otherRIBCommand phiMin])
  107.   {  return NO;
  108.   }
  109.   if (phiMax != [otherRIBCommand phiMax])
  110.   {  return NO;
  111.   }
  112.  
  113.   return [super theSameAs:otherRIBCommand];
  114. }
  115.  
  116. - (BOOL)isLerpable { return YES; }
  117.  
  118. // note: because we've made the WWSampleList "safe" for having
  119. // multiple samples with the same data, it's perfectly valid to return
  120. // yourself or b
  121. - lerpWith:b by:(float)uValue
  122. {
  123.    id      newMe = nil;
  124.    RtFloat minorRadiusA, majorRadiusA, phiMinA, phiMaxA, thetaMaxA;
  125.    RtFloat minorRadiusB, majorRadiusB, phiMinB, phiMaxB, thetaMaxB;
  126.  
  127.  
  128.    if (([self class] != [b class]) || (uValue <= 0.0))
  129.    {  return self;
  130.    }
  131.  
  132.    if (uValue >= 1.0)
  133.    {  return b;
  134.    }
  135.  
  136.    newMe = [super lerpWith:b by:uValue]; // this makes a copy for us
  137.  
  138.    // okay, now do the specific stuff for this class
  139.    minorRadiusA = [self minorRadius];
  140.    minorRadiusB = [b minorRadius];
  141.    [newMe setMinorRadius:(minorRadiusA + ((minorRadiusB - minorRadiusA) * uValue))]; 
  142.    majorRadiusA = [self majorRadius];
  143.    majorRadiusB = [b majorRadius];
  144.    [newMe setMajorRadius:(majorRadiusA + ((majorRadiusB - majorRadiusA) * uValue))]; 
  145.    phiMinA = [self phiMin];
  146.    phiMinB = [b phiMin];
  147.    [newMe setPhiMin:(phiMinA + ((phiMinB - phiMinA) * uValue))];
  148.    phiMaxA = [self phiMax];
  149.    phiMaxB = [b phiMax];
  150.    [newMe setPhiMax:(phiMaxA + ((phiMaxB - phiMaxA) * uValue))];
  151.    thetaMaxA = [self thetaMax];
  152.    thetaMaxB = [b thetaMax];
  153.    [newMe setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
  154.  
  155.    return newMe;
  156. }
  157.  
  158.  
  159. - lerpSelfWith:b by:(float)uValue
  160. {
  161.    RtFloat minorRadiusA, majorRadiusA, phiMinA, phiMaxA, thetaMaxA;
  162.    RtFloat minorRadiusB, majorRadiusB, phiMinB, phiMaxB, thetaMaxB;
  163.  
  164.  
  165.    if (([self class] != [b class]) || (uValue <= 0.0))
  166.    {  return self;
  167.    }
  168.  
  169.    if (uValue >= 1.0)
  170.    {  return b;
  171.    }
  172.  
  173.    [super lerpSelfWith:b by:uValue]; // this makes a copy for us
  174.  
  175.    // okay, now do the specific stuff for this class
  176.    minorRadiusA = [self minorRadius];
  177.    minorRadiusB = [b minorRadius];
  178.    [self setMinorRadius:(minorRadiusA + ((minorRadiusB - minorRadiusA) * uValue))]; 
  179.    majorRadiusA = [self majorRadius];
  180.    majorRadiusB = [b majorRadius];
  181.    [self setMajorRadius:(majorRadiusA + ((majorRadiusB - majorRadiusA) * uValue))]; 
  182.    phiMinA = [self phiMin];
  183.    phiMinB = [b phiMin];
  184.    [self setPhiMin:(phiMinA + ((phiMinB - phiMinA) * uValue))];
  185.    phiMaxA = [self phiMax];
  186.    phiMaxB = [b phiMax];
  187.    [self setPhiMax:(phiMaxA + ((phiMaxB - phiMaxA) * uValue))];
  188.    thetaMaxA = [self thetaMax];
  189.    thetaMaxB = [b thetaMax];
  190.    [self setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
  191.  
  192.    return self;
  193. }
  194.  
  195. - writeEve:(NXStream *)stream atTabLevel:(int)tab
  196. {
  197.    int  i;
  198.  
  199.  
  200.    for (i = 0; i < tab; i++)
  201.    {  NXPrintf(stream, "\t");
  202.    }
  203.    NXPrintf(stream, "Torus %f %f %f %f %f", majorRadius, minorRadius, phiMin, phiMax, thetaMax);
  204.    [super writeParameterList:stream];
  205.    return self;
  206. }
  207.  
  208. - writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
  209. {
  210.    RtFloat umax;
  211.    RtFloat uknots[12];
  212.    RtFloat vmin, vmax;
  213.    RtFloat vknots[12];
  214.    RtFloat knots[12] = { 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1.0, 1.0, 1.0};
  215.    RtFloat uspline[9][4] = { {1.0, 0.0, 1.0, 1.0},
  216.                  {M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  217.                  {0.0, 1.0, 1.0, 1.0},
  218.                  {-M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  219.                  {-1.0, 0.0, 1.0, 1.0},
  220.                  {-M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  221.                  {0.0, -1.0, 1.0, 1.0},
  222.                  {M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2},
  223.                  {1.0, 0.0, 1.0, 1.0}};
  224.    RtFloat vspline[9][4];
  225.    int i, j, k;
  226.  
  227.  
  228.    umax = [self thetaMax] / 360.0;
  229.    vmin = [self phiMin] / 360.0;
  230.    vmax = [self phiMax] / 360.0;
  231.    for (i=0; i<12; i++)
  232.    {  uknots[i] = knots[i] / umax;
  233.       vknots[i] = (knots[i] - vmin) / (vmax - vmin);
  234.    }
  235.  
  236.    vspline[0][0] = [self majorRadius] - [self minorRadius];
  237.    vspline[0][1] = [self majorRadius] - [self minorRadius];
  238.    vspline[0][2] = 0.0;
  239.    vspline[0][3] = 1.0;
  240.    vspline[1][0] = ([self majorRadius] - [self minorRadius]) * M_SQRT1_2;
  241.    vspline[1][1] = ([self majorRadius] - [self minorRadius]) * M_SQRT1_2;
  242.    vspline[1][2] = -[self minorRadius] * M_SQRT1_2;
  243.    vspline[1][3] = M_SQRT1_2;
  244.    vspline[2][0] = [self majorRadius];
  245.    vspline[2][1] = [self majorRadius];
  246.    vspline[2][2] = -[self minorRadius];
  247.    vspline[2][3] = 1.0;
  248.    vspline[3][0] = ([self majorRadius] + [self minorRadius]) * M_SQRT1_2;
  249.    vspline[3][1] = ([self majorRadius] + [self minorRadius]) * M_SQRT1_2;
  250.    vspline[3][2] = -[self minorRadius] * M_SQRT1_2;
  251.    vspline[3][3] = M_SQRT1_2;
  252.    vspline[4][0] = [self majorRadius] + [self minorRadius];
  253.    vspline[4][1] = [self majorRadius] + [self minorRadius];
  254.    vspline[4][2] = 0.0;
  255.    vspline[4][3] = 1.0;
  256.    vspline[5][0] = ([self majorRadius] + [self minorRadius]) * M_SQRT1_2;
  257.    vspline[5][1] = ([self majorRadius] + [self minorRadius]) * M_SQRT1_2;
  258.    vspline[5][2] = [self minorRadius] * M_SQRT1_2;
  259.    vspline[5][3] = M_SQRT1_2;
  260.    vspline[6][0] = [self majorRadius];
  261.    vspline[6][1] = [self majorRadius];
  262.    vspline[6][2] = [self minorRadius];
  263.    vspline[6][3] = 1.0;
  264.    vspline[7][0] = ([self majorRadius] - [self minorRadius]) * M_SQRT1_2;
  265.    vspline[7][1] = ([self majorRadius] - [self minorRadius]) * M_SQRT1_2;
  266.    vspline[7][2] = [self minorRadius] * M_SQRT1_2;
  267.    vspline[7][3] = M_SQRT1_2;
  268.    vspline[8][0] = [self majorRadius] - [self minorRadius];
  269.    vspline[8][1] = [self majorRadius] - [self minorRadius];
  270.    vspline[8][2] = 0.0;
  271.    vspline[8][3] = 1.0;
  272.  
  273.    for (i = 0; i < tab; i++)
  274.    {  NXPrintf(stream, "\t");
  275.    }
  276.    NXPrintf(stream, "# ");
  277.    [self writeEve:stream atTabLevel:0];
  278.    NXPrintf(stream, "\n");
  279.  
  280.    for (i = 0; i < tab; i++)
  281.    {  NXPrintf(stream, "\t");
  282.    }
  283.    NXPrintf(stream, "# since Inventor doesn't directly support quadrics in any terribly useful way (sigh), we turn it into a NURBS surface:\n");
  284.  
  285.    for (i = 0; i < tab; i++)
  286.    {  NXPrintf(stream, "\t");
  287.    }
  288.    NXPrintf(stream, "Separator {\n");
  289.  
  290.    for (i = 0; i < (tab+1); i++)  {  NXPrintf(stream, "\t"); }
  291.    NXPrintf(stream, "Complexity {\n");
  292.    for (i = 0; i < (tab+2); i++) {  NXPrintf(stream, "\t"); }
  293.    NXPrintf(stream, "value 1.0\n");
  294.    for (i = 0; i < (tab+1); i++) {  NXPrintf(stream, "\t"); }
  295.    NXPrintf(stream, "}\n");
  296.  
  297.    for (i = 0; i < (tab+1); i++)  {  NXPrintf(stream, "\t"); }
  298.    NXPrintf(stream, "Coordinate4 {\n");
  299.    for (i = 0; i < (tab+2); i++) {  NXPrintf(stream, "\t"); }
  300.    NXPrintf(stream, "point [");
  301.  
  302.    for (i=0; i<8; i++)
  303.    {  for (j=0; j<9; j++)
  304.       {  if (!i && !j)
  305.          {  NXPrintf(stream, 
  306.              "%f %f %f %f,\n", 
  307.              (uspline[j][0] * vspline[i][0]),
  308.              (uspline[j][1] * vspline[i][1]),
  309.              (uspline[j][2] * vspline[i][2]),
  310.              (uspline[j][3] * vspline[i][3]));
  311.       }
  312.          else
  313.          {  NXPrintf(stream, 
  314.              "       %f %f %f %f,\n", 
  315.              (uspline[j][0] * vspline[i][0]),
  316.              (uspline[j][1] * vspline[i][1]),
  317.              (uspline[j][2] * vspline[i][2]),
  318.              (uspline[j][3] * vspline[i][3]));
  319.       }
  320.          for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  321.       }
  322.    }
  323.    for (j=0; j<8; j++)
  324.    {  NXPrintf(stream, 
  325.                "       %f %f %f %f,\n", 
  326.                (uspline[j][0] * vspline[i][0]),
  327.                (uspline[j][1] * vspline[i][1]),
  328.                (uspline[j][2] * vspline[i][2]),
  329.                (uspline[j][3] * vspline[i][3]));
  330.      for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  331.    }
  332.    NXPrintf(stream, 
  333.         "       %f %f %f %f]\n", 
  334.         (uspline[j][0] * vspline[i][0]),
  335.         (uspline[j][1] * vspline[i][1]),
  336.         (uspline[j][2] * vspline[i][2]),
  337.         (uspline[j][3] * vspline[i][3]));
  338.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  339.    NXPrintf(stream, "}\n");
  340.  
  341.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  342.    NXPrintf(stream, "NurbsSurface {\n");
  343.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  344.    NXPrintf(stream, "numUControlPoints 9\n");
  345.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  346.    NXPrintf(stream, "numVControlPoints 2\n");
  347.  
  348.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  349.    NXPrintf(stream, "uKnotVector [");
  350.    for (i=0; i<11; i++)
  351.    {    NXPrintf(stream, "%f, ", uknots[i]);
  352.    }
  353.    NXPrintf(stream, "%f]\n", uknots[i]);
  354.  
  355.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  356.    NXPrintf(stream, "vKnotVector [");
  357.    for (i=0; i<3; i++)
  358.    {    NXPrintf(stream, "%f, ", vknots[i]);
  359.    }
  360.    NXPrintf(stream, "%f]\n", vknots[i]);
  361.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  362.    NXPrintf(stream, "}\n");
  363.    for (k = 0; k < tab; k++) {  NXPrintf(stream, "\t"); }
  364.    NXPrintf(stream, "}\n");
  365.  
  366.    return self;
  367. }
  368.  
  369.  
  370. #define typeVector "ffff"
  371. #define typeValues &majorRadius, &minorRadius, &phiMin, &phiMax
  372.  
  373. - read:(NXTypedStream *)stream 
  374. {
  375.     int version;
  376.     [super read:stream];
  377.  
  378.     version = NXTypedStreamClassVersion(stream,"RIBTorus");
  379.     if (version == 0) NXReadTypes(stream,"i",&version), version=1;
  380.     if (version == 1)
  381.     {  NXReadTypes(stream,typeVector,typeValues);
  382.     } 
  383.     else 
  384.     {
  385.     }
  386.     return self;
  387. }
  388.  
  389. - write:(NXTypedStream *)stream 
  390. {
  391.     [super write:stream];
  392.  
  393.     NXWriteTypes(stream,typeVector, typeValues);
  394.  
  395.     return self;
  396. }
  397.  
  398.  
  399.  
  400. @end
  401.