home *** CD-ROM | disk | FTP | other *** search
- #import "CFWireFrame.h"
-
- @implementation CFWireFrame: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@hasc.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 CreepyFace, I think,
- // and there were two other contributors, but I can't find their names in the
- // source for it.
- //
- // CreepyFaceView shows a simple (ha!) spinning CreepyFace logo, in full 3D. The 3D code
- // came from an app I wrote a long time ago called "CFWireFrame", 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;
- }
-
-
- static 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);
- }
-
- - makeCFWireFrame:(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
-