home *** CD-ROM | disk | FTP | other *** search
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
- #import "RIBHyperboloid.h"
- #import <stdio.h>
-
-
- @implementation RIBHyperboloid
-
-
- + initialize { return [RIBHyperboloid setVersion:1], self; }
-
- - (BOOL)hasBoundingBox { return YES; }
-
- - init
- {
- [super init];
-
- point1[0] = 0.0;
- point1[1] = 0.0;
- point1[2] = 0.0;
- point2[0] = 0.5;
- point2[1] = 0.0;
- point2[2] = 0.0;
-
- return self;
- }
-
-
- - setPoint1:(RtPoint)newPoint1 point2:(RtPoint)newPoint2
- thetaMax:(RtFloat)newThetaMax
- n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
- printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
- {
- point1[0] = newPoint1[0];
- point1[1] = newPoint1[1];
- point1[2] = newPoint1[2];
-
- point2[0] = newPoint2[0];
- point2[1] = newPoint2[1];
- point2[2] = newPoint2[2];
-
- thetaMax = newThetaMax;
-
- [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
-
- dirtyBoundingBox = TRUE;
-
- return self;
- }
-
- - setPoint1:(RtPoint)newPoint1
- {
- point1[0] = newPoint1[0];
- point1[1] = newPoint1[1];
- point1[2] = newPoint1[2];
-
- dirtyBoundingBox = TRUE;
-
- return self;
- }
-
- - setPoint2:(RtPoint)newPoint2
- {
- point2[0] = newPoint2[0];
- point2[1] = newPoint2[1];
- point2[2] = newPoint2[2];
-
- dirtyBoundingBox = TRUE;
-
- return self;
- }
-
- - (RtPoint *)point1 { return &point1; }
- - (RtPoint *)point2 { return &point2; }
-
-
- #define wwMax(a,b) (((a)>(b))?(a):(b))
- #define wwMin(a,b) (((a)>(b))?(b):(a))
-
- - calculateBoundingBoxStartingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- boundingBox[0] = wwMin(point1[0], point2[0]);
- boundingBox[1] = wwMax(point1[0], point2[0]);
-
- boundingBox[2] = wwMin(point1[1], point2[1]);
- boundingBox[3] = wwMax(point1[1], point2[1]);
-
- boundingBox[4] = wwMin(point1[2], point2[2]);
- boundingBox[5] = wwMax(point1[2], point2[2]);
- dirtyBoundingBox = FALSE;
-
- return self;
- }
-
- - (BOOL)isMoot
- {
- if ((point1[0] == point2[0]) && (point1[1] == point2[1]) && (point1[2] == point2[2]))
- { return YES;
- }
- return [super isMoot];
- }
-
- - (BOOL)theSameAs:otherRIBCommand
- {
- RtPoint *otherPt1Ptr, *otherPt2Ptr;
-
-
- otherPt1Ptr = [otherRIBCommand point1];
- if (point1[0] != *otherPt1Ptr[0])
- { return NO;
- }
- if (point1[1] != *otherPt1Ptr[1])
- { return NO;
- }
- if (point1[2] != *otherPt1Ptr[2])
- { return NO;
- }
-
- otherPt2Ptr = [otherRIBCommand point2];
- if (point2[0] != *otherPt2Ptr[0])
- { return NO;
- }
- if (point2[1] != *otherPt2Ptr[1])
- { return NO;
- }
- if (point2[2] != *otherPt2Ptr[2])
- { return NO;
- }
-
- return [super theSameAs:otherRIBCommand];
- }
-
- - renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- RiHyperboloidV(point1, point2, thetaMax, n, tokens, parms);
-
- return self;
- }
-
- - (unsigned long int)maxSampleBandwidth { return ([super maxSampleBandwidth] + (unsigned long int)((3 + 3 + 1) * sizeof(RtFloat))); }
-
- - (BOOL)isLerpable { return YES; }
-
- // note: because we've made the WWSampleList "safe" for having
- // multiple samples with the same data, it's perfectly valid to return
- // yourself or b
- - lerpWith:b by:(float)uValue
- {
- id newMe = nil;
- RtFloat thetaMaxA, thetaMaxB;
- RtPoint *point1A, *point2A, newPoint;
- RtPoint *point1B, *point2B;
-
-
- if (([self class] != [b class]) || (uValue <= 0.0))
- { return self;
- }
-
- if (uValue >= 1.0)
- { return b;
- }
-
- newMe = [super lerpWith:b by:uValue]; // this makes a copy for us
-
- // okay, now do the specific stuff for this class
- point1A = [self point1];
- point1B = [b point1];
- newPoint[0] = (*point1A)[0] + (((*point1B)[0] - (*point1A)[0]) * uValue);
- newPoint[1] = (*point1A)[1] + (((*point1B)[1] - (*point1A)[1]) * uValue);
- newPoint[2] = (*point1A)[2] + (((*point1B)[2] - (*point1A)[2]) * uValue);
- [newMe setPoint1:newPoint];
-
- point2A = [self point2];
- point2B = [b point2];
- newPoint[0] = (*point2A)[0] + (((*point2B)[0] - (*point2A)[0]) * uValue);
- newPoint[1] = (*point2A)[1] + (((*point2B)[1] - (*point2A)[1]) * uValue);
- newPoint[2] = (*point2A)[2] + (((*point2B)[2] - (*point2A)[2]) * uValue);
- [newMe setPoint2:newPoint];
-
- thetaMaxA = [self thetaMax];
- thetaMaxB = [b thetaMax];
- [newMe setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
-
- return newMe;
- }
-
-
- - lerpSelfWith:b by:(float)uValue
- {
- RtFloat thetaMaxA, thetaMaxB;
- RtPoint *point1A, *point2A, newPoint;
- RtPoint *point1B, *point2B;
-
-
- if (([self class] != [b class]) || (uValue <= 0.0))
- { return self;
- }
-
- if (uValue >= 1.0)
- { return b;
- }
-
- [super lerpSelfWith:b by:uValue]; // this makes a copy for us
-
- // okay, now do the specific stuff for this class
- point1A = [self point1];
- point1B = [b point1];
- newPoint[0] = (*point1A)[0] + (((*point1B)[0] - (*point1A)[0]) * uValue);
- newPoint[1] = (*point1A)[1] + (((*point1B)[1] - (*point1A)[1]) * uValue);
- newPoint[2] = (*point1A)[2] + (((*point1B)[2] - (*point1A)[2]) * uValue);
- [self setPoint1:newPoint];
-
- point2A = [self point2];
- point2B = [b point2];
- newPoint[0] = (*point2A)[0] + (((*point2B)[0] - (*point2A)[0]) * uValue);
- newPoint[1] = (*point2A)[1] + (((*point2B)[1] - (*point2A)[1]) * uValue);
- newPoint[2] = (*point2A)[2] + (((*point2B)[2] - (*point2A)[2]) * uValue);
- [self setPoint2:newPoint];
-
- thetaMaxA = [self thetaMax];
- thetaMaxB = [b thetaMax];
- [self setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
-
- return self;
- }
-
- - writeEve:(NXStream *)stream atTabLevel:(int)tab
- {
- int i;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "Hyperboloid %f %f %f %f %f %f %f ", point1[0], point1[1], point1[2], point2[0], point2[1], point2[2], thetaMax);
- [super writeParameterList:stream];
- return self;
- }
-
- - writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
- {
- RtFloat umax;
- RtFloat uknots[12];
- 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};
- RtFloat vknots[4] = {0.0, 0.0, 1.0, 1.0};
- RtFloat xuspline[9][2] = {{1.0, 0.0}, {M_SQRT1_2, -M_SQRT1_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}, {M_SQRT1_2, M_SQRT1_2}, {1.0, 0.0}};
- 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},
- {-M_SQRT1_2, -M_SQRT1_2}, {-1.0, 0.0}, {-M_SQRT1_2, M_SQRT1_2}, {0.0, 1.0}};
- 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};
- int i, j, k;
-
-
- umax = [self thetaMax] / 360.0;
- for (i=0; i<12; i++)
- { uknots[i] = uk[i] / umax;
- }
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "# ");
- [self writeEve:stream atTabLevel:0];
- NXPrintf(stream, "\n");
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "# since Inventor doesn't directly support quadrics in any terribly useful way (sigh), we turn it into a NURBS surface:\n");
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "Separator {\n");
-
- for (i = 0; i < (tab+1); i++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "Coordinate4 {\n");
- for (i = 0; i < (tab+2); i++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "point [");
-
- for (j=0; j<9; j++)
- { if (!j)
- { NXPrintf(stream,
- "%f %f %f %f,\n",
- (point1[0] * xuspline[j][0] + point1[1] * xuspline[j][1]),
- (point1[0] * yuspline[j][0] + point1[1] * yuspline[j][1]),
- (point1[2] * zwuspline[j]),
- (zwuspline[j]));
- }
- else
- { NXPrintf(stream,
- " %f %f %f %f,\n",
- (point1[0] * xuspline[j][0] + point1[1] * xuspline[j][1]),
- (point1[0] * yuspline[j][0] + point1[1] * yuspline[j][1]),
- (point1[2] * zwuspline[j]),
- (zwuspline[j]));
- }
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- }
-
- for (j=0; j<8; j++)
- { NXPrintf(stream,
- " %f %f %f %f,\n",
- (point2[0] * xuspline[j][0] + point2[1] * xuspline[j][1]),
- (point2[0] * yuspline[j][0] + point2[1] * yuspline[j][1]),
- (point2[2] * zwuspline[j]),
- (zwuspline[j]));
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- }
- NXPrintf(stream,
- " %f %f %f %f]\n",
- (point2[0] * xuspline[j][0] + point2[1] * xuspline[j][1]),
- (point2[0] * yuspline[j][0] + point2[1] * yuspline[j][1]),
- (point2[2] * zwuspline[j]),
- (zwuspline[j]));
-
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n");
-
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "NurbsSurface {\n");
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "numUControlPoints 9\n");
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "numVControlPoints 2\n");
-
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "uKnotVector [");
- for (i=0; i<11; i++)
- { NXPrintf(stream, "%f, ", uknots[i]);
- }
- NXPrintf(stream, "%f]\n", uknots[i]);
-
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "vKnotVector [");
- for (i=0; i<3; i++)
- { NXPrintf(stream, "%f, ", vknots[i]);
- }
- NXPrintf(stream, "%f]\n", vknots[i]);
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n");
- for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n");
-
- return self;
- }
-
-
- - read:(NXTypedStream*)stream
- {
- int version;
- [super read:stream];
-
- version = NXTypedStreamClassVersion(stream,"RIBHyperboloid");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1) {
- NXReadArray(stream, "f", 3, point1);
- NXReadArray(stream, "f", 3, point2);
- } else {
- }
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
- NXWriteArray(stream, "f", 3, point1);
- NXWriteArray(stream, "f", 3, point2);
- return self;
- }
-
-
- @end
-