Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Ground Generator
Трава супер, но деревья это пестец.
Да и лог в 250 мегабайт наверно жрет ресурсы на создание
А у меня с землей все окей

// вектор в тридэ
class float3 {
public:
float x;
float y;
float z;
float3(){
x=0.0f;
y=0.0f;
z=0.0f;
}
float3(float a, float b, float c){
x=a;
y=b;
z=c;
}
void set(float a, float b,float c)
{
x=a;
y=b;
z=c;
}
};
float3 operator*(float3 a, float3 b){
float3 result;
result.x=a.y*b.z-b.y*a.z;
result.y=a.z*b.x-b.z*a.x;
result.z=a.x*b.y-b.x*a.y;
return result;
}
float3 operator*(float3 a, float b){
float3 result(a.x*b,a.y*b,a.z*b);
return result;
}
float3 operator*(float a, float3 b){
float3 result(b.x*a,b.y*a,b.z*a);
return result;
}
float3 operator+(float3 a,float3 b){
float3 result;
result.x=a.x+b.x;
result.y=a.y+b.y;
result.z=a.z+b.z;
return result;
}
float3 operator/(float3 a, float b){
float3 result;
result.x=a.x/b;
result.y=a.y/b;
result.z=a.z/b;
return result;
}
//*************
//*************
//-------------------------------------------
//класс триколелектион
class tree_col{
public:
//***textures of leaves
Handle leaf_tex0;
Handle leaf_tex1;
Handle leaf_tex2;
Handle leaf_tex3;
//***textures of truncs
Handle bark_tex0;
Handle bark_tex1;
Handle bark_tex2;
Handle bark_tex3;
//***Handle of meshs for branch imitation
Handle trunc0;
Handle l1_branch0;
Handle l2_branch0;
//just for fan
double **data;
Handle temp;
//********************
tree_col(){
load_resources();
//mesh of trunc
float size=1;
trunc0=MakeMesh(4,size,size/5);
xEntityTexture(trunc0,bark_tex0);
xHideEntity(trunc0);
//texturifaing
l1_branch0=MakeMesh(4,32,4.3);
xEntityTexture(l1_branch0,bark_tex0);
xHideEntity(l1_branch0);
temp=xCreatePivot();
}
Handle Make_a_tree(float3 p,float3 r,float3 s, int gen, Handle smesh, float length){
//ignition
if(gen==0){
xFreeEntity(temp);
temp=xCreatePivot();
xPositionEntity(temp,p.x,p.y,p.z);}
Handle branch_mesh=smesh;
int generation=gen;
Handle mesh=xCopyEntity(branch_mesh,temp);
xScaleEntity(mesh,s.x,s.y,s.z);
xPositionEntity(mesh,p.x,p.y,p.z);
if(gen==0){ xPositionEntity(mesh,0,0,0);}
xAlignToVector(mesh,r.x,r.y,r.z,2,1);
xTFormPoint(0,0.9*length,0,mesh,temp);
float3 ch_pos(xTFormedX(),xTFormedY(),xTFormedZ());
int ch_num=xRand(1,3);
// листва
if(gen==2){
Handle leaf=Make_a_Branch(length);
xEntityParent(leaf,temp);
xPositionEntity(leaf,ch_pos.x,ch_pos.y,ch_pos.z);
xScaleEntity(leaf,xRnd(30,35)*length/32,40*length/32,xRnd(30,35)*length/32);
xAlignToVector(leaf,r.x,r.y,r.z,2,1);}
//child generation
if(generation<2){
float seedh=xRnd(0,M_PI);
float seedv=xRnd(-0.1*M_PI,0.1*M_PI);
for(int i=0;i<ch_num;i++){
int genr=generation+1;
float xr=seedh+2*M_PI*i/ch_num+xRnd(-M_PI*0.1,M_PI*0.1);
//y-axis
float yr=seedv+0.15*M_PI+xRnd(-M_PI*0.3,M_PI*0.3);
float3 rt(cos(xr)*cos(yr),cos(yr),sin(xr)*cos(yr));
rt=rt+0.5*r;
//scale defenition
float3 scle(0.5*s.x,xRnd(0.6,0.8)*s.y,0.5*s.z);
Make_a_tree(ch_pos,rt,scle,genr,smesh,length);
}
}
return temp;
}
Handle Make_a_Branch(float size){
Handle leaf=xCreateMesh();
Handle surf=xCreateSurface(leaf);
int v00=xAddVertex(surf,-1,0,0,0,0);
int v01=xAddVertex(surf,1,0,0,1,0);
int v10=xAddVertex(surf,-1,2,0,0,1);
int v11=xAddVertex(surf,1,2,0,1,1);
xAddTriangle(surf,v00,v01,v10);
xAddTriangle(surf,v01,v11,v10);
xAddTriangle(surf,v01,v00,v10);
xAddTriangle(surf,v11,v01,v10);
v00=xAddVertex(surf,0,0,-1,0,0);
v01=xAddVertex(surf,0,0,1,1,0);
v10=xAddVertex(surf,0,2,-1,0,1);
v11=xAddVertex(surf,0,2,1,1,1);
xAddTriangle(surf,v00,v01,v10);
xAddTriangle(surf,v01,v11,v10);
xAddTriangle(surf,v01,v00,v10);
xAddTriangle(surf,v11,v01,v10);
xEntityTexture(leaf,leaf_tex1);
xEntityFX(leaf,2);
return leaf;
}
Handle MakeMesh(int segments, float size, float radius){
gradient_noise(segments,1.33,3,rand());
Handle mesh=xCreateMesh();
Handle surf=xCreateSurface(mesh);
//создание плоскости
for(int i=0;i<=segments;i++){for(int j=0;j<=segments;j++){xAddVertex(surf,i,0,j,(double)i*3/segments,(double)j*3/segments);}}
int qvert=xCountVertices(surf);
for(int i=0;i<qvert-segments-1;i++){
int v0=i;
int v1=i+1;
int v2=i+segments+1;
int v3=v2+1;
if(v3<qvert && xMod(i,segments+1)!=segments){
xAddTriangle(surf,v2,v1,v3); xAddTriangle(surf,v2,v0,v1);
}}
for(int i=0;i<=segments;i++){for(int j=0;j<=segments;j++){
int index=i*(segments+1)+j;
//в 360 градусах 2*m_pi радиан
double crad=(radius+size*data[i%segments][j%segments]/32)*((segments-0.55*i)/segments);
double disp=3.5*sin(M_PI*i/(double)segments);
double sn=crad*sin(2*M_PI*j/(double)segments);
double cs=crad*cos(2*M_PI*j/(double)segments);
xVertexCoords(surf,index,sn,i*size/segments,cs);
if(i==segments){xVertexCoords(surf,index,0,i*size/segments,0);}}}
xUpdateN(mesh);
xCalculateFrustumVolume(mesh);
return mesh;
}
void gradient_noise(int size, double sharp, int diff, int seed){
//создается массив для значений
srand(seed);
data=new double*[size+1];
for(int i=0;i<=size;i++){data[i]= new double[size];}
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){data[i][j]=0;}}
//заполнение краев случайными числами (1;5)
int step=size>>2;
for(int i=0;i<=size;i=i+step){
for(int j=0;j<=size;j=j+step){
data[i][j]= xRnd(-5,5);}}
step=size>>1;
while(step>0){
//первая строка
for(int i=step;i<=size-step;i=i+2*step){
for(int j=step;j<=size-step;j=j+2*step){
//вычисление необходимых индексов
int x0=i-step;
if(x0<0){x0=x0+size;}
int x1=i+step;
if(x1>=size){x1=x1-size;}
int y0=j-step;
if(y0<0){y0=y0+size;}
int y1=j+step;
if(y1>=size){y1=y1-size;}
double val00=data[x0][y0];
double val01=data[x0][y1];
double val10=data[x1][y0];
double val11=data[x1][y1];
if(data[i][j]==0 && val00!=0 && val01!=0 && val10!=0 && val11!=0){
data[i][j]=0.25*(val00+val01+val10+val11)+0.5*step*xRnd(-sharp,sharp);
data[x0][j]=0.5*(val00+val01)+0.5*step*xRnd(-sharp,sharp);
data[x1][j]=0.5*(val10+val11)+0.5*step*xRnd(-sharp,sharp);
data[i][y0]=0.5*(val00+val10)+0.5*step*xRnd(-sharp,sharp);
data[i][y1]=0.5*(val01+val11)+0.5*step*xRnd(-sharp,sharp);}
}
}
step=step>>1;}
//приведение значений в массиве в интервал (0;1)
double max=0;
double min=0;
for (int i=0;i<=size;i++){
for (int j=0;j<=size;j++){
if(data[i][j]>=max){max=data [i][j];}
if(data[i][j]<=min){min=data [i][j];}}}
double length=max-min;
for (int i=0;i<=size;i++){
for (int j=0;j<=size;j++){
data[i][j]=pow(((data[i][j]-min)/length),1);}}
}
void load_resources(){
//textures of leaves
//leaf_tex0=xLoadTexture("tex/branch1.dds",2);
leaf_tex1=xLoadTexture("tex/branch3.dds",4);
//leaf_tex2=xLoadTexture("tex/branch4.dds",4);
//leaf_tex3=xLoadTexture("tex/sacura2.dds",4);
//textures of bark
bark_tex0=xLoadTexture("tex/bark0.jpg");
//bark_tex1=xLoadTexture("tex/bark1.jpg");
//bark_tex2=xLoadTexture("tex/bark2.jpg");
//bark_tex3=xLoadTexture("tex/bark3.jpg");
}
double xRnd(double min, double max){
double length=max-min;
double var =((double) rand() / (double)RAND_MAX);
double value=min+var*length;
return value;
}
};
//********************
//управляющий код
//********************
tree_col trees;
for(int i=0;i<100;i++){
float3 pos(i,0,i);
float3 rot(0,1,0);
float3 scale(1,1,1);
int generation=0;
Handle tr=xCopyEntity(trees.Make_a_tree(pos,rot,scale,generation,trees.trunc0,1));}
/*нужно иметь папку tex
в которой
bark_tex0=xLoadTexture("tex/bark0.jpg"); текстура коры
leaf_tex1=xLoadTexture("tex/branch3.dds",4);текстура веток.*/
|