home *** CD-ROM | disk | FTP | other *** search
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
- #import "WW3DShape.h"
- #import "RIBPatch.h"
-
- @implementation RIBPatch
-
- + initialize { return [RIBPatch setVersion:1], self; }
-
- - (BOOL)hasBoundingBox { return YES; }
-
- - init
- {
- [super init];
-
- type = NULL;
- return self;
- }
-
-
- - free
- {
- if (type) { free(type); }
- return [super init];
- }
-
- // this is used only internally, for setting a copy without freeing the original
- - _setType:(const char *)newType
- {
- if (newType)
- { type = NXCopyStringBuffer(newType);
- }
- else
- { type = NULL;
- }
- return self;
- }
-
- - copyFromZone:(NXZone *)zone
- {
- id newCopy = [super copyFromZone:zone];
-
- [newCopy _setType:type];
- return newCopy;
- }
-
-
- - setType:(char *)newType
- n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
- printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
- {
- type = NXCopyStringBuffer(newType);
-
- [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
-
- dirtyBoundingBox = TRUE;
-
- return self;
- }
-
- - setType:(char *)newType { if (type) { free(type); } type = NXCopyStringBuffer(newType); return self; }
- - (const char *)type { return type; }
- - (RtBasis *)uBasis { return &uBasis; }
- - (RtToken)uBasisToken { return uBasisToken; }
- - (RtInt)uStep { return uStep; }
- - (RtBasis *)vBasis { return &vBasis; }
- - (RtToken)vBasisToken { return vBasisToken; }
- - (RtInt)vStep { return vStep; }
-
-
- // note that the code in here is largely stolen from WW3DShape's updateBases
- // function. The reason we can't use it directly is because of the need to
- // start (potentially) somewhere in the middle of the list of ribCommands.
- - brokenGetBases
- {
- int ourPosition = -1,
- howManyPositions, i;
- BOOL foundIt;
- id cmd = nil,
- ancestor = [myShape ancestor];
-
-
- howManyPositions = [[myShape ribCommands] count];
- i = 0;
- foundIt = NO;
- while (!foundIt && (i < howManyPositions))
- { if (self == [[myShape ribCommands] objectAt:i])
- { ourPosition = i;
- foundIt = YES;
- }
- else
- { i++;
- }
- }
- if (!foundIt)
- { NXLogError("Yikes! couldn't find myself inside myShape (%s)", [myShape shapeName]);
- return nil;
- }
-
- i = (ourPosition - 1);
- foundIt = NO;
- while (!foundIt && (i > 0))
- { cmd = [[myShape ribCommands] objectAt:i];
- if ([cmd respondsTo:@selector(uBasis)])
- { foundIt = YES;
- }
- else
- { i--;
- }
- }
-
- if (foundIt)
- { N3D_CopyMatrix(*([cmd uBasis]), uBasis);
- uStep = [cmd uStep];
- N3D_CopyMatrix(*([cmd vBasis]), vBasis);
- vStep = [cmd vStep];
- }
- else
- { if (ancestor) // get it from our ancestor
- { N3D_CopyMatrix(*([ancestor uBasis]), uBasis);
- uStep = [ancestor uStep];
- N3D_CopyMatrix(*([ancestor vBasis]), vBasis);
- vStep = [ancestor vStep];
- }
- else // the shape we are in is the root; fill in bezier bases for both u and v
- { N3D_CopyMatrix(RiBezierBasis, uBasis);
- uStep = 3;
- N3D_CopyMatrix(RiBezierBasis, vBasis);
- vStep = 3;
- }
- }
-
-
- return self;
- }
-
-
- - getBases
- {
- //WAVE - fix ME!!! boge for now
- N3D_CopyMatrix(RiBezierBasis, uBasis);
- uStep = 3;
- N3D_CopyMatrix(RiBezierBasis, vBasis);
- vStep = 3;
-
- return self;
- }
-
-
- - calculateBoundingBoxStartingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- if (![self getBases])
- { return nil;
- }
-
- // if both are bezier, just call our super's routine, since we
- // can just check against the points.
-
- // ya know, we might want to have a string tag along with the bases,
- // just so we don't have to deal with this epsilon bullshit...
-
- if ( (uBasisToken && vBasisToken)
- && ( ((!strcmp(uBasisToken, RI_BEZIER)) && (!strcmp(vBasisToken, RI_BEZIER)))
- || ((!strcmp(uBasisToken, RI_BSPLINE)) && (!strcmp(vBasisToken, RI_BSPLINE)))
- || ((!strcmp(uBasisToken, RI_BEZIER)) && (!strcmp(vBasisToken, RI_BSPLINE)))
- || ((!strcmp(uBasisToken, RI_BSPLINE)) && (!strcmp(vBasisToken, RI_BEZIER)))))
- {
- [super calculateBoundingBoxStartingAt:shutterOpenTime endingAt:shutterCloseTime];
- dirtyBoundingBox = FALSE;
- return self;
- }
-
- // otherwise, need to transform one or both...
- // for now, we'll still bail, and just call the super version...
- [super calculateBoundingBoxStartingAt:shutterOpenTime endingAt:shutterCloseTime];
- dirtyBoundingBox = FALSE;
-
- return self;
- }
-
-
- - (BOOL)theSameAs:otherRIBCommand
- {
- if ([self class] != [otherRIBCommand class])
- { return NO;
- }
- if (type != [(RIBPatch *)otherRIBCommand type]) // if they're tokens, they're the same string pointer
- { if (strcmp(type, [(RIBPatch *)otherRIBCommand type])) // just make sure by comparing the actual strings....
- { return NO; // okay, they really are different
- }
- }
-
- // this will check all the parameters...
- return [super theSameAs:otherRIBCommand];
- }
-
-
- - (BOOL)similarTo:otherRIBCommand
- {
- if ([self class] != [otherRIBCommand class])
- { return NO;
- }
- if (type != [(RIBPatch *)otherRIBCommand type]) // if they're tokens, they're the same string pointer
- { if (strcmp(type, [(RIBPatch *)otherRIBCommand type])) // just make sure by comparing the actual strings....
- { return NO; // okay, they really are different
- }
- }
- return YES;
- }
-
-
- - renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- RiPatchV(type, n, tokens, parms);
-
- return self;
- }
-
- - (BOOL)isMotionBlurrable { return YES; }
-
- - writeEve:(NXStream *)stream atTabLevel:(int)tab
- {
- int i;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "Patch %s ", type);
- [super writeParameterList:stream];
- return self;
- }
-
- #define typeVector "*"
- #define typeValues &type
-
- - read:(NXTypedStream*)stream
- {
- int version;
- [super read:stream];
-
- version = NXTypedStreamClassVersion(stream,"RIBPatch");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1)
- { NXReadTypes(stream,typeVector,typeValues);
- }
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
-
- NXWriteTypes(stream,typeVector, typeValues);
-
- return self;
- }
-
-
- @end
-