Guest User

HUI

a guest
Oct 25th, 2011
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.25 KB | None | 0 0
  1. #include "treegen.h"
  2. #include <math.h>
  3. #include <stdio.h>
  4.  
  5. int TreeGen::TREE_TEX;
  6. int TreeGen::TREE_SHADER;
  7. int TreeGen::LEAF_TEX;
  8.  
  9. float rnd(float v1,float v2)
  10. {
  11.     long int _v1 = (long int)(v1*10000);
  12.     long int _v2 = (long int)(v2*10000);
  13.     return (_v1 + rand()%(_v2-_v1))/10000.0f;
  14. }
  15.  
  16. int TreeGen::Tree(TreeGen::Trunc * pTree)
  17. {
  18.     if(!TreeGen::TREE_TEX) TreeGen::TREE_TEX = xLoadTexture("media/treetex.png");
  19.     if(!TreeGen::LEAF_TEX) TreeGen::LEAF_TEX = xLoadTexture("media/leaf_1.png",2);
  20.     if(!TreeGen::TREE_SHADER)
  21.     {
  22.         TreeGen::TREE_SHADER = xLoadFXFile("shaders/tree.fx");
  23.         if(!TreeGen::TREE_SHADER)
  24.         {
  25.             printf("Error with loading Tree Shader\n");
  26.             exit(1);
  27.         }
  28.     }
  29.     pTree->iLeafSurface = 0;
  30.     pTree->iMesh = 0;
  31.     pTree->iSurface = 0;
  32.     float lx = pTree->x,ly = pTree->y,lz = pTree->z;
  33.     pTree->x = pTree->y = pTree->z = 0;
  34.     int iTree = TreeGen::BuildTree(pTree,0);
  35.     if(iTree)
  36.     {
  37.         xPositionEntity(iTree,lx,ly,lz);
  38.         //xSetEntityEffect(iTree,TreeGen::TREE_SHADER);
  39.         //xSetEffectTechnique(iTree,"Tree");
  40.         xEntityTexture(iTree,TreeGen::TREE_TEX);
  41.         xSurfaceTexture(pTree->iLeafSurface,TreeGen::LEAF_TEX,0,0);
  42.         xSurfaceFX(pTree->iLeafSurface,16);
  43.         //xSurfaceColor(pTree->iLeafSurface,rand()%20,rand()%200,rand()%30);
  44.         xUpdateNormals(iTree);
  45.     }
  46.     return iTree;
  47. }
  48.  
  49. int TreeGen::BuildTree(TreeGen::Trunc * pTree,int iRecurseCounter)
  50. {
  51.     //Создать шаблон
  52.     if(pTree->iSectionCount<1) return 0;
  53.     if(pTree->iVertexCount<3) pTree->iVertexCount = 3;
  54.     int iTemplate = xCreateMesh();
  55.     int iTemplateSurface = xCreateSurface(iTemplate);
  56.     int iTemplateStack = 0;
  57.     for(int k = 0;k<pTree->iVertexCount;k++)
  58.     {
  59.         float fAngle = 2*M_PI*((float)k/pTree->iVertexCount);
  60.         xAddVertex(iTemplateSurface,sin(fAngle),cos(fAngle),0,(float)(k/pTree->iVertexCount));
  61.     }
  62.  
  63.     //Два буфера вершин
  64.     int iVCount = pTree->iVertexCount;
  65.     int * piVertexBuffer1 = new int[iVCount];
  66.     int * piVertexBuffer2 = new int[iVCount];
  67.     bool bUseVertexBuffer = false; //вязать или нет)
  68.  
  69.     //меш ветки.
  70.     int iMesh,iSurface,iLeaf;
  71.     iMesh = (pTree->iMesh?pTree->iMesh:xCreateMesh());
  72.     iSurface = (pTree->iSurface?pTree->iSurface:xCreateSurface(iMesh));
  73.     iLeaf = (pTree->iLeafSurface?pTree->iLeafSurface:xCreateSurface(iMesh));
  74.     pTree->iLeafSurface = iLeaf;
  75.  
  76.     int iPoint = xCreatePivot();
  77.  
  78.     //Подготовка
  79.     float nx = pTree->nx,ny = pTree->ny,nz = pTree->nz;
  80.     float x = pTree->x,y = pTree->y,z = pTree->z;
  81.     float fLength = 0;
  82.     TreeGen::NormalizeVector(nx,ny,nz);
  83.     int iCount = pTree->iSectionCount+1;
  84.     //ГО!
  85.     while(iCount--)
  86.     {
  87.         //Поставить направляющую, сделать образ в 3D
  88.         iTemplateStack = xCopyMesh(iTemplate); //PUSH
  89.         xPositionEntity(iPoint,nx,ny,nz);
  90.         xPointEntity(iTemplate,iPoint);
  91.         xRotateMesh(iTemplate,xEntityPitch(iTemplate),xEntityYaw(iTemplate),0);
  92.         for(int k = 0;k<pTree->iVertexCount;k++)
  93.             piVertexBuffer1[k] = xAddVertex(iSurface,
  94.                                             xVertexX(iTemplateSurface,k)*pTree->fSectionRadius+x,
  95.                                             xVertexY(iTemplateSurface,k)*pTree->fSectionRadius+y,
  96.                                             xVertexZ(iTemplateSurface,k)*pTree->fSectionRadius+z,
  97.                                             ((float)k/iVCount)*.2,
  98.                                             fLength*10);
  99.         xFreeEntity(iTemplate);
  100.         iTemplate = iTemplateStack; //POP
  101.         iTemplateSurface = xGetSurface(iTemplate,0);
  102.  
  103.         //Связать геометрию
  104.         if(bUseVertexBuffer)
  105.         {
  106.             for(int k = 0;k<iVCount;k++)
  107.             {
  108.                 int k1 = k+1;
  109.                 int k2 = k-1;
  110.                 if(k1==iVCount) k1 = 0;
  111.                 if(k2<0) k2 = iVCount-1;
  112.                 xAddTriangle(iSurface,piVertexBuffer1[k],piVertexBuffer2[k1],piVertexBuffer2[k]);
  113.                 xAddTriangle(iSurface,piVertexBuffer1[k],piVertexBuffer2[k],piVertexBuffer1[k2]);
  114.             }
  115.             //Запустить еще веток)))
  116.             for(int k = 0;k<3+(pTree->fSectionRadius<2?4:0);k++)
  117.             {
  118.                 float n1[3] = {nx*pTree->fSectionSize,ny*pTree->fSectionSize,nz*pTree->fSectionSize};
  119.                 float n2[3] = {n1[0]+rnd(-2,2),n1[1]+rnd(-2,2),n1[2]+rnd(-2,2)};
  120.                 float n3[3] = {
  121.                                 (n1[1]*n2[2] - n2[1]*n1[2]),
  122.                                 (n1[0]*n2[2] - n2[0]*n1[2]),
  123.                                 (n1[0]*n2[1] - n2[0]*n1[1])
  124.                             };
  125.                 TreeGen::NormalizeVector(n3[0],n3[1],n3[2]);
  126.                 float fAngle = rnd(.3,.5);
  127.                 float fPos = rnd(0,1);
  128.                 TreeGen::Trunc Tree;
  129.                 Tree.fSectionRadius = pTree->fSectionRadius*rnd(.3,.7);
  130.                 Tree.fSectionSize = pTree->fSectionSize*.7;
  131.                 Tree.iVertexCount = pTree->iVertexCount*.6;
  132.                 Tree.iSectionCount = iCount-(1+rand()%2);
  133.                 Tree.nx = nx+(n3[0]-nx)*fAngle;
  134.                 Tree.ny = ny+(n3[1]-ny)*fAngle;
  135.                 Tree.nz = nz+(n3[2]-nz)*fAngle;
  136.                 Tree.x = x+(nx*pTree->fSectionSize)*fPos;
  137.                 Tree.y = y+(ny*pTree->fSectionSize)*fPos;
  138.                 Tree.z = z+(nz*pTree->fSectionSize)*fPos;
  139.                 Tree.iMesh = iMesh;
  140.                 Tree.iSurface = iSurface;
  141.                 Tree.iLeafSurface = iLeaf;
  142.                 TreeGen::BuildTree(&Tree,0);
  143.             }
  144.         }
  145.         if(pTree->fSectionRadius<2)
  146.             for(int k = 0;k<2;k++)
  147.             {
  148.                 float fPos = rnd(0,1);
  149.                 int iT = xCreateMesh();
  150.                 int iS = xCreateSurface(iT);
  151.                 float fA = rand()%360;
  152.                 #define size 6
  153.                 float fx = cos(fA/(180/M_PI))*size;
  154.                 float fy = sin(fA/(180/M_PI))*size;
  155.  
  156.                 int pi[4] = {
  157.                     xAddVertex(iS,size,0,size,0,0),
  158.                     xAddVertex(iS,size,0,0,1,0),
  159.                     xAddVertex(iS,0,0,0,1,1),
  160.                     xAddVertex(iS,0,0,size,0,1)
  161.                 };
  162.                 #undef size
  163.                 xPositionEntity(iPoint,nx,ny,nz);xPointEntity(iT,iPoint);
  164.                 xRotateMesh(iT,xEntityPitch(iT),xEntityYaw(iT),0);
  165.                 //xRotateMesh(iT,0,0,rand()%360);
  166.  
  167.                 for(int k = 0;k<4;k++)
  168.                     pi[k] = xAddVertex(iLeaf,
  169.                                        xVertexX(iS,k)+x+(nx*pTree->fSectionSize)*fPos,
  170.                                        xVertexY(iS,k)+y+(ny*pTree->fSectionSize)*fPos,
  171.                                        xVertexZ(iS,k)+z+(nz*pTree->fSectionSize)*fPos,
  172.                                        xVertexU(iS,k),
  173.                                        xVertexV(iS,k));
  174.                 xAddTriangle(iLeaf,pi[0],pi[1],pi[2]);
  175.                 xAddTriangle(iLeaf,pi[0],pi[3],pi[2]);
  176.                 xFreeEntity(iT);
  177.             }
  178.         //поменять буфера
  179.         int * piTemp = piVertexBuffer1;
  180.         piVertexBuffer1 = piVertexBuffer2;
  181.         piVertexBuffer2 = piTemp;
  182.  
  183.         //Посчитать дальнейшее передвижение
  184.         x+=nx*pTree->fSectionSize;
  185.         y+=ny*pTree->fSectionSize;
  186.         z+=nz*pTree->fSectionSize;
  187.         nx+=rnd(-.2,.2);
  188.         ny+=rnd(-.2,.2);
  189.         nz+=rnd(-.2,.2);
  190.         TreeGen::NormalizeVector(nx,ny,nz);
  191.         fLength+=sqrt(nx*nx+ny*ny+nz*nz);
  192.         pTree->fSectionRadius*=.65;
  193.         bUseVertexBuffer = true;
  194.     }
  195.     int V = xAddVertex(iSurface,x,y,z);
  196.     for(int k = 0;k<iVCount;k++)
  197.     {
  198.         int n1 = k+1;
  199.         if(n1 == iVCount) n1 = 0;
  200.         xAddTriangle(iSurface,V,piVertexBuffer2[n1],piVertexBuffer2[k]);
  201.     }
  202.  
  203.     delete[] piVertexBuffer1;
  204.     delete[] piVertexBuffer2;
  205.     xFreeEntity(iPoint);
  206.     xFreeEntity(iTemplate);
  207.     return iMesh;
  208. }
  209.  
  210. void TreeGen::NormalizeVector(float & x,float & y,float & z)
  211. {
  212.     float fLen = sqrt(x*x+y*y+z*z);
  213.     x/=fLen;y/=fLen;z/=fLen;
  214. }
  215.  
Advertisement
Add Comment
Please, Sign In to add comment