home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / 2D_3D / Tree3D_3.1 / Source / Tree.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  4.3 KB  |  153 lines

  1. // Tree.m -- a tree object, subclass and formed of Branches
  2.  
  3. #import <appkit/appkit.h>
  4. #import "ForestCamera.h"
  5. #import "Tree.h"
  6. extern long random();
  7. id globalShader;
  8.  
  9. @implementation Tree
  10. - init
  11. {    [super init];
  12.     random_mode = 1;
  13.     [self inzVars :0];
  14.     return self;
  15. }
  16.  
  17.  // access generation parmaeters
  18. - (double) angle                        {return angle;}
  19. - (double) angle :(double)angleArg        {return angle = angleArg;}
  20. - (double) twist                        {return twist;}
  21. - (double) twist :(double)twistArg        {return twist = twistArg;}
  22. - (double) shrink                        {return shrink;}
  23. - (double) shrink :(double)shrinkArg    {return shrink = shrinkArg;}
  24. - (int) branchFactor                    {return branchFactor;}
  25. - (int) branchFactor :(int)branchFactorArg
  26.                                         {return branchFactor=branchFactorArg;}
  27. - (int) levels                            {return levels;}
  28. - (int) levels :(int)levelsArg            {return levels = levelsArg;}
  29.  
  30. - (double) SDangle                        {return SDangle;}
  31. - (double) SDangle :(double)SDangleArg    {return SDangle = SDangleArg;}
  32. - (double) SDtwist                        {return SDtwist;}
  33. - (double) SDtwist :(double)SDtwistArg    {return SDtwist = SDtwistArg;}
  34. - (double) SDshrink                        {return SDshrink;}
  35. - (double) SDshrink :(double)SDshrinkArg{return SDshrink = SDshrinkArg;}
  36. - (double) SDbranchFactor                {return SDbranchFactor;}
  37. - (double) SDbranchFactor :(double)SDbranchFactorArg {return 
  38.                                         SDbranchFactor = SDbranchFactorArg;}
  39. - (double) SDlevels                        {return SDlevels;}
  40. - (double) SDlevels :(double)SDlevelsArg{return SDlevels = SDlevelsArg;}
  41.  
  42.  
  43. - plantIn :(ForestCamera *)forestArg
  44. {    RtBound box;
  45.     RtPoint eyePt, viewPt;
  46.     float rollAng, dist, d, size, x,y,z;
  47.     int i;
  48.     Branch *trunk = [[Branch alloc] init];
  49.     id oldWorldShape = [forestArg setWorldShape :self];
  50.  
  51.     srandom(lastSeed = random_mode? time(0): lastSeed);
  52.     
  53.     if (oldWorldShape == self)
  54.         oldWorldShape = descendant;
  55.     [oldWorldShape freeAll]; // free any old (parts of) trees
  56.     forest = forestArg;
  57.     
  58.     [trunk setShader :globalShader];
  59.     [trunk setBoundingBox :0 :0 :0 :0 :0 :1];
  60.     //[[self descendant] free];
  61.     [self linkDescendant :trunk];
  62.     [trunk tree :self];
  63.     [trunk addBranches :1 inTree :self];
  64.     [self getBoundingBox :&box];
  65.  
  66.      // Position viewpoint at center of box:
  67.     [forest getEyeAt :&eyePt toward :&viewPt roll :&rollAng];
  68.     viewPt[0] = x = (box[0]+box[1])*0.5;
  69.     viewPt[1] = y = (box[2]+box[3])*0.5;
  70.     viewPt[2] = z = (box[4]+box[5])*0.5;
  71.     [forest setEyeAt :eyePt toward :viewPt roll :-90.0];
  72.  
  73.      // Position the camera at a distance so the tree fills screen:
  74.     for (i=0, size=0.01; i<6; i+=2)    /* compute the largest dimension of the */
  75.     {    d = box[i] - box[i+1];        /*   surrounding box.*/
  76.         if (d < 0)                    
  77.             d = -d;
  78.         if (d > size)
  79.             size = d;
  80.     }
  81.     dist = sqrt((x-=eyePt[0])*x + (y-=eyePt[1])*y + (z-=eyePt[2])*z);
  82.     [forest moveEyeBy :0.0 :0.0 :2.2*size - dist];
  83.  
  84.     return self;
  85. }
  86.  
  87.  
  88. typedef struct
  89. {    int levels, branchFactor;
  90.     float angle, twist, shrink;
  91.     int SDbranchFactor, SDlevels;
  92.     float SDangle, SDtwist,SDshrink;
  93. } treeType;
  94. #define nTrees 6
  95. treeType trees[nTrees] = {
  96.     {4,  2, 45.0, 90.0, 0.70},                // inz
  97.     {5,  2, 20.0, 73.0, 0.83},                // elm
  98.     {3,  5, 35.0, 73.0, 0.75},                // queen annes lace
  99.     {7,  2, 23.0,  0.0, 0.80},                // fan
  100.     {7,  2, 90.0, 90.0, 0.67},                // tv antenna
  101.     {20, 1, 20.7,  0.7, 0.85},                // hook
  102. };
  103.  
  104. - specis :sender
  105. {    [self inzVars :[sender selectedTag]];
  106.     [self plantIn :forest];
  107.     [forest newParameter :nil];
  108.     [forest redrawNow :nil];
  109.     return self;
  110. }
  111.  
  112. - (int) inzVars :(int) index
  113. {    treeType *nt = &trees[index];
  114.     if (index < 0 || index >= nTrees)
  115.         return 0;
  116.     angle            = nt->angle;
  117.     twist            = nt->twist;
  118.     shrink            = nt->shrink;
  119.     branchFactor    = nt->branchFactor;
  120.     levels            = nt->levels;
  121.     SDangle            = nt->SDangle;
  122.     SDtwist            = nt->SDtwist;
  123.     SDshrink        = nt->SDshrink;
  124.     SDbranchFactor    = nt->SDbranchFactor;
  125.     SDlevels        = nt->SDlevels;
  126.     return 1;
  127. }
  128.  
  129. - randomMode :sender;
  130. {    int lastRandom_mode = random_mode;
  131.     random_mode = [sender selectedTag];
  132.     if ((lastRandom_mode && random_mode) || (!lastRandom_mode && !random_mode))
  133.     {    if ([forest redraw_mode])
  134.         {    [self plantIn :forest];
  135.             [forest redrawNow :nil];
  136.     }    }
  137.     return self;
  138. }
  139.  
  140. - (float) randVal :(treeParameter) param;
  141. {    float r = ((random()&0xfffffff)/(float)0x8000000 - 1.0), val=0, sd=0;
  142.  
  143.     switch (param)
  144.     {    case ANGLE:            return (angle + r * SDangle);
  145.         case TWIST:            return (twist + r * SDtwist);
  146.         case SHRINK:        return (shrink + r * SDshrink);
  147.         case BRANCHFACTOR:    return (branchFactor + r * SDbranchFactor);
  148.         case LEVELS:        return (levels + r * SDlevels);
  149.     }
  150.     return 0.0;
  151. }
  152.  
  153. @end