This is WireFrame.m in view mode; [Download] [Up]
#import "WireFrame.h" @implementation WireFrame:Object // this code is copyright Darcy Brockbank, 1993 // // You may freely reuse and distribute this code in any way shape or // form, provided that this notice stays intact. // // darcy@solutions.ca, samurai@cs.mcgill.ca // // StefView was implemented out of WorldSpaceView and retains some of the // movement properties... // // The code for WorldSpaceView was written by Sam Streeper at NeXT, I think, // and there were two other contributors, but I can't find their names in the // source for it. // // NeXTView shows a simple (ha!) spinning NeXTcube logo, in full 3D. The 3D code // came from an app I wrote a long time ago called "WireFrame", and so the code // is pretty scary. As well, this thing is only a quick hack, though a nice one. // // This thing has room for improvement, and if you do so, send me a copy! // // - darcy #define SCALE 1.0045 - getCentre:(float*) x:(float *)y :(float *)z { *x=myCentre.x; *y=myCentre.y; *z=myCentre.z; return self; } - getFrameColour:(float *)r :(float *)g :(float *)b { *r=myFrameColour.red; *b=myFrameColour.blue; *g=myFrameColour.green; return self; } - getTagColour:(float *)r :(float *)g :(float *)b { *r=myTagColour.red; *b=myTagColour.blue; *g=myTagColour.green; return self; } int count(const char *s,char thisChar) { int c=0; for (;*s!=(char)0;s++) if (*s==thisChar) c++; return (c); } #define LIM 6400000.0 - init { [super init]; myLineWidth=0.1; psint=sin(0.085); nsint=-psint; cost=cos(0.085); bbox[0]=-LIM; bbox[1]=-LIM; bbox[2]=2*LIM; bbox[3]=2*LIM; myTable = [[NXStringTable alloc] init]; dimension=4; return self; } - free { [myTable free]; return [super free]; } - addMyPS:(char)command { myPSCommands[numberOfMyPS++]=command; return self; } - addPoint:(float)x :(float)y :(float)z { myCoords[numberOfCoords*4]=x; myCoords[numberOfCoords*4+1]=y; myCoords[numberOfCoords*4+2]=z; myCoords[numberOfCoords*4+3]=1.0; numberOfCoords++; return self; } - moveTo:(float)x:(float)y:(float)z { int i; for(i=0;i<numberOfCoords*dimension;i+=dimension){ myCoords[i]+=(x-myCentre.x); myCoords[i+1]+=(y-myCentre.y); myCoords[i+2]+=(z-myCentre.z); } for(i=0;i<numberOfTags*coordsInATag*dimension;i+=dimension){ myTags[i]+=(x-myCentre.x); myTags[i+1]+=(y-myCentre.y); myTags[i+2]+=(z-myCentre.z); } myCentre.x=x; myCentre.y=y; myCentre.z=z; return self; } - drawYourself:(float)zoom centeredOn:(float)X :(float)Y; { int i,j,x; int stop,start; BOOL behindMe; DPSUserPathAction op; behindMe=NO; stop=numberOfCoords*dimension; for (i=0,j=0;i<stop;j+=2,i+=dimension){ if (myCoords[i+2]>=-0.001) { behindMe=YES; break; } output[j]=((myCoords[i])*(-zoom/myCoords[i+2]))+X; output[j+1]=((myCoords[i+1])*(-zoom/myCoords[i+2]))+Y; } if (!behindMe && stop!=0 && numberOfCoords>0){ PSsetrgbcolor(myFrameColour.red,myFrameColour.green,myFrameColour.blue); DPSDoUserPath(output,2*numberOfCoords,dps_float,myPSCommands, numberOfMyPS,bbox,dps_ustroke); } if (numberOfTags){ op=dps_ufill; for(x=0;x<numberOfTags;x++){ behindMe=NO; start=x*coordsInATag*dimension; if (!(myTags[2+start]>=myCentre.z)) { // closer than centre op = dps_ustroke; } stop=start+(coordsInATag*dimension); for(j=0,i=start;i<stop;j+=2,i+=dimension){ if (myTags[i+2]>=0){ behindMe=YES; break; } output[j]=((myTags[i])*(-zoom/myTags[i+2]))+X; output[j+1]=((myTags[i+1])*(-zoom/myTags[i+2]))+Y; } if (!behindMe && coordsInATag > 0){ PSsetrgbcolor(myTagColour.red,myTagColour.green,myTagColour.blue) ; DPSDoUserPath(output,(2*coordsInATag),dps_float,myTagPSCommands, numberOfTagPS,bbox,op); } } } return self; } - rotate: (Direction) direction aroundAxis:(Axis) thisAxis atOrigin:(Origin) thisOrigin { double mysint; double s1,s2,s3; Origin origin; int i; if (direction==negative) { mysint=nsint; } else { mysint=psint; } origin=thisOrigin; switch(thisAxis){ case x: for (i=0;i<numberOfCoords*dimension;i+=dimension){ s2=myCoords[i+1]-origin.y; s3=myCoords[i+2]-origin.z; myCoords[i+1]=(float)((s2)*cost-(s3)*mysint)+origin.y; myCoords[i+2]=(float)((s2)*mysint+(s3)*cost)+origin.z; } for (i=0; i<(numberOfTags*coordsInATag)*dimension; i+=dimension){ s2=myTags[i+1]-origin.y; s3=myTags[i+2]-origin.z; myTags[i+1]=(float)((s2)*cost-(s3)*mysint)+origin.y; myTags[i+2]=(float)((s2)*mysint+(s3)*cost)+origin.z; } s2=myCentre.y-origin.y; s3=myCentre.z-origin.z; myCentre.y=(float)(s2*cost-s3*mysint)+origin.y; myCentre.z=(float)(s2*mysint+s3*cost)+origin.z; break; case y: for (i=0; i<numberOfCoords*dimension; i+=dimension){ s1=myCoords[i]-origin.x; s3=myCoords[i+2]-origin.z; myCoords[i]=(float)((s1)*cost+s3*mysint)+origin.x; myCoords[i+2]=(float)((-s1)*mysint+s3*cost)+origin.z; } for (i=0; i<(numberOfTags*coordsInATag*dimension); i+=dimension){ s1=myTags[i]-origin.x; s3=myTags[i+2]-origin.z; myTags[i]=(float)((s1)*cost+s3*mysint)+origin.x; myTags[i+2]=(float)((-s1)*mysint+s3*cost)+origin.z; } s1=myCentre.x-origin.x; s3=myCentre.z-origin.z; myCentre.x=(float)(s1*cost+s3*mysint)+origin.x; myCentre.z=(float)(-s1*mysint+s3*cost)+origin.z; break; case z: for (i=0; i<numberOfCoords*dimension; i+=dimension){ s1=myCoords[i]-origin.x; s2=myCoords[i+1]-origin.y; myCoords[i]=(float)(s1*cost-s2*mysint)+origin.x; myCoords[i+1]=(float)(s1*mysint+s2*cost)+origin.y; } for (i=0; i<(numberOfTags*coordsInATag*dimension); i+=dimension){ s1=myTags[i]-origin.x; s2=myTags[i+1]-origin.y; myTags[i]=(float)(s1*cost-s2*mysint)+origin.x; myTags[i+1]=(float)(s1*mysint+s2*cost)+origin.y; } s2=myCentre.y-origin.x; s1=myCentre.x-origin.y; myCentre.x=(float)(s1*cost-s2*mysint)+origin.x; myCentre.y=(float)(s1*mysint+s2*cost)+origin.y; } return self; } - translate: (Direction) direction alongAxis: (Axis) thisAxis atRate:(float) rate { float mydir; int i; if(direction==negative) { mydir=-1*rate; } else { mydir=rate; } switch(thisAxis) { case x: myCentre.x+=mydir; break; case y: myCentre.y+=mydir; break; case z: myCentre.z+=mydir; break; } for(i=0;i<numberOfCoords*dimension;i+=dimension){ myCoords[i+thisAxis]+=mydir; } for(i=0;i<numberOfTags*coordsInATag*dimension;i+=dimension){ myTags[i+thisAxis]+=mydir; } return self; } - setCentre:(float) x :(float)y :(float)z { printf("Setting\n"); myCentre.x=x; myCentre.y=y; myCentre.z=z; return self; } - setFrameColour:(float) r :(float)g :(float)b { myFrameColour.red=r; myFrameColour.green=g; myFrameColour.blue=b; return self; } - setTagColour:(float) r :(float)g :(float)b { myTagColour.red=r; myTagColour.green=g; myTagColour.blue=b; return self; } - setNumberOfTags:(int)count { numberOfTags=count; return self; } - setCoordsInATag:(int)count; { coordsInATag=count; return self; } - setNumberOfTagPS:(int)count; { numberOfTagPS=count; return self; } - setNumberOfCoords:(int) count; { numberOfCoords=count; return self; } - setNumberOfMyPS:(int) count; { numberOfMyPS=count; return self; } - setBoundingBox:(float *) thisBox { bbox[0]=-1.0e16; bbox[1]=-1.0e16; bbox[2]=1.0e16; bbox[3]=1.0e16; return self; } - (int) getNumberOfMyPS { return numberOfMyPS; } - (int) getNumberOfPoints { return (numberOfCoords); } - makeWireFrame:(const char *)thisFrame { const char *frameCoords,*framePS,*tagCoords,*numOfTags,*frameColour, *frameCentre,*tagColour,*tagPS, *coordsInTag,*check; int i; char ps=0; if ([myTable readFromFile:thisFrame]==nil){ return self; NXRunAlertPanel(thisFrame,"The file is not in the given directory. Please fix this problem and restart the application.","Quit",NULL,NULL); [NXApp terminate:self]; } frameCoords=[myTable valueForStringKey:"FramePoints"]; tagCoords=[myTable valueForStringKey:"TagPoints"]; frameColour=[myTable valueForStringKey:"FrameColor"]; tagColour=[myTable valueForStringKey:"TagColor"]; framePS=[myTable valueForStringKey:"FramePS"]; coordsInTag=[myTable valueForStringKey:"PointsPerTag"]; numOfTags=[myTable valueForStringKey:"NumberOfTags"]; frameCentre=[myTable valueForStringKey:"FrameCenter"]; tagPS=[myTable valueForStringKey:"TagPS"]; numberOfTags=atoi(numOfTags); coordsInATag=atoi(coordsInTag); numberOfCoords=count(frameCoords,',')+1; numberOfMyPS=count(framePS,',')+1; numberOfTagPS=count(tagPS,',')+1; sscanf(frameColour,"%f , %f , %f", &myFrameColour.red,&myFrameColour.green,&myFrameColour.blue); sscanf(tagColour,"%f , %f , %f", &myTagColour.red,&myTagColour.green,&myTagColour.blue); sscanf(frameCentre,"%f , %f , %f",&myCentre.x,&myCentre.y,&myCentre.z); for(i=0,check=framePS;check!=(char *)1;i++,check=index(check,',')+1){ switch(check[0]){ case 'a': switch (check[3]){ case 'n': ps=dps_arcn; break; case 't': ps=dps_arct; break; default: ps=dps_arc; } break; case 'm': ps=dps_moveto;break; case 'r': switch(check[1]){ case 'm': ps=dps_rmoveto;break; case 'l': ps=dps_rlineto; break; default: ps=dps_rcurveto; } break; switch(check[1]){ case 'l' :ps=dps_closepath; break; case 'u':ps=dps_curveto; break; } case 'c': switch(check[1]){ case 'l' :ps=dps_closepath; break; case 'u':ps=dps_curveto; break; } break; case 'u': ps=dps_ucache; break; case 'l' : ps=dps_lineto; break; default: ps=-1; } myPSCommands[i]=ps; } for(i=0,check=tagPS;check!=(char *)1;i++,check=index(check,',')+1){ switch(check[0]){ case 'a': switch (check[3]){ case 'n': ps=dps_arcn; break; case 't': ps=dps_arct; break; default: ps=dps_arc; } break; case 'm': ps=dps_moveto; break; case 'r': switch(check[1]){ case 'm': ps=dps_rmoveto; break; case 'l': ps=dps_rlineto; break; default: ps=dps_rcurveto; } break; case 'c': switch(check[1]){ case 'l' :ps=dps_closepath; break; case 'u':ps=dps_curveto; break; } break; case 'u': ps=dps_ucache; break; case 'l' : ps=dps_lineto; break; default: ps=-1; break; } myTagPSCommands[i]=ps; } for (i=0,check=frameCoords;i<numberOfCoords;i++,check=(index(check,',')+1)){ sscanf(check," %f",(&myCoords[i])); } for (i=0,check=tagCoords;i<numberOfTags*coordsInATag*4;i++,check=(index(check,',')+1)){ sscanf(check," %f",(&myTags[i])); } numberOfCoords/=4; return self; } - readBinaryCodeFrom: (char *) thisFile { return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.