home *** CD-ROM | disk | FTP | other *** search
- // Tree.m -- a tree object, subclass and formed of Branches
-
- #import <appkit/appkit.h>
- #import "ForestCamera.h"
- #import "Tree.h"
- extern long random();
- id globalShader;
-
- @implementation Tree
- - init
- { [super init];
- random_mode = 1;
- [self inzVars :0];
- return self;
- }
-
- // access generation parmaeters
- - (double) angle {return angle;}
- - (double) angle :(double)angleArg {return angle = angleArg;}
- - (double) twist {return twist;}
- - (double) twist :(double)twistArg {return twist = twistArg;}
- - (double) shrink {return shrink;}
- - (double) shrink :(double)shrinkArg {return shrink = shrinkArg;}
- - (int) branchFactor {return branchFactor;}
- - (int) branchFactor :(int)branchFactorArg
- {return branchFactor=branchFactorArg;}
- - (int) levels {return levels;}
- - (int) levels :(int)levelsArg {return levels = levelsArg;}
-
- - (double) SDangle {return SDangle;}
- - (double) SDangle :(double)SDangleArg {return SDangle = SDangleArg;}
- - (double) SDtwist {return SDtwist;}
- - (double) SDtwist :(double)SDtwistArg {return SDtwist = SDtwistArg;}
- - (double) SDshrink {return SDshrink;}
- - (double) SDshrink :(double)SDshrinkArg{return SDshrink = SDshrinkArg;}
- - (double) SDbranchFactor {return SDbranchFactor;}
- - (double) SDbranchFactor :(double)SDbranchFactorArg {return
- SDbranchFactor = SDbranchFactorArg;}
- - (double) SDlevels {return SDlevels;}
- - (double) SDlevels :(double)SDlevelsArg{return SDlevels = SDlevelsArg;}
-
-
- - plantIn :(ForestCamera *)forestArg
- { RtBound box;
- RtPoint eyePt, viewPt;
- float rollAng, dist, d, size, x,y,z;
- int i;
- Branch *trunk = [[Branch alloc] init];
- id oldWorldShape = [forestArg setWorldShape :self];
-
- srandom(lastSeed = random_mode? time(0): lastSeed);
-
- if (oldWorldShape == self)
- oldWorldShape = descendant;
- [oldWorldShape freeAll]; // free any old (parts of) trees
- forest = forestArg;
-
- [trunk setShader :globalShader];
- [trunk setBoundingBox :0 :0 :0 :0 :0 :1];
- //[[self descendant] free];
- [self linkDescendant :trunk];
- [trunk tree :self];
- [trunk addBranches :1 inTree :self];
- [self getBoundingBox :&box];
-
- // Position viewpoint at center of box:
- [forest getEyeAt :&eyePt toward :&viewPt roll :&rollAng];
- viewPt[0] = x = (box[0]+box[1])*0.5;
- viewPt[1] = y = (box[2]+box[3])*0.5;
- viewPt[2] = z = (box[4]+box[5])*0.5;
- [forest setEyeAt :eyePt toward :viewPt roll :-90.0];
-
- // Position the camera at a distance so the tree fills screen:
- for (i=0, size=0.01; i<6; i+=2) /* compute the largest dimension of the */
- { d = box[i] - box[i+1]; /* surrounding box.*/
- if (d < 0)
- d = -d;
- if (d > size)
- size = d;
- }
- dist = sqrt((x-=eyePt[0])*x + (y-=eyePt[1])*y + (z-=eyePt[2])*z);
- [forest moveEyeBy :0.0 :0.0 :2.2*size - dist];
-
- return self;
- }
-
-
- typedef struct
- { int levels, branchFactor;
- float angle, twist, shrink;
- int SDbranchFactor, SDlevels;
- float SDangle, SDtwist,SDshrink;
- } treeType;
- #define nTrees 6
- treeType trees[nTrees] = {
- {4, 2, 45.0, 90.0, 0.70}, // inz
- {5, 2, 20.0, 73.0, 0.83}, // elm
- {3, 5, 35.0, 73.0, 0.75}, // queen annes lace
- {7, 2, 23.0, 0.0, 0.80}, // fan
- {7, 2, 90.0, 90.0, 0.67}, // tv antenna
- {20, 1, 20.7, 0.7, 0.85}, // hook
- };
-
- - specis :sender
- { [self inzVars :[sender selectedTag]];
- [self plantIn :forest];
- [forest newParameter :nil];
- [forest redrawNow :nil];
- return self;
- }
-
- - (int) inzVars :(int) index
- { treeType *nt = &trees[index];
- if (index < 0 || index >= nTrees)
- return 0;
- angle = nt->angle;
- twist = nt->twist;
- shrink = nt->shrink;
- branchFactor = nt->branchFactor;
- levels = nt->levels;
- SDangle = nt->SDangle;
- SDtwist = nt->SDtwist;
- SDshrink = nt->SDshrink;
- SDbranchFactor = nt->SDbranchFactor;
- SDlevels = nt->SDlevels;
- return 1;
- }
-
- - randomMode :sender;
- { int lastRandom_mode = random_mode;
- random_mode = [sender selectedTag];
- if ((lastRandom_mode && random_mode) || (!lastRandom_mode && !random_mode))
- { if ([forest redraw_mode])
- { [self plantIn :forest];
- [forest redrawNow :nil];
- } }
- return self;
- }
-
- - (float) randVal :(treeParameter) param;
- { float r = ((random()&0xfffffff)/(float)0x8000000 - 1.0), val=0, sd=0;
-
- switch (param)
- { case ANGLE: return (angle + r * SDangle);
- case TWIST: return (twist + r * SDtwist);
- case SHRINK: return (shrink + r * SDshrink);
- case BRANCHFACTOR: return (branchFactor + r * SDbranchFactor);
- case LEVELS: return (levels + r * SDlevels);
- }
- return 0.0;
- }
-
- @end