Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "treegen.h"
- #include <math.h>
- #include <stdio.h>
- int TreeGen::TREE_TEX;
- int TreeGen::TREE_SHADER;
- int TreeGen::LEAF_TEX;
- float rnd(float v1,float v2)
- {
- long int _v1 = (long int)(v1*10000);
- long int _v2 = (long int)(v2*10000);
- return (_v1 + rand()%(_v2-_v1))/10000.0f;
- }
- int TreeGen::Tree(TreeGen::Trunc * pTree)
- {
- if(!TreeGen::TREE_TEX) TreeGen::TREE_TEX = xLoadTexture("media/treetex.png");
- if(!TreeGen::LEAF_TEX) TreeGen::LEAF_TEX = xLoadTexture("media/leaf_1.png",2);
- if(!TreeGen::TREE_SHADER)
- {
- TreeGen::TREE_SHADER = xLoadFXFile("shaders/tree.fx");
- if(!TreeGen::TREE_SHADER)
- {
- printf("Error with loading Tree Shader\n");
- exit(1);
- }
- }
- pTree->iLeafSurface = 0;
- pTree->iMesh = 0;
- pTree->iSurface = 0;
- float lx = pTree->x,ly = pTree->y,lz = pTree->z;
- pTree->x = pTree->y = pTree->z = 0;
- int iTree = TreeGen::BuildTree(pTree,0);
- if(iTree)
- {
- xPositionEntity(iTree,lx,ly,lz);
- //xSetEntityEffect(iTree,TreeGen::TREE_SHADER);
- //xSetEffectTechnique(iTree,"Tree");
- xEntityTexture(iTree,TreeGen::TREE_TEX);
- xSurfaceTexture(pTree->iLeafSurface,TreeGen::LEAF_TEX,0,0);
- xSurfaceFX(pTree->iLeafSurface,16);
- //xSurfaceColor(pTree->iLeafSurface,rand()%20,rand()%200,rand()%30);
- xUpdateNormals(iTree);
- }
- return iTree;
- }
- int TreeGen::BuildTree(TreeGen::Trunc * pTree,int iRecurseCounter)
- {
- //Создать шаблон
- if(pTree->iSectionCount<1) return 0;
- if(pTree->iVertexCount<3) pTree->iVertexCount = 3;
- int iTemplate = xCreateMesh();
- int iTemplateSurface = xCreateSurface(iTemplate);
- int iTemplateStack = 0;
- for(int k = 0;k<pTree->iVertexCount;k++)
- {
- float fAngle = 2*M_PI*((float)k/pTree->iVertexCount);
- xAddVertex(iTemplateSurface,sin(fAngle),cos(fAngle),0,(float)(k/pTree->iVertexCount));
- }
- //Два буфера вершин
- int iVCount = pTree->iVertexCount;
- int * piVertexBuffer1 = new int[iVCount];
- int * piVertexBuffer2 = new int[iVCount];
- bool bUseVertexBuffer = false; //вязать или нет)
- //меш ветки.
- int iMesh,iSurface,iLeaf;
- iMesh = (pTree->iMesh?pTree->iMesh:xCreateMesh());
- iSurface = (pTree->iSurface?pTree->iSurface:xCreateSurface(iMesh));
- iLeaf = (pTree->iLeafSurface?pTree->iLeafSurface:xCreateSurface(iMesh));
- pTree->iLeafSurface = iLeaf;
- int iPoint = xCreatePivot();
- //Подготовка
- float nx = pTree->nx,ny = pTree->ny,nz = pTree->nz;
- float x = pTree->x,y = pTree->y,z = pTree->z;
- float fLength = 0;
- TreeGen::NormalizeVector(nx,ny,nz);
- int iCount = pTree->iSectionCount+1;
- //ГО!
- while(iCount--)
- {
- //Поставить направляющую, сделать образ в 3D
- iTemplateStack = xCopyMesh(iTemplate); //PUSH
- xPositionEntity(iPoint,nx,ny,nz);
- xPointEntity(iTemplate,iPoint);
- xRotateMesh(iTemplate,xEntityPitch(iTemplate),xEntityYaw(iTemplate),0);
- for(int k = 0;k<pTree->iVertexCount;k++)
- piVertexBuffer1[k] = xAddVertex(iSurface,
- xVertexX(iTemplateSurface,k)*pTree->fSectionRadius+x,
- xVertexY(iTemplateSurface,k)*pTree->fSectionRadius+y,
- xVertexZ(iTemplateSurface,k)*pTree->fSectionRadius+z,
- ((float)k/iVCount)*.2,
- fLength*10);
- xFreeEntity(iTemplate);
- iTemplate = iTemplateStack; //POP
- iTemplateSurface = xGetSurface(iTemplate,0);
- //Связать геометрию
- if(bUseVertexBuffer)
- {
- for(int k = 0;k<iVCount;k++)
- {
- int k1 = k+1;
- int k2 = k-1;
- if(k1==iVCount) k1 = 0;
- if(k2<0) k2 = iVCount-1;
- xAddTriangle(iSurface,piVertexBuffer1[k],piVertexBuffer2[k1],piVertexBuffer2[k]);
- xAddTriangle(iSurface,piVertexBuffer1[k],piVertexBuffer2[k],piVertexBuffer1[k2]);
- }
- //Запустить еще веток)))
- for(int k = 0;k<3+(pTree->fSectionRadius<2?4:0);k++)
- {
- float n1[3] = {nx*pTree->fSectionSize,ny*pTree->fSectionSize,nz*pTree->fSectionSize};
- float n2[3] = {n1[0]+rnd(-2,2),n1[1]+rnd(-2,2),n1[2]+rnd(-2,2)};
- float n3[3] = {
- (n1[1]*n2[2] - n2[1]*n1[2]),
- (n1[0]*n2[2] - n2[0]*n1[2]),
- (n1[0]*n2[1] - n2[0]*n1[1])
- };
- TreeGen::NormalizeVector(n3[0],n3[1],n3[2]);
- float fAngle = rnd(.3,.5);
- float fPos = rnd(0,1);
- TreeGen::Trunc Tree;
- Tree.fSectionRadius = pTree->fSectionRadius*rnd(.3,.7);
- Tree.fSectionSize = pTree->fSectionSize*.7;
- Tree.iVertexCount = pTree->iVertexCount*.6;
- Tree.iSectionCount = iCount-(1+rand()%2);
- Tree.nx = nx+(n3[0]-nx)*fAngle;
- Tree.ny = ny+(n3[1]-ny)*fAngle;
- Tree.nz = nz+(n3[2]-nz)*fAngle;
- Tree.x = x+(nx*pTree->fSectionSize)*fPos;
- Tree.y = y+(ny*pTree->fSectionSize)*fPos;
- Tree.z = z+(nz*pTree->fSectionSize)*fPos;
- Tree.iMesh = iMesh;
- Tree.iSurface = iSurface;
- Tree.iLeafSurface = iLeaf;
- TreeGen::BuildTree(&Tree,0);
- }
- }
- if(pTree->fSectionRadius<2)
- for(int k = 0;k<2;k++)
- {
- float fPos = rnd(0,1);
- int iT = xCreateMesh();
- int iS = xCreateSurface(iT);
- float fA = rand()%360;
- #define size 6
- float fx = cos(fA/(180/M_PI))*size;
- float fy = sin(fA/(180/M_PI))*size;
- int pi[4] = {
- xAddVertex(iS,size,0,size,0,0),
- xAddVertex(iS,size,0,0,1,0),
- xAddVertex(iS,0,0,0,1,1),
- xAddVertex(iS,0,0,size,0,1)
- };
- #undef size
- xPositionEntity(iPoint,nx,ny,nz);xPointEntity(iT,iPoint);
- xRotateMesh(iT,xEntityPitch(iT),xEntityYaw(iT),0);
- //xRotateMesh(iT,0,0,rand()%360);
- for(int k = 0;k<4;k++)
- pi[k] = xAddVertex(iLeaf,
- xVertexX(iS,k)+x+(nx*pTree->fSectionSize)*fPos,
- xVertexY(iS,k)+y+(ny*pTree->fSectionSize)*fPos,
- xVertexZ(iS,k)+z+(nz*pTree->fSectionSize)*fPos,
- xVertexU(iS,k),
- xVertexV(iS,k));
- xAddTriangle(iLeaf,pi[0],pi[1],pi[2]);
- xAddTriangle(iLeaf,pi[0],pi[3],pi[2]);
- xFreeEntity(iT);
- }
- //поменять буфера
- int * piTemp = piVertexBuffer1;
- piVertexBuffer1 = piVertexBuffer2;
- piVertexBuffer2 = piTemp;
- //Посчитать дальнейшее передвижение
- x+=nx*pTree->fSectionSize;
- y+=ny*pTree->fSectionSize;
- z+=nz*pTree->fSectionSize;
- nx+=rnd(-.2,.2);
- ny+=rnd(-.2,.2);
- nz+=rnd(-.2,.2);
- TreeGen::NormalizeVector(nx,ny,nz);
- fLength+=sqrt(nx*nx+ny*ny+nz*nz);
- pTree->fSectionRadius*=.65;
- bUseVertexBuffer = true;
- }
- int V = xAddVertex(iSurface,x,y,z);
- for(int k = 0;k<iVCount;k++)
- {
- int n1 = k+1;
- if(n1 == iVCount) n1 = 0;
- xAddTriangle(iSurface,V,piVertexBuffer2[n1],piVertexBuffer2[k]);
- }
- delete[] piVertexBuffer1;
- delete[] piVertexBuffer2;
- xFreeEntity(iPoint);
- xFreeEntity(iTemplate);
- return iMesh;
- }
- void TreeGen::NormalizeVector(float & x,float & y,float & z)
- {
- float fLen = sqrt(x*x+y*y+z*z);
- x/=fLen;y/=fLen;z/=fLen;
- }
Advertisement
Add Comment
Please, Sign In to add comment