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

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