|
Xors3D Графический движок с поддержкой DirectX9 |
25.10.2011, 17:58
|
#181
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Вот то что я понимаю под синглсюрфейс. Пытался сделать легкий доступ к кваду и вроде получилось. Осталось нормальный контроль кол-ва сделать и можно будет кой-чо делать.
// вектор в тридэ class float3 { public: float x; float y; float z; float3(){ x=0.0f; y=0.0f; z=0.0f; } void set(float a, float b,float c) { x=a; y=b;z=c; } }; //вершина class vert_data { public: int index; Handle surf; float3 *position; float3 *normal; vert_data(){ position= new float3; normal= new float3; } void setnormal(float a, float b,float c){ xVertexNormal(surf,index,a,b,c); normal->set(a,b,c);} void setposition(float a, float b,float c){ xVertexCoords(surf,index,a,b,c); xVertexTexCoords(surf,index,a,c); position->set(a,b,c);} /* обновление нормали. есть четыре вектора (1,0,val00-val10) (0,1,val00-val01) (-1,0,val00-(val-10)) (0,1,val00-(val0-1)) попарно векторное умножение даст четыре нормали сумма/4 результирующая нормаль. одно вычисление валидно для четырех квадов */ }; //квад class quad { public: Handle surf; vert_data *v00; vert_data *v01; vert_data *v10; vert_data *v11; int index; quad(){ v00= new vert_data; v01= new vert_data; v10= new vert_data; v11= new vert_data; } }; //менеджер квадов class manager { public: Handle mesh; //массив под поверхности Handle *surf; // массив квадов // сикока квадо увсего int cquad; quad **sys; //размер элемента группы квадов. int size; //methods area //constructor manager(); }; manager :: manager(){ //ограничение числа индексов в 65536 //значит число квадов в поверхности int quadnum=256*64; cquad=0; mesh=xCreateMesh(); int number=4; surf= new Handle[number]; sys = new quad*[quadnum*number]; for(int i=0;i<number;i++){ surf[i]=xCreateSurface(mesh); for(int j=0;j<quadnum;j++){ int v00=xAddVertex(surf[i],0,0,0,0,0); int v01=xAddVertex(surf[i],0,0,0,0,0); int v10=xAddVertex(surf[i],0,0,0,0,0); int v11=xAddVertex(surf[i],0,0,0,0,0); xAddTriangle(surf[i],v00,v01,v10); xAddTriangle(surf[i],v01,v11,v10); //заполнение данными вышележащей(или глубже) структуры sys[cquad]=new quad; sys[cquad]->index=cquad; sys[cquad]->surf=surf[i]; sys[cquad]->v00->index=v00; sys[cquad]->v00->surf=sys[cquad]->surf; sys[cquad]->v00->setposition(0.0f,0.0f,0.0f); sys[cquad]->v00->setnormal(0.0f,1.0f,0.0f); sys[cquad]->v10->index=v10; sys[cquad]->v10->surf=sys[cquad]->surf; sys[cquad]->v10->setposition(1.0f,0.0f,0.0f); sys[cquad]->v10->setnormal(0.0f,1.0f,0.0f); sys[cquad]->v01->index=v01; sys[cquad]->v01->surf=sys[cquad]->surf; sys[cquad]->v01->setposition(0.0f,0.0f,1.0f); sys[cquad]->v01->setnormal(0.0f,1.0f,0.0f); sys[cquad]->v11->index=v11; sys[cquad]->v11->surf=sys[cquad]->surf; sys[cquad]->v11->setposition(1.0f,0.0f,1.0f); sys[cquad]->v11->setnormal(0.0f,1.0f,0.0f); cquad++; } } }
итоговый управляющий код:
manager uno; for(int i=0;i<uno.cquad;i++){ uno.sys[i]->v00->setposition(i,i,0); uno.sys[i]->v00->setnormal(0,1,0); uno.sys[i]->v10->setposition(i+1,i+1,0); uno.sys[i]->v10->setnormal(0,1,0); uno.sys[i]->v01->setposition(i,i,1); uno.sys[i]->v01->setnormal(0,1,0); uno.sys[i]->v11->setposition(i+1,i+1,1); uno.sys[i]->v11->setnormal(0,1,0); } xCalculateFrustumVolume(uno.mesh);
Смысл в том что одной поверхностью можно имитировать наличие нескольких тысяч частиц, тех же спрайтов к примеру. И рисоваться они будут за один дип вместо нескольких тысяч. На примере своего ландшафта я понял, что чем больше треугольников в одном дипе тем лучше. так как, что при 30к треугольников на экране, что при 150к фпс оставался практически идентичным даже на встроенном в сандибридж видео.
Последний раз редактировалось dsd, 29.10.2011 в 16:24.
|
(Offline)
|
|
27.10.2011, 00:26
|
#182
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
провел ацкую для моих способностей кодера битву за дипы. Снизил их количество радикально. Узнал много нового про ссылки и че нельзя и чего не надо делать с классами. Результат двоякий, фпс минимальный не повысился, средний возрос от полутора до двух раз. Теперь можно в любом месте вырезать дырку без регенерации поверхностей. Теперь данные генерируются и хранятся в одном классе, а модели в другом.
// вектор в тридэ
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 vert_data {
public:
int index;
Handle surf;
void setnormal(float a, float b,float c){
xVertexNormal(surf,index,a,b,c);
}
void setnormal(float3 a){
xVertexNormal(surf,index,a.x,a.y,a.z);
}
void setposition(float a, float b,float c){
xVertexCoords(surf,index,a,b,c);
xVertexTexCoords(surf,index,a,c);
}
/*
обновление нормали.
есть четыре вектора (1,0,val00-val10) (0,1,val00-val01) (-1,0,val00-(val-10)) (0,1,val00-(val0-1))
попарно векторное умножение даст четыре нормали сумма/4 результирующая нормаль.
одно вычисление валидно для четырех квадов
*/
};
//квад
class quadz {
public:
Handle surf;
vert_data v00;
vert_data v01;
vert_data v10;
vert_data v11;
int index;
};
//менеджер квадов
class manager {
public:
Handle mesh;
//массив под поверхности
Handle *surf;
// массив квадов
// сикока квадо увсего
quadz **quad;
//размер элемента группы квадов.
int size;
//methods area
//constructor
manager(int limiter);
};
manager::manager(int limiter){
//ограничитель кол-ва квадов
//ограничение числа индексов в 65536
//значит число квадов в поверхности
int quadnum=256*64;
int cquad=0;
mesh=xCreateMesh();
int number=ceil(limiter/quadnum)+1;
surf= new Handle[number];
quad = new quadz*[quadnum*number];
for(int i=0;i<number;i++){
surf[i]=xCreateSurface(mesh);
for(int j=0;j<quadnum;j++){
if(cquad==limiter){break;}
int v00=xAddVertex(surf[i],0,0,0,0,0);
int v01=xAddVertex(surf[i],0,0,0,0,0);
int v10=xAddVertex(surf[i],0,0,0,0,0);
int v11=xAddVertex(surf[i],0,0,0,0,0);
xAddTriangle(surf[i],v00,v01,v10);
xAddTriangle(surf[i],v01,v11,v10);
//заполнение данными вышележащей(или глубже) структуры
quad[cquad]=new quadz;
quad[cquad]->index=cquad;
quad[cquad]->surf=surf[i];
quad[cquad]->v00.index=v00; quad[cquad]->v00.surf=quad[cquad]->surf;
quad[cquad]->v10.index=v10; quad[cquad]->v10.surf=quad[cquad]->surf;
quad[cquad]->v01.index=v01; quad[cquad]->v01.surf=quad[cquad]->surf;
quad[cquad]->v11.index=v11; quad[cquad]->v11.surf=quad[cquad]->surf;
cquad++;
}
if(cquad==limiter){break;}
}
size=cquad;
}
class ground{
public:
//текущая позиция камеры
int x,y;
//***************************************
//далекое
Handle farmesh;
//далекое поверхность
Handle farsur;
// разрешение наиболее детализировнных ячеек.
int resolution;
// разрешение клеток средней детализации
int resol;
int number;
//data for deformations
//хранитель мирового зерна.
int uppersize;
float **seed;
int grain;
//массивы билжнего плана.
float ****strip;
//массивы среднего плана.
float ****stripm;
//шершавость нижнего уровня
float sharpness;
//сглживание
float smothing;
float defkof;
//нижняя точка всего ландшафта
float minimum;
//высота ландшафта
float height;
//скэйл текстур
//******************************************
//конструктор класса
ground(){
//position intitilazer
x=xEntityX(Pivot);
y=xEntityZ(Pivot);
//Mesh creation
//surface for mesh
//создание ближнего квадрата
number=6;
resolution=32;
sharpness=0.25f;
minimum=1000.4f;
//ближний план
//генерация мирового зерна
int upsize=10;
uppersize=1<<upsize;
grain=xMillisecs();
First_Generator(upsize,xMillisecs());
//структура данных ближнего плана
strip= new float ***[number+2];
for(int i=0;i<number+2;i++){strip[i]=new float **[number+2];}
//генерация деформационных массивов ближнего квадрата.
for(int i=0;i<number+2;i++){for(int j=0;j<number+2;j++){
strip[i][j]=new float *[resolution+1];
for(int k=0;k<=resolution;k++){strip[i][j][k]=new float[resolution+1];}}}
for(int i=0;i<number+2;i++){for(int j=0;j<number+2;j++){Diamond_Square(i,j,sharpness, smothing);}}
//структура данных среднего плана
resol=resolution/4;
//средний план
stripm= new float ***[3*number+2];
for(int i=0;i<3*number+2;i++){stripm[i]=new float **[3*number+2];}
//генерация деформационных массивов среднего квадрата.
for(int i=0;i<3*number+2;i++){for(int j=0;j<3*number+2;j++){
stripm[i][j]=new float *[resol+1];
for(int k=0;k<=resol;k++){stripm[i][j][k]=new float[resol+1];}}}
for(int i=0;i<3*number+2;i++){for(int j=0;j<3*number+2;j++){Diamond_Squarem(i,j,4*sharpness, smothing);}}
//*******************************************
farmesh=xCreateMesh();
//xEntityFX(farmesh,2);
farsur=xCreateSurface(farmesh);
int seize=50;
for(int i=-0.5*seize;i<=0.5*seize;i++){for(int j=-0.5*seize;j<=0.5*seize;j++){
int v0=xAddVertex(farsur,i*resolution,0,j*resolution,i*resolution,j*resolution);
int v1=xAddVertex(farsur,(i+1)*resolution,0,j*resolution,(i+1)*resolution,j*resolution);
int v2=xAddVertex(farsur,i*resolution,0,(j+1)*resolution,i*resolution,(j+1)*resolution);
int v3=xAddVertex(farsur,(i+1)*resolution,0,(j+1)*resolution,(i+1)*resolution,(j+1)*resolution);
if(((i>=number*1.5 || i<-number*1.5) && (j>=number*1.5 || number*1.5<-1)) || ((i<number*1.5 || i>-number*1.5) && (j>=number*1.5 || j<-number*1.5)) ||((i>=number*1.5 || i<-number*1.5) && (j<number*1.5 || j>-number*1.5))) {xAddTriangle(farsur,v1,v0,v2); xAddTriangle(farsur,v3,v1,v2);}
}}
Handle seaside_tex=xLoadTexture("tex/Gravel01.jpg");
Handle lgrass_tex=xLoadTexture("tex/Grass01.jpg");
Handle dgrass_tex=xLoadTexture("tex/Grass02.jpg");
Handle plain_tex=xLoadTexture("tex/Gravel02.jpg");
Handle lmountain_tex=xLoadTexture("tex/dirt01.jpg");
Handle mmountain_tex=xLoadTexture("tex/rock01.jpg");
Handle hmountain_tex=xLoadTexture("tex/snow02.jpg");
Handle smountain_tex=xLoadTexture("tex/snow01.jpg");
Handle rock_tex=xLoadTexture("tex/rockn.jpg");
Handle Shader=xLoadFXFile("shader/landpainter.fx");
xSetEntityEffect(farmesh,Shader);
xSetEffectTexture(farmesh,"seaside",seaside_tex);
xSetEffectTexture(farmesh,"lgrass",lgrass_tex);
xSetEffectTexture(farmesh,"dgrass",dgrass_tex);
xSetEffectTexture(farmesh,"plain",plain_tex);
xSetEffectTexture(farmesh,"lmountain",lmountain_tex);
xSetEffectTexture(farmesh,"mmountain",mmountain_tex);
xSetEffectTexture(farmesh,"hmountain",hmountain_tex);
xSetEffectTexture(farmesh,"smountain",smountain_tex);
xSetEffectTexture(farmesh,"rockn",rock_tex);
xSetEffectTechnique(farmesh, "Diffuse");
xSetEffectFloat(farmesh,"scale",0.3);
}
//***************************************************
//***************************************************
void Update_Environment(){
srand(x+y);
xPositionEntity(farmesh,x,0,y);
int qvert=xCountVertices(farsur);
for(int i=0;i<qvert;i++){
//смотрим в мировое зерно
int u=xVertexX(farsur,i);
int v=xVertexZ(farsur,i);
//адрес текущей точки в массиве значений
int xj=xMod((x+u)/resolution+4,uppersize);
int yj=xMod((y+v)/resolution+4,uppersize);
float val=seed[xj][yj];
xVertexCoords(farsur,i,u,val,v);
float m[3][4];
//вычисляю индекс вершины
//первая нормаль
int x1=-1; int z1=0;
int x2=0; int z2=1;
float y0=seed[xMod(xj,uppersize)][xMod(yj,uppersize)];
float y1=seed[xMod(xj+x1,uppersize)][xMod(yj+z1,uppersize)];
float y2=seed[xMod(xj+x2,uppersize)][xMod(yj+z2,uppersize)];
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
y1=seed[xMod(xj+x1,uppersize)][xMod(yj+z1,uppersize)];
y2=seed[xMod(xj+x2,uppersize)][xMod(yj+z2,uppersize)];
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
y1=seed[xMod(xj+x1,uppersize)][xMod(yj+z1,uppersize)];
y2=seed[xMod(xj+x2,uppersize)][xMod(yj+z2,uppersize)];
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
y1=seed[xMod(xj+x1,uppersize)][xMod(yj+z1,uppersize)];
y2=seed[xMod(xj+x2,uppersize)][xMod(yj+z2,uppersize)];
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-4.0f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
xVertexNormal(farsur,i,m[0][0],m[1][0],m[2][0]);
}
xCalculateFrustumVolume(farmesh);
}
//***************************************************
void Data_Switcher(int flag){
float **temp[number+2];
//do not touch this, never ever.
if(flag==0){
for(int i=0;i<number+2;i++){
temp[i]=strip[0][i];
for(int k=0;k<number+1;k++) {strip[k][i]=strip[k+1][i];}
strip[number+1][i]=temp[i];
Diamond_Square(number+1,i,sharpness,smothing);}}
if(flag==1){
for(int i=0;i<number+2;i++){
temp[i]=strip[number+1][i];
for(int k=number+1;k>0;k--) {strip[k][i]=strip[k-1][i];}
strip[0][i]=temp[i];
Diamond_Square2(0,i,sharpness,smothing);}}
if(flag==2){
for(int i=0;i<number+2;i++){
temp[i]=strip[i][0];
for(int k=0;k<number+1;k++) {strip[i][k]=strip[i][k+1];}
strip[i][number+1]=temp[i];
Diamond_Square(i,number+1,sharpness,smothing);}}
if(flag==3){
for(int i=0;i<number+2;i++){
temp[i]=strip[i][number+1];
for(int k=number+1;k>0;k--) {strip[i][k]=strip[i][k-1];}
strip[i][0]=temp[i];
Diamond_Square3(i,0,sharpness,smothing);}}
}
//*******************************************
void Data_Switcherm(int flag){
float **temp[3*number+2];
//do not touch this, never ever.
if(flag==0){
for(int i=0;i<3*number+2;i++){
temp[i]=stripm[0][i];
for(int k=0;k<3*number+1;k++) {stripm[k][i]=stripm[k+1][i];}
stripm[3*number+1][i]=temp[i];
Diamond_Squarem(3*number+1,i,4*sharpness,smothing);}}
if(flag==1){
for(int i=0;i<3*number+2;i++){
temp[i]=stripm[3*number+1][i];
for(int k=3*number+1;k>0;k--) {stripm[k][i]=stripm[k-1][i];}
stripm[0][i]=temp[i];
Diamond_Square2m(0,i,4*sharpness,smothing);}}
if(flag==2){
for(int i=0;i<3*number+2;i++){
temp[i]=stripm[i][0];
for(int k=0;k<3*number+1;k++) {stripm[i][k]=stripm[i][k+1];}
stripm[i][3*number+1]=temp[i];
Diamond_Squarem(i,3*number+1,4*sharpness,smothing);}}
if(flag==3){
for(int i=0;i<3*number+2;i++){
temp[i]=stripm[i][3*number+1];
for(int k=3*number+1;k>0;k--) {stripm[i][k]=stripm[i][k-1];}
stripm[i][0]=temp[i];
Diamond_Square3m(i,0,4*sharpness,smothing);}}
}
//сокращение нижнего уровня
void regenerator(int a,int b, float sharp, int size, float ****m, int dis){
//заполнение краев
if(m[a][b][0][0]==0){ m[a][b][0][0]=seed[xMod(x/resolution+a-dis,uppersize)][xMod(y/resolution+b-dis,uppersize)];}
if(m[a][b][size][0]==0) {m[a][b][size][0]=seed[xMod(x/resolution+a+1-dis,uppersize)][xMod(y/resolution+b-dis,uppersize)];}
if(m[a][b][0][size]==0) {m[a][b][0][size]=seed[xMod(x/resolution+a-dis,uppersize)][xMod(y/resolution+b+1-dis,uppersize)];}
if(m[a][b][size][size]==0) {m[a][b][size][size]=seed[xMod(x/resolution+a+1-dis,uppersize)][xMod(y/resolution+b+1-dis,uppersize)];}
int 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){
float val00=m[a][b][i-step][j-step];
float val01=m[a][b][i-step][j+step];
float val10=m[a][b][i+step][j-step];
float val11=m[a][b][i+step][j+step];
if(m[a][b][i][j]==0){m[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(m[a][b][i-step][j]==0){m[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(m[a][b][i+step][j]==0){m[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(m[a][b][i][j-step]==0){m[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(m[a][b][i][j+step]==0){m[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}}}
step=step>>1;}
}
//*******************************************************
void Diamond_Square(int a,int b, float sharp, int diff){
int size=resolution;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){strip[a][b][i][j]=0;}}
srand(seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b,uppersize)]);
for(int i=0;i<=size;i++){
if(a>0){strip[a][b][0][i]=strip[a-1][b][size][i];}
if(b>0){strip[a][b][i][0]=strip[a][b-1][i][size];}}
regenerator(a,b,sharp,size,strip,0);}
//********************************************************
void Diamond_Square2(int a,int b, float sharp, int diff){
int size=resolution;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){strip[a][b][i][j]=0;}}
srand(seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b,uppersize)]);
for(int i=0;i<=size;i++){
if(a<number){strip[a][b][size][i]=strip[a+1][b][0][i];}
if(b>0){strip[a][b][i][0]=strip[a][b-1][i][size];}}
regenerator(a,b,sharp,size,strip,0);}
//********************************************************
void Diamond_Square3(int a,int b, float sharp, int diff){
int size=resolution;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){strip[a][b][i][j]=0;}}
srand(seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b,uppersize)]);
for(int i=0;i<=size;i++){
if(a>0){strip[a][b][0][i]=strip[a-1][b][size][i];}
if(b<number){strip[a][b][i][size]=strip[a][b+1][i][0];}}
regenerator(a,b,sharp,size,strip,0);}
//*******************************************************
void Diamond_Squarem(int a,int b, float sharp, int diff){
int size=resol;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){stripm[a][b][i][j]=0;}}
srand(seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b-number,uppersize)]);
for(int i=0;i<=size;i++){
if(a>0){stripm[a][b][0][i]=stripm[a-1][b][size][i];}
if(b>0){stripm[a][b][i][0]=stripm[a][b-1][i][size];}}
regenerator(a,b,sharp,size,stripm,number);}
//********************************************************
void Diamond_Square2m(int a,int b, float sharp, int diff){
int size=resol;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){stripm[a][b][i][j]=0;}}
srand(seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b-number,uppersize)]);
for(int i=0;i<=size;i++){
if(a<number){stripm[a][b][size][i]=stripm[a+1][b][0][i];}
if(b>0){stripm[a][b][i][0]=stripm[a][b-1][i][size];}}
regenerator(a,b,sharp,size,stripm,number);}
//********************************************************
void Diamond_Square3m(int a,int b, float sharp, int diff){
int size=resol;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){stripm[a][b][i][j]=0;}}
srand(seed[xMod(x/resol+a-number,uppersize)][xMod(y/resol+b-number,uppersize)]);
for(int i=0;i<=size;i++){
if(a>0){stripm[a][b][0][i]=stripm[a-1][b][size][i];}
if(b<number){stripm[a][b][i][size]=stripm[a][b+1][i][0];}}
regenerator(a,b,sharp,size,stripm,number);}
//********************************************************
float xRnd(float min, float max){
float length=max-min;
float var =((float) rand() / (float)RAND_MAX);
float value=min+var*length;
return value;}
//********************************************************
void First_Generator(int size, int grain){
float max=-10000.01;
srand(grain);
int resolution=1<<size;
//создание структуры данных
float **m1[size];
for(int i=0;i<size;i++){
m1[i]=new float*[resolution];
for(int j=0;j<resolution;j++){m1[i][j]=new float[resolution];}}
//обнуление
for(int i=0;i<size;i++){for(int j=0;j<resolution;j++){for(int k=0;k<resolution;k++){m1[i][j][k]=0;}}}
//создание исходного шума
float length=0;
for(int i=0;i<size;i++){
int width=1<<(i+1);
//kof коэффициент веса октавы
float detsize=2.0f;
float kof=(size-i);
if(i==0){kof=detsize*16;}
if(i==1){kof=detsize*32;}
if(i==2){kof=detsize*64;}
if(i==3){kof=detsize*32;}
if(i==4){kof=detsize*16;}
if(i==5){kof=detsize*8;}
if(i>5){kof=detsize*4;}
for(int j=0;j<width;j++){for(int k=0;k<width;k++){m1[i][j<<(size-i-1)][k<<(size-i-1)]=kof*(1-2*(float)rand()/RAND_MAX);}}
//cуммируется вес октав это будет максимально возможный перепад высот
length=length+kof;}
//что бы коегде заменить все деления умножением
float len=(0.5/length);
//тут градиентный шум считается
for(int k=0;k<size-1;k++){
int step=resolution>>1;
while(step>0){
for(int i=step;i<resolution-step;i=i+2*step){
for(int j=step;j<resolution-step;j=j+2*step){
//данные в углах текущей клетки
float val00=m1[k][i-step][j-step];
float val01=m1[k][i-step][j+step];
float val10=m1[k][i+step][j-step];
float val11=m1[k][i+step][j+step];
//если текущая клетка пуста, то пишется в клетку крест значений
if(m1[k][i][j]==0){
m1[k][i][j]=0.25*(val00+val01+val10+val11);
m1[k][i-step][j]=0.5*(val00+val01);
m1[k][i+step][j]=0.5*(val10+val11);
m1[k][i][j-step]=0.5*(val00+val10);
m1[k][i][j+step]=0.5*(val01+val11);}
}}
step=step>>1;}}
//суммирование в последний массив
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){for(int k=0;k<size-1;k++){m1[size-1][i][j]=m1[size-1][i][j]+m1[k][i][j];}}}
seed=new float*[resolution];
for(int j=0;j<resolution;j++){seed[j]=new float[resolution];}
//суммирование в последний массив
for(int i=0;i<resolution;i++){
for(int j=0;j<resolution;j++){
seed[i][j]=m1[size-1][i][j];
}}
}
//********************************************************
int xMod(int a,int b){
int c=a-b*floor(a/b);
if(c<0) {c=c+b;}
return c;
}
//********************************************************
};
class land {
public:
int resolution;
int resol;
int number;
//ссылка на первичный класс земли
ground first;
//это координаты мира для которых система квадов прикинута миром.
int x,y;
//манагер квадов
manager *surf;
manager *surfm;
//структура для квадов
int ****strip;
int ****stripm;
land();
void updateland(){
int xc=xEntityX(Pivot);
int yc=xEntityZ(Pivot);
if(xc-resolution-1>x){
x=x+resolution;
first.x=x;
first.Data_Switcher(0);
first.Data_Switcherm(0);
first.Update_Environment();
Data_Switcher(0);
Data_Switcherm(0);}
if(xc+resolution+1<x){
x=x-resolution;
first.x=x;
first.Data_Switcher(1);
first.Data_Switcherm(1);
first.Update_Environment();
Data_Switcher(1);
Data_Switcherm(1);}
if(yc-resolution-1>y){
y=y+resolution;
first.y=y;
first.Data_Switcher(2);
first.Data_Switcherm(2);
first.Update_Environment();
Data_Switcher(2);
Data_Switcherm(2);}
if(yc+resolution+1<y){
y=y-resolution;
first.y=y;
first.Data_Switcher(3);
first.Data_Switcherm(3);
first.Update_Environment();
Data_Switcher(3);
Data_Switcherm(3);}
}
void Data_Switcher(int flag){
int **temp[number];
//do not touch this, never ever.
if(flag==0){
for(int i=0;i<number;i++){
temp[i]=strip[0][i];
for(int k=0;k<number-1;k++) {strip[k][i]=strip[k+1][i];}
strip[number-1][i]=temp[i];}
for(int i=0;i<number;i++){migrate_quads(number-1,i);}}
if(flag==1){
for(int i=0;i<number;i++){
temp[i]=strip[number-1][i];
for(int k=number-1;k>0;k--) {strip[k][i]=strip[k-1][i];}
strip[0][i]=temp[i];}
for(int i=0;i<number;i++){migrate_quads(0,i);}}
if(flag==2){
for(int i=0;i<number;i++){
temp[i]=strip[i][0];
for(int k=0;k<number-1;k++) {strip[i][k]=strip[i][k+1];}
strip[i][number-1]=temp[i];}
for(int i=0;i<number;i++){migrate_quads(i,number-1);}}
if(flag==3){
for(int i=0;i<number;i++){
temp[i]=strip[i][number-1];
for(int k=number-1;k>0;k--) {strip[i][k]=strip[i][k-1];}
strip[i][0]=temp[i];}
for(int i=0;i<number;i++){migrate_quads(i,0);}}
xCalculateFrustumVolume(surf->mesh);
}
void Data_Switcherm(int flag){
int **temp[3*number];
//do not touch this, never ever.
collapse_quadsm();
if(flag==0){
for(int i=0;i<3*number;i++){
temp[i]=stripm[0][i];
for(int k=0;k<3*number-1;k++) {stripm[k][i]=stripm[k+1][i];}
stripm[3*number-1][i]=temp[i];}
for(int i=0;i<3*number;i++){migrate_quadsm(3*number-1,i);}
for(int i=number;i<2*number;i++){migrate_quadsm(number-1,i);}}
if(flag==1){
for(int i=0;i<3*number;i++){
temp[i]=stripm[3*number-1][i];
for(int k=3*number-1;k>0;k--) {stripm[k][i]=stripm[k-1][i];}
stripm[0][i]=temp[i];}
for(int i=0;i<3*number;i++){migrate_quadsm(0,i);}
for(int i=number;i<2*number;i++){migrate_quadsm(2*number,i);}}
if(flag==2){
for(int i=0;i<3*number;i++){
temp[i]=stripm[i][0];
for(int k=0;k<3*number-1;k++) {stripm[i][k]=stripm[i][k+1];}
stripm[i][3*number-1]=temp[i];}
for(int i=0;i<3*number;i++){migrate_quadsm(i,3*number-1);}
for(int i=number;i<2*number;i++){migrate_quadsm(i,number-1);}}
if(flag==3){
for(int i=0;i<3*number;i++){
temp[i]=stripm[i][3*number-1];
for(int k=3*number-1;k>0;k--) {stripm[i][k]=stripm[i][k-1];}
stripm[i][0]=temp[i];}
for(int i=0;i<3*number;i++){migrate_quadsm(i,0);}
for(int i=number;i<2*number;i++){migrate_quadsm(i,2*number);}}
xCalculateFrustumVolume(surfm->mesh);
}
void collapse_quadsm(){
for(int a=number;a<2*number;a++){
for(int b=number;b<2*number;b++) {
for(int i=0;i<resol;i++){
for(int j=0;j<resol;j++){
int index=stripm[a][b][i][j];
int cont=-100;
surfm->quad[index]->v00.setposition(x+(a-1.5*number)*resolution+i*4,first.stripm[a+1][b+1][i][j]+cont,y+(b-1.5*number)*resolution+j*4);
surfm->quad[index]->v10.setposition(x+(a-1.5*number)*resolution+i*4+4,first.stripm[a+1][b+1][i+1][j]+cont,y+(b-1.5*number)*resolution+j*4);
surfm->quad[index]->v01.setposition(x+(a-1.5*number)*resolution+i*4,first.stripm[a+1][b+1][i][j+1]+cont,y+(b-1.5*number)*resolution+j*4+1*4);
surfm->quad[index]->v11.setposition(x+(a-1.5*number)*resolution+i*4+4,first.stripm[a+1][b+1][i+1][j+1]+cont,y+(b-1.5*number)*resolution+j*4+1*4);
}}}}
}
void migrate_quadsm(int a,int b){
for(int i=0;i<resol;i++){
for(int j=0;j<resol;j++){
int index=stripm[a][b][i][j];
surfm->quad[index]->v00.setposition(x+(a-1.5*number)*resolution+i*4,first.stripm[a+1][b+1][i][j],y+(b-1.5*number)*resolution+j*4);
surfm->quad[index]->v10.setposition(x+(a-1.5*number)*resolution+i*4+4,first.stripm[a+1][b+1][i+1][j],y+(b-1.5*number)*resolution+j*4);
surfm->quad[index]->v01.setposition(x+(a-1.5*number)*resolution+i*4,first.stripm[a+1][b+1][i][j+1],y+(b-1.5*number)*resolution+j*4+1*4);
surfm->quad[index]->v11.setposition(x+(a-1.5*number)*resolution+i*4+4,first.stripm[a+1][b+1][i+1][j+1],y+(b-1.5*number)*resolution+j*4+1*4);
//расчет нормалей
//нормаль для точки v00
//получение значений
float m[3][4];
//первая нормаль
int x1=-1; int z1=0;
int x2=0; int z2=1;
float y0=first.stripm[a+1][b+1][i][j];
float y1;
if(i==0){y1=first.stripm[a][b+1][i+x1+resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
float y2;
if(j==resol){y2=first.stripm[a+1][b+2][i+x2][j+z2-resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resol){y1=first.stripm[a+1][b+2][i+x1][j+z1-resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==resol){y2=first.stripm[a+2][b+1][i+x2-resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resol) {y1=first.stripm[a+2][b+1][i+x1-resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.stripm[a+1][b][i+x2][j+z2+resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.stripm[a+1][b][i+x1][j+z1+resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.stripm[a][b+1][i+x2+resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.8f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surfm->quad[index]->v00.setnormal(m[0][0],m[1][0],m[2][0]);
i++;
//нормаль для точки v10
//получение значений
m[3][4];
//первая нормаль
x1=-1; z1=0;
x2=0; z2=1;
y0=first.stripm[a+1][b+1][i][j];
y1;
if(i==0){y1=first.stripm[a][b+1][i+x1+resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
y2;
if(j==resol){y2=first.stripm[a+1][b+2][i+x2][j+z2-resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resol){y1=first.stripm[a+1][b+2][i+x1][j+z1-resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==resol){y2=first.stripm[a+2][b+1][i+x2-resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resol) {y1=first.stripm[a+2][b+1][i+x1-resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.stripm[a+1][b][i+x2][j+z2+resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.stripm[a+1][b][i+x1][j+z1+resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.stripm[a][b+1][i+x2+resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.8f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surfm->quad[index]->v10.setnormal(m[0][0],m[1][0],m[2][0]);
j++;
//нормаль для точки v11
//получение значений
m[3][4];
//первая нормаль
x1=-1; z1=0;
x2=0; z2=1;
y0=first.stripm[a+1][b+1][i][j];
y1;
if(i==0){y1=first.stripm[a][b+1][i+x1+resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
y2;
if(j==resol){y2=first.stripm[a+1][b+2][i+x2][j+z2-resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resol){y1=first.stripm[a+1][b+2][i+x1][j+z1-resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==resol){y2=first.stripm[a+2][b+1][i+x2-resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resol) {y1=first.stripm[a+2][b+1][i+x1-resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.stripm[a+1][b][i+x2][j+z2+resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.stripm[a+1][b][i+x1][j+z1+resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.stripm[a][b+1][i+x2+resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.8f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surfm->quad[index]->v11.setnormal(m[0][0],m[1][0],m[2][0]);
i--;
//нормаль для точки v01
//получение значений
m[3][4];
//первая нормаль
x1=-1; z1=0;
x2=0; z2=1;
y0=first.stripm[a+1][b+1][i][j];
y1;
if(i==0){y1=first.stripm[a][b+1][i+x1+resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
y2;
if(j==resol){y2=first.stripm[a+1][b+2][i+x2][j+z2-resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resol){y1=first.stripm[a+1][b+2][i+x1][j+z1-resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==resol){y2=first.stripm[a+2][b+1][i+x2-resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resol) {y1=first.stripm[a+2][b+1][i+x1-resol][j+z1];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.stripm[a+1][b][i+x2][j+z2+resol];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.stripm[a+1][b][i+x1][j+z1+resol];} else{y1=first.stripm[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.stripm[a][b+1][i+x2+resol][j+z2];} else{y2=first.stripm[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.8f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surfm->quad[index]->v01.setnormal(m[0][0],m[1][0],m[2][0]);
j--;
}}
}
void migrate_quads(int a,int b){
for(int i=0;i<resolution;i++){
for(int j=0;j<resolution;j++){
int index=strip[a][b][i][j];
surf->quad[index]->v00.setposition(x+(a-number/2)*resolution+i,first.strip[a+1][b+1][i][j],y+(b-number/2)*resolution+j);
surf->quad[index]->v10.setposition(x+(a-number/2)*resolution+i+1,first.strip[a+1][b+1][i+1][j],y+(b-number/2)*resolution+j);
surf->quad[index]->v01.setposition(x+(a-number/2)*resolution+i,first.strip[a+1][b+1][i][j+1],y+(b-number/2)*resolution+j+1);
surf->quad[index]->v11.setposition(x+(a-number/2)*resolution+i+1,first.strip[a+1][b+1][i+1][j+1],y+(b-number/2)*resolution+j+1);
//расчет нормалей
//нормаль для точки v00
//получение значений
float m[3][4];
int x1=-1; int z1=0;
int x2=0; int z2=1;
float y0=first.strip[a+1][b+1][i][j];
float y1;
if(i==0){y1=first.strip[a][b+1][i+x1+resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
float y2;
if(j==resolution){y2=first.strip[a+1][b+2][i+x2][j+z2-resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resolution){y1=first.strip[a+1][b+2][i+x1][j+z1-resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==resolution){y2=first.strip[a+2][b+1][i+x2-resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resolution) {y1=first.strip[a+2][b+1][i+x1-resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.strip[a+1][b][i+x2][j+z2+resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.strip[a+1][b][i+x1][j+z1+resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.strip[a][b+1][i+x2+resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.25f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surf->quad[index]->v00.setnormal(m[0][0],m[1][0],m[2][0]);
//нормаль для точки v01
//получение значений
j++;
m[3][4];
x1=-1; z1=0;
x2=0; z2=1;
y0=first.strip[a+1][b+1][i][j];
y1;
if(i==0){y1=first.strip[a][b+1][i+x1+resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
y2;
if(j==resolution){y2=first.strip[a+1][b+2][i+x2][j+z2-resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resolution){y1=first.strip[a+1][b+2][i+x1][j+z1-resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==resolution){y2=first.strip[a+2][b+1][i+x2-resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resolution) {y1=first.strip[a+2][b+1][i+x1-resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.strip[a+1][b][i+x2][j+z2+resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.strip[a+1][b][i+x1][j+z1+resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.strip[a][b+1][i+x2+resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.25f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surf->quad[index]->v01.setnormal(m[0][0],m[1][0],m[2][0]);
i++;
//нормаль для точки v11
//получение значений
m[3][4];
x1=-1; z1=0;
x2=0; z2=1;
y0=first.strip[a+1][b+1][i][j];
y1;
if(i==0){y1=first.strip[a][b+1][i+x1+resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
y2;
if(j==resolution){y2=first.strip[a+1][b+2][i+x2][j+z2-resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resolution){y1=first.strip[a+1][b+2][i+x1][j+z1-resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==resolution){y2=first.strip[a+2][b+1][i+x2-resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resolution) {y1=first.strip[a+2][b+1][i+x1-resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.strip[a+1][b][i+x2][j+z2+resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.strip[a+1][b][i+x1][j+z1+resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.strip[a][b+1][i+x2+resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.25f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surf->quad[index]->v11.setnormal(m[0][0],m[1][0],m[2][0]);
j--;
//нормаль для точки v10
//получение значений
m[3][4];
x1=-1; z1=0;
x2=0; z2=1;
y0=first.strip[a+1][b+1][i][j];
y1;
if(i==0){y1=first.strip[a][b+1][i+x1+resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
y2;
if(j==resolution){y2=first.strip[a+1][b+2][i+x2][j+z2-resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][0]=y1-y0;
m[1][0]=-1;
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resolution){y1=first.strip[a+1][b+2][i+x1][j+z1-resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==resolution){y2=first.strip[a+2][b+1][i+x2-resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][1]=y0-y2;
m[1][1]=-1;
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resolution) {y1=first.strip[a+2][b+1][i+x1-resolution][j+z1];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=first.strip[a+1][b][i+x2][j+z2+resolution];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][2]=y0-y1;
m[1][2]=-1;
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=first.strip[a+1][b][i+x1][j+z1+resolution];} else{y1=first.strip[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=first.strip[a][b+1][i+x2+resolution][j+z2];} else{y2=first.strip[a+1][b+1][i+x2][j+z2];}
m[0][3]=y2-y0;
m[1][3]=-1;
m[2][3]=y1-y0;
m[0][0]=0.25f*(m[0][0]+m[0][1]+m[0][2]+m[0][3]);
m[1][0]=-0.25f*(m[1][0]+m[1][1]+m[1][2]+m[1][3]);
m[2][0]=0.25f*(m[2][0]+m[2][1]+m[2][2]+m[2][3]);
surf->quad[index]->v10.setnormal(m[0][0],m[1][0],m[2][0]);
i--;
}}
}
};
land::land() {
//узнаю из переданного объекта разрешение
resolution=first.resolution;
number=first.number;
int quantity=resolution*resolution*number*number;
//создан объект который прикинется землей ближнего круга.
surf= new manager(quantity);
//теперь делю квады на нужное кол-во групп и пишу их индексы в массив
strip= new int ***[number];
for(int i=0;i<number;i++){strip[i]=new int **[number];}
//генерация деформационных массивов ближнего квадрата.
for(int i=0;i<number;i++){for(int j=0;j<number;j++){
strip[i][j]=new int *[resolution];
for(int k=0;k<resolution;k++){strip[i][j][k]=new int[resolution];}}}
x=0;
y=0;
//пишу индексы в размеченный массив.
int index=0;
for(int a=0;a<number;a++){
for(int b=0;b<number;b++) {
for(int i=0;i<resolution;i++){
for(int j=0;j<resolution;j++){
strip[a][b][i][j]=index;
surf->quad[index]->v00.setposition((a-number/2)*resolution+i,first.strip[a+1][b+1][i][j],(b-number/2)*resolution+j);
surf->quad[index]->v10.setposition((a-number/2)*resolution+i+1,first.strip[a+1][b+1][i+1][j],(b-number/2)*resolution+j);
surf->quad[index]->v01.setposition((a-number/2)*resolution+i,first.strip[a+1][b+1][i][j+1],(b-number/2)*resolution+j+1);
surf->quad[index]->v11.setposition((a-number/2)*resolution+i+1,first.strip[a+1][b+1][i+1][j+1],(b-number/2)*resolution+j+1);
index++;}}}}
for(int a=0;a<number;a++){
for(int b=0;b<number;b++) {migrate_quads(a,b);}}
resol=first.resol;
quantity=resol*resol*number*number*3*3;
//создан объект который прикинется землей ближнего круга.
surfm= new manager(quantity);
stripm= new int ***[3*number];
for(int i=0;i<3*number;i++){stripm[i]=new int **[3*number];}
//генерация деформационных массивов среднего квадрата.
for(int i=0;i<3*number;i++){for(int j=0;j<3*number;j++){
stripm[i][j]=new int *[resol];
for(int k=0;k<resol;k++){stripm[i][j][k]=new int[resol];}}}
index=0;
for(int a=0;a<3*number;a++){
for(int b=0;b<3*number;b++) {
for(int i=0;i<resol;i++){
for(int j=0;j<resol;j++){
stripm[a][b][i][j]=index;
surfm->quad[index]->v00.setposition((a-1.5*number)*resolution+i*4,first.stripm[a+1][b+1][i][j],(b-1.5*number)*resolution+j*4);
surfm->quad[index]->v10.setposition((a-1.5*number)*resolution+(i+1)*4,first.stripm[a+1][b+1][i+1][j],(b-1.5*number)*resolution+j*4);
surfm->quad[index]->v01.setposition((a-1.5*number)*resolution+i*4,first.stripm[a+1][b+1][i][j+1],(b-1.5*number)*resolution+(j+1)*4);
surfm->quad[index]->v11.setposition((a-1.5*number)*resolution+(i+1)*4,first.stripm[a+1][b+1][i+1][j+1],(b-1.5*number)*resolution+(j+1)*4);
index++;}}}}
for(int i=0;i<3*number;i++){for(int j=0;j<3*number;j++){migrate_quadsm(i,j);}}
//краска
Handle seaside_tex=xLoadTexture("tex/Gravel01.jpg");
Handle lgrass_tex=xLoadTexture("tex/Grass01.jpg");
Handle dgrass_tex=xLoadTexture("tex/Grass02.jpg");
Handle plain_tex=xLoadTexture("tex/Gravel02.jpg");
Handle lmountain_tex=xLoadTexture("tex/dirt01.jpg");
Handle mmountain_tex=xLoadTexture("tex/rock01.jpg");
Handle hmountain_tex=xLoadTexture("tex/snow02.jpg");
Handle smountain_tex=xLoadTexture("tex/snow01.jpg");
Handle rock_tex=xLoadTexture("tex/rockn.jpg");
Handle Shader=xLoadFXFile("shader/landpainter.fx");
xSetEntityEffect(surf->mesh,Shader);
xSetEffectTexture(surf->mesh,"seaside",seaside_tex);
xSetEffectTexture(surf->mesh,"lgrass",lgrass_tex);
xSetEffectTexture(surf->mesh,"dgrass",dgrass_tex);
xSetEffectTexture(surf->mesh,"plain",plain_tex);
xSetEffectTexture(surf->mesh,"lmountain",lmountain_tex);
xSetEffectTexture(surf->mesh,"mmountain",mmountain_tex);
xSetEffectTexture(surf->mesh,"hmountain",hmountain_tex);
xSetEffectTexture(surf->mesh,"smountain",smountain_tex);
xSetEffectTexture(surf->mesh,"rockn",rock_tex);
xSetEffectTechnique(surf->mesh, "Diffuse");
xSetEffectFloat(surf->mesh,"scale",0.3);
xSetEntityEffect(surfm->mesh,Shader);
xSetEffectTexture(surfm->mesh,"seaside",seaside_tex);
xSetEffectTexture(surfm->mesh,"lgrass",lgrass_tex);
xSetEffectTexture(surfm->mesh,"dgrass",dgrass_tex);
xSetEffectTexture(surfm->mesh,"plain",plain_tex);
xSetEffectTexture(surfm->mesh,"lmountain",lmountain_tex);
xSetEffectTexture(surfm->mesh,"mmountain",mmountain_tex);
xSetEffectTexture(surfm->mesh,"hmountain",hmountain_tex);
xSetEffectTexture(surfm->mesh,"smountain",smountain_tex);
xSetEffectTexture(surfm->mesh,"rockn",rock_tex);
xSetEffectTechnique(surf->mesh, "Diffuse");
xSetEffectFloat(surf->mesh,"scale",0.3);
}
А ведь на глаз разницы нету.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
27.10.2011, 00:32
|
#183
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: Странное.
А ведь на глаз разницы нету.
Ох.. а ещё бывает проведёшь "ацкую" оптимизацию: убьёшь день-два на рефакторинг и иные реализации. Причём всё сделаешь так, что новый супералгоритм будет выдавать такую же красивую картинку как и предшествующий супер-шейдер-мультитекстур-дот-паралакс-бампинг, но быстрее в несколько раз / без юзания внешних библиотек / со стабильным фпс / код мультиплатформенный / код сверхуниверсальный (нужное подчеркнуть).
Сторонний наблюдатель посмотрит-посмотрит, и скажет так, с пренебрежением:
- мндээ - ну и что ты два дня делал?!
По коду мельком:
- лучше в объявлении класса писать только пропиты* методов;
- в методах, при обращении к членам класса, лучше использовать синтаксис this->
это:
+убирает неоднозначность при совпадении имён (можешь дать аргументам адекватные имена x,y,z);
+большинство IDE будет подсказывать (выводить список) членов класса: меньше опечаток и загруженности человеку;
+код более нагляден.
апд: * - прототипы имелось в виду, вот так опечатка
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо impersonalis за это полезное сообщение:
|
|
27.10.2011, 23:52
|
#184
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Игрался с чужими картинками и нормалями, захотелось сделать генератор бесшовных текстур плавно изменяющегося градиента независимо для трех каналов цвета. Причем, чтобы он от 0.5 рисовал в обе стороны
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
|
|
28.10.2011, 20:53
|
#185
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Написал генератор отклонения нормали от нормального положения для шейдераф. Бесшовный. Быстрый относительно. С настройками.
int ARGB (int a,int r,int b, int g){
int color=(a<<24)+(r<<16)+(b<< +g;
return color;
}
//генератор градиентного трехканального шума
Handle GrimMagicPikcha(int size, double sharp, int seed){
xSeedRnd(seed);
//создается массив для значений
double **m0[size+1];
for(int i=0;i<=size;i++){m0[i]= new double*[size+1];}
for(int i=0;i<=size;i++){
for(int j=0;j<=size;j++){
m0[i][j]= new double[3];}}
for(int k=0;k<3;k++){
for(int i=0;i<=size;i++){
for(int j=0;j<=size;j++){
m0[i][j][k]=0;
}
}
//заполнение краев случайными числами (-5;5)
m0[0][0][k]=xRnd(-5,5);
m0[size][0][k]=xRnd(-5,5);
m0[0][size][k]=xRnd(-5,5);
m0[size][size][k]=xRnd(-5,5);
int 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=m0[x0][y0][k];
double val01=m0[x0][y1][k];
double val10=m0[x1][y0][k];
double val11=m0[x1][y1][k];
if(m0[i][j][k]==0 && val00!=0 && val01!=0 && val10!=0 && val11!=0){
m0[i][j][k]=0.25*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);
m0[x0][j][k]=0.5*(val00+val01)+0.5*step*xRnd(-sharp,sharp);
m0[x1][j][k]=0.5*(val10+val11)+0.5*step*xRnd(-sharp,sharp);
m0[i][y0][k]=0.5*(val00+val10)+0.5*step*xRnd(-sharp,sharp);
m0[i][y1][k]=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(m0[i][j][k]>=max){max=m0 [i][j][k];}
if(m0[i][j][k]<=min){min=m0 [i][j][k];}
}
}
double length=max-min;
for (int i=0;i<=size;i++){
for (int j=0;j<=size;j++){
m0[i][j][k]=(m0 [i][j][k]-min)/length;
}
}
}
//*************************************
//дальше вывод значений
Handle tex=xCreateTexture(size,size);
xSetBuffer(xTextureBuffer(tex));
xLockBuffer(xTextureBuffer(tex));
for (int i=0;i<size;i++){
for (int j=0;j<size;j++){
double val0=m0 [i][j][0];
double val1=m0 [i][j][1];
double val2=m0 [i][j][2];
xWritePixelFast(i,j,ARGB(255,val0*255,val1*255,val 2*255),xTextureBuffer(tex));
}
}
xSetBuffer(xBackBuffer());
xUnlockBuffer(xTextureBuffer(tex));
return tex;
}
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
29.10.2011, 15:25
|
#186
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Как очень легко накодил це:
class base_point{
public:
int x;
int y;
float val;
};
class temp_data{
public:
//вес и index
float w0;
int v0;
float w1;
int v1;
float w2;
int v2;
float w3;
int v3;
//конструктор задающий нули в поля
temp_data(){
w0=0;
v0=0;
w1=0;
v1=0;
w2=0;
v2=0;
w3=0;
v3=0;
}
};
class map_matrix{
public:
int size;
//массив базовых точек
base_point *mas;
//массив для временных значений
temp_data **temp;
//результирующий граиент значений
float **result;
//текстура
Handle tex;
map_matrix(int a){
size=a;
//число базовых точек
int number=150;
mas=new base_point[number];
//запись в точки
for(int i=0;i<number;i++){
mas[i].val=xRnd(-5,5);
mas[i].x=xRand(0,size);
mas[i].y=xRand(0,size);}
temp=new temp_data*[size+1];
for(int i=0;i<=size;i++){temp[i]=new temp_data[size+1];}
//вычисление максимальной дистанции
float dist0=size*sqrt(2.0);
for(int i=0;i<=size;i++){
for(int j=0;j<=size;j++){
//индексы с предельными значениями весов
int i0,i1,i2,i3;
float we0=0;
float we1=0;
float we2=0;
float we3=0;
for(int k=0;k<number;k++){
int x=mas[k].x;
int y=mas[k].y;
float dist=sqrt((x-i)*(x-i)+(y-j)*(y-j));
float weight=(dist0-dist)/dist0;
//some kind of sort
if(weight>=we0){we3=we2;we2=we1;we1=we0;we0=weight; i3=i2;i2=i1;i1=i0;i0=k;}
if(weight>=we1){we3=we2;we2=we1;we1=weight;i3=i2;i2=i1;i1=k;}
if(weight>=we2){we3=we2;we2=weight;i3=i2;i2=k;}
if(weight>=we3){we3=weight;i3=k;}}
//для текущей точки i,j есть соседи
//пишем их в временную дату
temp[i][j].v0=i0;
temp[i][j].w0=we0;
temp[i][j].v1=i1;
temp[i][j].w1=we1;
temp[i][j].v2=i2;
temp[i][j].w2=we2;
temp[i][j].v3=i3;
temp[i][j].w3=we3;
}
}
//предварительная дата готова
//теперь нужно создать и посчитать итоговый массив данных
result=new float*[size+1];
for(int i=0;i<=size;i++){result[i]=new float[size+1];}
//calculations
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){
//смотрю в базовые точки
float val0=mas[temp[i][j].v0].val; float we0=temp[i][j].w0;
float val1=mas[temp[i][j].v1].val; float we1=temp[i][j].w1;
float val2=mas[temp[i][j].v2].val; float we2=temp[i][j].w2;
float val3=mas[temp[i][j].v3].val; float we3=temp[i][j].w3;
float mval=val0*we0+val1*we1+val2*we2+val3*we3;
//складываю квадраты весов.
float weights=we0+we1+we2+we3;
result[i][j]=mval/weights;
}}
//to 0,1
float min=100000;
float max=-100000;
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){
if(result[i][j]>max){max=result[i][j];}
if(result[i][j]<min){min=result[i][j];}
}}
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){
result[i][j]=(result[i][j]-min)/(max-min);
}}
//вывод в текстуру
tex=xCreateTexture(size,size);
xSetBuffer(xTextureBuffer(tex));
xLockBuffer(xTextureBuffer(tex));
for (int i=0;i<size;i++){
for (int j=0;j<size;j++){
float val0=result[i][j];
xWritePixelFast(i,j,ARGB(255,val0*255,val0*255,val0*255),xTextureBuffer(tex));
}
}
xSetBuffer(xBackBuffer());
xUnlockBuffer(xTextureBuffer(tex));
}
};
Последний раз редактировалось dsd, 29.10.2011 в 16:26.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
|
|
29.10.2011, 23:49
|
#187
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
На деревяшки чисто по форме поверхности похоже или нет?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
29.10.2011, 23:55
|
#188
|
злобный флудер
Регистрация: 10.07.2007
Сообщений: 2,585
Написано 789 полезных сообщений (для 1,476 пользователей)
|
Ответ: Странное.
На сосны.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
29.10.2011, 23:56
|
#189
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
То есть иллюзия именно бревна покрытого корой, а не просто столбов с бугристой поверхностью?
Подайте люди добрые модельку анимированную в б3д какого-нибудь гуманоида, на опыты. Чтобы была анимация ходьбы, шаги в сторону, бег и ну и рукой дрыгал угрожающе, а если еще и руками потирать сможет вообще сказка
|
(Offline)
|
|
30.10.2011, 00:55
|
#190
|
злобный флудер
Регистрация: 10.07.2007
Сообщений: 2,585
Написано 789 полезных сообщений (для 1,476 пользователей)
|
Ответ: Странное.
Вообщем - да. Попробуй на всё это дело налепить ещё фототекстуру.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
30.10.2011, 02:55
|
#191
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Странное.
Вообщем - да. Попробуй на всё это дело налепить ещё фототекстуру.
|
если детали текстуры не будет совпадать с деталяим геометрии, то фейл. тут либо процедурная текстура, либо геометрия на основе реал тексы.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
30.10.2011, 12:13
|
#192
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Ну вообще я планировал сделать цилиндр 8х8, и дальше наложить более высокого разрешения текстуру на основе которой сделать нечто вроде бампа, для рельефа, а когда есть рельеф то сама фактура коры похожа на это:
Нужно только пару параметров подобрать, мне в принципе не важна фотореалистичность.
|
(Offline)
|
|
30.10.2011, 14:41
|
#193
|
Задрот
Регистрация: 24.07.2009
Адрес: Ивановская область, г. Кинешма
Сообщений: 1,574
Написано 407 полезных сообщений (для 863 пользователей)
|
Ответ: Странное.
Похоже на сосны, но у них текстура в действительности серая. И более вытянутая вверх.
|
(Offline)
|
|
30.10.2011, 15:38
|
#194
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Дались вам эти сосны... Мож это пихты или кедры.
Кстати в чем фэйл несовпадения фототекстуры и геометрии? Я сам чето догнать не могу О_о вроде нормально даже если сильно не совпадает. Че не так должно быть?
|
(Offline)
|
|
30.10.2011, 15:57
|
#195
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Странное.
ну на кору это точно не похоже. как скалы - ок.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Mr_F_ за это полезное сообщение:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:10.
|