|
Xors3D Графический движок с поддержкой DirectX9 |
17.10.2011, 22:44
|
#121
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
шум перлина
прикола ради написал це
Handle perlin_noise(int seed, int size){
srand(seed);
int resolution=1<<size;
printf("\n resolution %d",resolution);
//создание структуры данных
double **m[size];
for(int i=0;i<size;i++){
int width=1<<(i+1);
m[i]=new double*[width];
for(int j=0;j<width;j++){m[i][j]=new double[width];}
printf("\n %d",width);
}
//заполнение структуры шумом
for(int i=0;i<size;i++){
int width=1<<(i+1);
for(int j=0;j<width;j++){for(int k=0;k<width;k++){m[i][j][k]=(1-2*(double)rand()/RAND_MAX)/(width>>1);}}}
//суммирование шума
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){
double val=0;
for(int k=0;k<size;k++){
//нулевой массив шириной 2 ячейки
int width=2<<k;
double vi=width*i/resolution;// что оно мне считает? О_о
double hi=width*j/resolution;// что оно мне считает? О_о
//так индексы
int x0=floor(vi);
int x1=ceil(vi);
double deltax=vi-x0;
int y0=floor(hi);
int y1=ceil(hi);
double deltay=hi-y0;
//теперь вычисление приближенного значения
//косяк тута в формуле.
val=val+((m[k][x0][y0]*deltax+m[k][x1%width][y0]*(1-deltax))*deltay+(m[k][x0][y1%width]*deltax+m[k][x1%width][y1%width]*(1-deltax))*(1-deltay));
}
m[size-1][i][j]=val; }}
//приведение в интервал (0,1)
double min=100000.01;
double max=-100000.01;
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){
if(m[size-1][i][j]>max){max=m[size-1][i][j];}
if(m[size-1][i][j]<min){min=m[size-1][i][j];}
}}
double length=max-min;
for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){
m[size-1][i][j]=(m[size-1][i][j]-min)/length;
}}
//рисование текстуры
Handle tex=xCreateTexture(resolution,resolution);
xSetBuffer(xTextureBuffer(tex));
xLockBuffer(xTextureBuffer(tex));
for (int i=0;i<resolution;i++){
for (int j=0;j<resolution;j++){
double val=pow(m[size-1][i][j],2);
xWritePixelFast(i,j,ARGB(255,255*val,255*val,255*val),xTextureBuffer(tex));}}
xSetBuffer(xBackBuffer());
xUnlockBuffer(xTextureBuffer(tex));
return tex;
}
пошел курить алгоритмы сглаживания
)
результат обоих кусков идентичен, а вот время различается сильно
val=val+((m[k][x0][y0]*deltax+m[k][x1%width][y0]*(1-deltax))*deltay+(m[k][x0][y1%width]*deltax+m[k][x1%width][y1%width]*(1-deltax))*(1-deltay));
//можно посчитать четыре прямые через вершины и усреднить итоговую сумму.
/*double val00=m[k][x0][y0];
double val01=m[k][x1%width][y0];
double val10=m[k][x0][y1%width];
double val11=m[k][x1%width][y1%width];*/
//вычисление точек на краях, точка может быть вне границы квадрата, но это пох.
//прямая через две точки
// |x2-x1 y2-y1|
// |x -x1 y -y1|=0
// уравнение прямой (x2-x1)(y-y1)-(x-x1)(y2-y1)=0
//y=x(y2-y1)/(x2-x1)+y1-x1(y2-y1)/(x2-x1)
//точка 0,0 и deltax,deltay ищу точку на этой прямой с координатой x=1
double x=1;
double x1=0;
double y1=0;
double x2=deltax;
double y2=deltay;
double y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
int ymin=floor(y);
int ymax=ceil(y);
double val00=(m[k][x00][ymin%width]*(ymax-ymin)+m[k][x00][ymax%width]*(1-ymax+ymin)-m[k][x00][y00])*deltax+m[k][x00][y00];
//точка 0,1 и deltax,deltay ищу точку на этой прямой с координатой x=1
x=1;
x1=0;
y1=1;
y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
//индекс у значений x01 а игрек
ymin=floor(y);
ymax=ceil(y);
double val01=(m[k][x10][ymin%width]*(ymax-ymin)+m[k][x10][ymax%width]*(1-ymax+ymin)-m[k][x00][y10])*deltax+m[k][x00][y10];
//точка 1,0 и deltax,deltay ищу точку на этой прямой с координатой x=0
x=0;
x1=1;
y1=0;
y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
ymin=floor(y);
ymax=ceil(y);
double val10=(m[k][x00][ymin%width]*(ymax-ymin)+m[k][x00][ymax%width]*(1-ymax+ymin)-m[k][x10][y00])*(1-deltax)+m[k][x10][y00];
//точка 1,1 и deltax,deltay ищу точку на этой прямой с координатой x=0
x=0;
x1=1;
y1=1;
y=x*(y2-y1)/(x2-x1)+y1-x1*(y2-y1)/(x2-x1);
ymin=floor(y);
ymax=ceil(y);
double val11=(m[k][x10][ymin%width]*(ymax-ymin)+m[k][x10][ymax%width]*(1-ymax+ymin)-m[k][x10][y10])*(1-deltax)+m[k][x10][y10];
//прямая через две точки
// |x2-x1 y2-y1|
// |x -x1 y -y1|=0
// уравнение прямой (x2-x1)(y-y1)-(x-x1)(y2-y1)=0
//y*(x2-x1)=x(y2-y1)+y1*(x2-x1)-x1(y2-y1)
//x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1)
//точка 0,0 и deltax,deltay ищу точку на этой прямой с координатой y=1
y=1;
x1=0;
y1=0;
x2=deltax;
y2=deltay;
x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
ymin=floor(x);
ymax=ceil(x);
double val100=(m[k][ymin%width][y00]*(ymax-ymin)+m[k][ymax%width][y00]*(1-ymax+ymin)-m[k][x00][y00])*deltay+m[k][x00][y00];
//точка 0,1 и deltax,deltay ищу точку на этой прямой с координатой y=1
y=1;
x1=0;
y1=1;
x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
//индекс у значений x01 а игрек
ymin=floor(y);
ymax=ceil(y);
double val101=(m[k][ymin%width][y10]*(ymax-ymin)+m[k][ymax%width][y10]*(1-ymax+ymin)-m[k][x00][y10])*(1-deltay)+m[k][x00][y10];
//точка 1,0 и deltax,deltay ищу точку на этой прямой с координатой x=0
y=0;
x1=1;
y1=0;
x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
ymin=floor(y);
ymax=ceil(y);
double val110=(m[k][ymin%width][y00]*(ymax-ymin)+m[k][ymax%width][y00]*(1-ymax+ymin)-m[k][x10][y00])*deltay+m[k][x10][y00];
//точка 1,1 и deltax,deltay ищу точку на этой прямой с координатой x=0
y=0;
x1=1;
y1=1;
x=y1*(x2-x1)/(y2-y1)-x1-y*(x2-x1)/(y2-y1);
ymin=floor(y);
ymax=ceil(y);
double val111=(m[k][ymin%width][y10]*(ymax-ymin)+m[k][ymax%width][y10]*(1-ymax+ymin)-m[k][x10][y10])*(1-deltay)+m[k][x10][y10];
//сумма
val=val+0.125*(val00+val01+val10+val11+val100+val101+val110+val111);
Последний раз редактировалось dsd, 13.12.2011 в 22:59.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
|
|
18.10.2011, 14:29
|
#122
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Накурился. Походу то что мне хочется это нетривиальная задача, надо сочинять нечто типа растеризации только в четырехугольнике и по парабалам или корню от исходных данных. Кстати шум перлина должен замечательно получится шейдером ибо механизм вычисления координаты в текстурах шума разных октав и размероа я сочинил, а растеризация реализована вроде железом.
|
(Offline)
|
|
18.10.2011, 15:04
|
#123
|
Мастер
Регистрация: 09.05.2010
Адрес: Самара
Сообщений: 1,083
Написано 254 полезных сообщений (для 533 пользователей)
|
Ответ: Странное.
Сообщение от dsd
Накурился. Походу то что мне хочется это нетривиальная задача, надо сочинять нечто типа растеризации только в четырехугольнике и по парабалам или корню от исходных данных. Кстати шум перлина должен замечательно получится шейдером ибо механизм вычисления координаты в текстурах шума разных октав и размероа я сочинил, а растеризация реализована вроде железом.
|
а это вообще зачем? ландшафт генерить?
|
(Offline)
|
|
18.10.2011, 23:09
|
#124
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Сообщение от pozitiffcat
а это вообще зачем? ландшафт генерить?
|
В принципе для любой природной хрени нужен минимально обработанный шум, потому как с обычным rand() получается плохой результат. Даймонд сквэйр дает все-таки результат больше похожий на пожамканную газету, зато резкий причем мою его реализацию можно еще ускорить раз в ацать там где-то затесались лишние проходы
Нагавнокодил таки простейший шум перлина с простым растеризатором.
Говнокод это когда знаешь как сделать быстрей, но сделаешь так только за деньги?
!!текстура 2^size x 2^size не надо туда ставить больших значений!!
//*********************************** int ARGB (int a,int r,int b, int g){ int color=(a<<24)+(r<<16)+(b<<8)+g; return color; }
//*********************************** Handle perlin_noise(int seed, int size){ srand(seed); int resolution=1<<size; printf("\n resolution %d",resolution); //создание структуры данных double **m[size]; for(int i=0;i<size;i++){ int width=1<<(i+1); m[i]=new double*[width]; for(int j=0;j<width;j++){m[i][j]=new double[width];} printf("\n %d",width); } //заполнение структуры шумом for(int i=0;i<size;i++){ int width=1<<(i+1); for(int j=0;j<width;j++){for(int k=0;k<width;k++){ //double kof=(size-i); /* if(i==0){kof=4.01;} if(i==1){kof=2.51;} if(i==2){kof=1.51;} if(i==3){kof=2.01;} if(i==4){kof=1.41;} if(i==5){kof=0.51;}*/ m[i][j][k]=(1-2*(double)rand()/RAND_MAX);}}} //теперь семь одинаковых массивов максимального размера double **m1[size]; for(int i=0;i<size;i++){ int width=resolution; m1[i]=new double*[width]; for(int j=0;j<width;j++){m1[i][j]=new double[width];} } //обнуление 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;}}} //***************************************************** //надо прописать весь шум в блок растеризации for(int i=0;i<size;i++){ int width=1<<(i+1); for(int j=0;j<width;j++){for(int k=0;k<width;k++){
m1[i][j<<(size-i-1)][k<<(size-i-1)]=m[i][j][k];}}} //***************************************************** for(int k=0;k<size;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){
double val00=m1[k][i-step][j-step]; double val01=m1[k][i-step][j+step]; double val10=m1[k][i+step][j-step]; double val11=m1[k][i+step][j+step];
if(m1[k][i][j]==0 && val00!=0 && val01!=0 && val10!=0 && val11!=0){m1[k][i][j]=0.25*(val00+val01+val10+val11);} if(m1[k][i-step][j]==0 && val00!=0 && val01!=0){m1[k][i-step][j]=0.5*(val00+val01);} if(m1[k][i+step][j]==0 && val10!=0 && val11!=0){m1[k][i+step][j]=0.5*(val10+val11);} if(m1[k][i][j-step]==0 && val00!=0 && val10!=0){m1[k][i][j-step]=0.5*(val00+val10);} if(m1[k][i][j+step]==0 && val01!=0 && val11!=0){m1[k][i][j+step]=0.5*(val01+val11);} } } step=step>>1;} } //***************************************************** //создание массива для суммы значений double **m0=new double*[resolution]; for(int j=0;j<resolution;j++){m0[j]=new double[resolution];}
//суммирование for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){ double val=0; for(int k=0;k<size;k++){val=val+m1[k][i][j];}
m0[i][j]=val; }} //приведение в интервал (0,1) double min=100000.01; double max=-100000.01; for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){ if(m0[i][j]>max){max=m0[i][j];} if(m0[i][j]<min){min=m0[i][j];} }} double length=max-min; for(int i=0;i<resolution;i++){for(int j=0;j<resolution;j++){ m0[i][j]=(m0[i][j]-min)/length; }} //рисование текстуры Handle tex=xCreateTexture(resolution,resolution); xSetBuffer(xTextureBuffer(tex)); xLockBuffer(xTextureBuffer(tex)); for (int i=0;i<resolution;i++){ for (int j=0;j<resolution;j++){ double val=pow(m0[i][j],2); xWritePixelFast(i,j,ARGB(255,255*val,255*val,255*val),xTextureBuffer(tex));/* int red=0; int green=0; int blue=0; if(val<=0.25) {blue=(1-val)*255; green=125*(1-val);red=0;} else { if(val>=0.6) {red=255*val; green=120*val;blue=0;} else{red=255*val; green=255*val;blue=0;}} xWritePixelFast(i,j,ARGB(255,red,green,blue),xTextureBuffer(tex));*/
}} xSetBuffer(xBackBuffer()); xUnlockBuffer(xTextureBuffer(tex));
return tex;
}
А че принтф это оооочень тормазная ф-ция?
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
|
|
18.10.2011, 23:58
|
#125
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
слегка улучшенный алгоритм
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
19.10.2011, 00:11
|
#126
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Сравнение двух алгоритмов
слева перлин справа даймонд размер текстур идентичный 512 х 512
на пробел новые текстуры.
Результат какого алгоритма красивше?
Зы. Почитал статьи как делать шум перлина на гамдеве. Я походу какой-то адовый кодило, ни мат обоснования, ни возведений в хрензнаеткакую степень с корнем. никахих функций напоминающих гаусинный блюр. Короче это не шум перлина, хоть и выглядит также :D
Последний раз редактировалось dsd, 23.10.2011 в 22:17.
|
(Offline)
|
|
19.10.2011, 12:07
|
#127
|
Мастер
Регистрация: 09.05.2010
Адрес: Самара
Сообщений: 1,083
Написано 254 полезных сообщений (для 533 пользователей)
|
Ответ: Странное.
Сообщение от dsd
А че принтф это оооочень тормазная ф-ция?
|
нет, но лучше в c++ использовать поток cout;
cout << "mystr" << intvar << floatvar << endl;
|
(Offline)
|
|
19.10.2011, 12:08
|
#128
|
Мастер
Регистрация: 09.05.2010
Адрес: Самара
Сообщений: 1,083
Написано 254 полезных сообщений (для 533 пользователей)
|
Ответ: Сравнение двух алгоритмов
Сообщение от dsd
Результат какого алгоритма красивше?
Зы. Почитал статьи как делать шум перлина на гамдеве. Я походу какой-то адовый кодило, ни мат обоснования, ни возведений в хрензнаеткакую степень с корнем. никахих функций напоминающих гаусинный блюр. Короче это не шум перлина, хоть и выглядит также :D
|
слева круче.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
19.10.2011, 16:46
|
#129
|
Бывалый
Регистрация: 16.09.2009
Адрес: Sun system
Сообщений: 831
Написано 442 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
У левого здоровецкие материки выходят. А у правого архипелаги. Каждый хорош в своем.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
19.10.2011, 20:14
|
#130
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
Привел шум в более приличный вид и ускорил его до почти приемлемого уровня, но он все равно пока медленней даймонда в size раз.
Handle perlin_noise(int seed, int size){
srand(seed);
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 kof=(size-i);
if(i==0){kof=8.01;}
if(i==1){kof=4.51;}
if(i==2){kof=2.51;}
if(i==3){kof=1.01;}
if(i==4){kof=0.81;}
if(i==5){kof=0.51;}
if(i>5){kof=0.24;}
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];}m1[size-1][i][j]=(m1[size-1][i][j]+length)*len;}}
//рисование текстуры
Handle tex=xCreateTexture(resolution,resolution);
xSetBuffer(xTextureBuffer(tex));
xLockBuffer(xTextureBuffer(tex));
for (int i=0;i<resolution;i++){
for (int j=0;j<resolution;j++){
float val=pow(m1[size-1][i][j],2);
int red,green,blue;
if(val<=0.25) {blue=(1-val)*255; green=125*(1-val);red=0;} //цвет моря
else {if(val>=0.5) {red=205*val; green=120*val;blue=70;} //цвет гор
else{red=255*val; green=255*val;blue=0;}} //цвет от побережья до предгорий
xWritePixelFast(i,j,(255<<24)+(red<<16)+(green<<8)+blue,xTextureBuffer(tex));}}
xSetBuffer(xBackBuffer());
xUnlockBuffer(xTextureBuffer(tex));
return tex;}
|
|
(Offline)
|
|
20.10.2011, 01:00
|
#131
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
примерно 30-40% от планируемого класса фпс 350 при движении по диагонали, ~400 при движении параллельно осям. И сильно снизиться уже не должен
class ground{
//текущая позиция камеры
int x,y;
//***************************************
//меш прикидывающийся детализированным ландшафтам с лодами.
Handle mesh;
//его поверхности ближнего плана
Handle **surf;
//среднего плана
Handle **surfm;
//дальнего плана
// разрешение наиболее детализировнных ячеек.
int resolution;
// разрешение клеток средней детализации
int resol;
int number;
//data for deformations
//хранитель мирового зерна.
int uppersize;
float **seed;
int grain;
//массивы билжнего плана.
float ****strip;
//массивы среднего плана.
float ****stripm;
//шершавость нижнего уровня
float sharpness;
//сглживание
float smothing;
//нижняя точка всего ландшафта
float minimum;
//высота ландшафта
float height;
//******************************************
public:
//конструктор класса
ground(){
//position intitilazer
x=xEntityX(Pivot);
y=xEntityZ(Pivot);
//Mesh creation
mesh=xCreateMesh();
xEntityFX(mesh,2);
xPositionEntity(mesh,x,0,y);
//surface for mesh
//создание ближнего квадрата
number=6;
resolution=32;
sharpness=0.17f;
smothing=3;
minimum=1000.4f;
//ближний план
surf=new Handle*[number];
for(int i=0;i<number;i++){surf[i]=new Handle[number];}
for(int i=0;i<number;i++){for(int j=0;j<number;j++){surf[i][j]=xCreateSurface(mesh);C_Plane(surf[i][j],resolution,resolution*(i-number*0.5f),resolution*(j-number*0.5f));}}
//генерация мирового зерна
uppersize=4*128;
grain=xMillisecs();
First_Generator(uppersize,5.1f,3,50);
//структура данных ближнего плана
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);}}
for(int i=0;i<number;i++){for(int j=0;j<number;j++){Surface_Monolitizer(i,j);}}
//структура данных среднего плана
resol=resolution/4;
//средний план
surfm=new Handle*[3*number];
for(int i=0;i<3*number;i++){surfm[i]=new Handle[3*number];}
for(int i=0;i<3*number;i++){for(int j=0;j<3*number;j++){
surfm[i][j]=xCreateSurface(mesh);C_Plane_m(surfm[i][j],resol,resolution*(i-1.5f*number),resolution*(j-1.5f*number));
}}
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,sharpness, smothing);}}
for(int i=0;i<3*number;i++){for(int j=0;j<3*number;j++){Surface_Monolitizerm(i,j);}}
//*******************************************
xCalculateFrustumVolume(mesh);
}
//***************************************************
void update(){
//position intitilazer
int xc=xEntityX(Pivot);
int yc=xEntityZ(Pivot);
if(xc-resolution-1>x){x=x+resolution;Data_Switcher(0);Surface_Switcher(0);Data_Switcherm(0);Surface_Switcherm(0);xCalculateFrustumVolume(mesh);}
if(xc+resolution+1<x){x=x-resolution;Data_Switcher(1);Surface_Switcher(1);Data_Switcherm(1);Surface_Switcherm(1);xCalculateFrustumVolume(mesh);}
if(yc-resolution-1>y){y=y+resolution;Data_Switcher(2);Surface_Switcher(2);Data_Switcherm(2);Surface_Switcherm(2);xCalculateFrustumVolume(mesh);}
if(yc+resolution+1<y){y=y-resolution;Data_Switcher(3);Surface_Switcher(3);Data_Switcherm(3);Surface_Switcherm(3);xCalculateFrustumVolume(mesh);}
//Создать давилку для среднего под ближним
//Создать давилку для дальнего под средним
}
//***************************************************
//***************************************************
//***************************************************
void Surface_Monolitizer(int a,int b){
float m[3][4];
for(int i=0;i<=resolution;i++){for(int j=0;j<=resolution;j++){
//вычисляю индекс вершины
int index=i*(resolution+1)+j;
//первая нормаль
int x1=-1; int z1=0;
int x2=0; int z2=1;
float y0=strip[a+1][b+1][i][j];
float y1;
if(i==0){y1=strip[a][b+1][i+x1+resolution][j+z1];} else{y1=strip[a+1][b+1][i+x1][j+z1];}
float y2;
if(j==resolution){y2=strip[a+1][b+2][i+x2][j+z2-resolution];} else{y2=strip[a+1][b+1][i+x2][j+z2];}
//x's
m[0][0]=y1-y0;
//y's
m[1][0]=-1;
//z's
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resolution){y1=strip[a+1][b+2][i+x1][j+z1-resolution];} else{y1=strip[a+1][b+1][i+x1][j+z1];}
if(i==resolution){y2=strip[a+2][b+1][i+x2-resolution][j+z2];} else{y2=strip[a+1][b+1][i+x2][j+z2];}
//x's
m[0][1]=y0-y2;
//y's
m[1][1]=-1;
//z's
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resolution) {y1=strip[a+2][b+1][i+x1-resolution][j+z1];} else{y1=strip[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=strip[a+1][b][i+x2][j+z2+resolution];} else{y2=strip[a+1][b+1][i+x2][j+z2];}
//x's
m[0][2]=y0-y1;
//y's
m[1][2]=-1;
//z's
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=strip[a+1][b][i+x1][j+z1+resolution];} else{y1=strip[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=strip[a][b+1][i+x2+resolution][j+z2];} else{y2=strip[a+1][b+1][i+x2][j+z2];}
//x's
m[0][3]=y2-y0;
//y's
m[1][3]=-1;
//z's
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]);
//вершино переставлялко
//*****************************
if(y0>=0){xVertexCoords(surf[a][b],index,xVertexX(surf[a][b],index),y0*y0*0.03f,xVertexZ(surf[a][b],index));}
if(y0<0){xVertexCoords(surf[a][b],index,xVertexX(surf[a][b],index),-y0*y0*0.03f,xVertexZ(surf[a][b],index));}
//****************************
xVertexNormal(surf[a][b],index,m[0][0],m[1][0],m[2][0]);
xVertexColor(surf[a][b],index,127,89,63);
//*******************************************
//раскрас поверхности
//*******************************************
//y0=y0*3;
//xVertexColor(surf[a][b],index,y0,y0+70,y0-70);
//морское дно глубже 2
if(y0<=-2){xVertexColor(surf[a][b],index,95,75,55);}
//песок 255,255,125 на побережье
if(fabs(y0)<2){xVertexColor(surf[a][b],index,255,238+xRnd(-15,15),89+xRnd(-15,15));}
if(y0>=2 && y0<5){xVertexColor(surf[a][b],index,192+xRnd(-15,15),255,109+xRnd(-15,15));}
if(y0>=5+xRnd(-0.5,0.5) && y0<10+xRnd(-1,1)){xVertexColor(surf[a][b],index,100+xRnd(-15,15),255,63+xRnd(-15,15));}
if(y0>=10+xRnd(-1,1) && y0<60+xRnd(-1,1)){xVertexColor(surf[a][b],index,0+xRnd(-15,15),127+xRnd(-15,15),40+xRnd(-15,15));}
//снег на двадцать единиц ниже пиков
if(y0>90+xRnd(-3,3)){xVertexColor(surf[a][b],index,255,255,255);}
}}
}
//***************************************************
void Surface_Monolitizerm(int a,int b){
float m[3][4];
for(int i=0;i<=resol;i++){for(int j=0;j<=resol;j++){
//вычисляю индекс вершины
int index=i*(resol+1)+j;
//первая нормаль
int x1=-1; int z1=0;
int x2=0; int z2=1;
float y0=stripm[a+1][b+1][i][j];
//вершино переставлялко
//*****************************
int delta=0;
if(y0>=0){xVertexCoords(surfm[a][b],index,xVertexX(surfm[a][b],index),y0*y0*0.03f,xVertexZ(surfm[a][b],index));}
if(y0<0){xVertexCoords(surfm[a][b],index,xVertexX(surfm[a][b],index),-y0*y0*0.03f,xVertexZ(surfm[a][b],index));}
//если a>
float y1;
if(i==0){y1=stripm[a][b+1][i+x1+resol][j+z1];} else{y1=stripm[a+1][b+1][i+x1][j+z1];}
float y2;
if(j==resol){y2=stripm[a+1][b+2][i+x2][j+z2-resol];} else{y2=stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][0]=y1-y0;
//y's
m[1][0]=-1;
//z's
m[2][0]=y0-y2;
//вторая нормаль
x1=0; z1=1;
x2=1; z2=0;
if(j==resol){y1=stripm[a+1][b+2][i+x1][j+z1-resol];} else{y1=stripm[a+1][b+1][i+x1][j+z1];}
if(i==resol){y2=stripm[a+2][b+1][i+x2-resol][j+z2];} else{y2=stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][1]=y0-y2;
//y's
m[1][1]=-1;
//z's
m[2][1]=y0-y1;
//третья нормаль
x1=1; z1=0;
x2=0; z2=-1;
if(i==resol) {y1=stripm[a+2][b+1][i+x1-resol][j+z1];} else{y1=stripm[a+1][b+1][i+x1][j+z1];}
if(j==0) {y2=stripm[a+1][b][i+x2][j+z2+resol];} else{y2=stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][2]=y0-y1;
//y's
m[1][2]=-1;
//z's
m[2][2]=y2-y0;
//четвертая нормаль
x1=0; z1=-1;
x2=-1; z2=0;
if(j==0){y1=stripm[a+1][b][i+x1][j+z1+resol];} else{y1=stripm[a+1][b+1][i+x1][j+z1];}
if(i==0){y2=stripm[a][b+1][i+x2+resol][j+z2];} else{y2=stripm[a+1][b+1][i+x2][j+z2];}
//x's
m[0][3]=y2-y0;
//y's
m[1][3]=-1;
//z's
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]);
//****************************
xVertexNormal(surfm[a][b],index,m[0][0],m[1][0],m[2][0]);
xVertexColor(surfm[a][b],index,127,89,63);
//*******************************************
//раскрас поверхности
//*******************************************
//y0=y0*3;
//xVertexColor(surf[a][b],index,y0,y0+70,y0-70);
//морское дно глубже 2
if(y0<=-2){xVertexColor(surfm[a][b],index,95,75,55);}
//песок 255,255,125 на побережье
if(fabs(y0)<2){xVertexColor(surfm[a][b],index,255,238+xRnd(-15,15),89+xRnd(-15,15));}
if(y0>=2 && y0<5){xVertexColor(surfm[a][b],index,192+xRnd(-15,15),255,109+xRnd(-15,15));}
if(y0>=5+xRnd(-0.5,0.5) && y0<10+xRnd(-1,1)){xVertexColor(surfm[a][b],index,100+xRnd(-15,15),255,63+xRnd(-15,15));}
if(y0>=10+xRnd(-1,1) && y0<60+xRnd(-1,1)){xVertexColor(surfm[a][b],index,0+xRnd(-15,15),127+xRnd(-15,15),40+xRnd(-15,15));}
//снег на двадцать единиц ниже пиков
if(y0>90+xRnd(-3,3)){xVertexColor(surfm[a][b],index,255,255,255);}
}}
}
//****************************************
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,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,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,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,sharpness,smothing);}}
}
//****************************************
void Surface_Switcher(int flag){
//do not touch this, never ever.
Handle temp[number];
if(flag==0){ for(int i=0;i<number;i++){temp[i]=surf[0][i];
for(int k=0;k<number-1;k++) {surf[k][i]=surf[k+1][i];}
surf[number-1][i]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j)+number*resolution,xVertexY(temp[i],j),xVertexZ(temp[i],j));}}
for(int i=0;i<number;i++){Surface_Monolitizer(number-1,i);}}
if(flag==1){ for(int i=0;i<number;i++){temp[i]=surf[number-1][i];
for(int k=number-1;k>0;k--) {surf[k][i]=surf[k-1][i];}
surf[0][i]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j)-number*resolution,xVertexY(temp[i],j),xVertexZ(temp[i],j));}}
for(int i=0;i<number;i++){
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Surface_Monolitizer(0,i);}}
if(flag==2){ for(int i=0;i<number;i++){temp[i]=surf[i][0];
for(int k=0;k<number-1;k++) {surf[i][k]=surf[i][k+1];}
surf[i][number-1]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j),xVertexY(temp[i],j),xVertexZ(temp[i],j)+number*resolution);}}
for(int i=0;i<number;i++){Surface_Monolitizer(i,number-1);}}
if(flag==3){ for(int i=0;i<number;i++){temp[i]=surf[i][number-1];
for(int k=number-1;k>0;k--) {surf[i][k]=surf[i][k-1];}
surf[i][0]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j),xVertexY(temp[i],j),xVertexZ(temp[i],j)-number*resolution);}}
for(int i=0;i<number;i++){
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Surface_Monolitizer(i,0);}}
}
//****************************************
void Surface_Switcherm(int flag){
//do not touch this, never ever.
Handle temp[3*number];
if(flag==0){ for(int i=0;i<3*number;i++){temp[i]=surfm[0][i];
for(int k=0;k<3*number-1;k++) {surfm[k][i]=surfm[k+1][i];}
surfm[3*number-1][i]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j)+3*number*resolution,xVertexY(temp[i],j),xVertexZ(temp[i],j));}}
for(int i=0;i<3*number;i++){Surface_Monolitizerm(3*number-1,i);}}
if(flag==1){ for(int i=0;i<3*number;i++){temp[i]=surfm[3*number-1][i];
for(int k=3*number-1;k>0;k--) {surfm[k][i]=surfm[k-1][i];}
surfm[0][i]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j)-3*number*resolution,xVertexY(temp[i],j),xVertexZ(temp[i],j));}}
for(int i=0;i<3*number;i++){
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Surface_Monolitizerm(0,i);}}
if(flag==2){ for(int i=0;i<3*number;i++){temp[i]=surfm[i][0];
for(int k=0;k<3*number-1;k++) {surfm[i][k]=surfm[i][k+1];}
surfm[i][3*number-1]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j),xVertexY(temp[i],j),xVertexZ(temp[i],j)+3*number*resolution);}}
for(int i=0;i<3*number;i++){Surface_Monolitizerm(i,3*number-1);}}
if(flag==3){ for(int i=0;i<3*number;i++){temp[i]=surfm[i][3*number-1];
for(int k=3*number-1;k>0;k--) {surfm[i][k]=surfm[i][k-1];}
surfm[i][0]=temp[i];
int qvert=xCountVertices(temp[i]);
for(int j=0;j<qvert;j++){xVertexCoords(temp[i],j,xVertexX(temp[i],j),xVertexY(temp[i],j),xVertexZ(temp[i],j)-3*number*resolution);}}
for(int i=0;i<3*number;i++){
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Surface_Monolitizerm(i,0);}}
}
//---------------------------------------------------
Handle C_Plane(Handle surf,int resolution, int posx, int posy){
for(int i=0;i<=resolution;i++){for(int j=0;j<=resolution;j++){int v0=xAddVertex(surf,i+posx,0,j+posy,i+posx,j+posy);xVertexNormal(surf,v0,0,1,0);}}
int qvert=xCountVertices(surf);
for(int i=0;i<qvert-resolution-1;i++){int v0=i; int v1=i+1; int v2=i+resolution+1; int v3=v2+1;
if(v3<qvert && xMod(i,resolution+1)!=resolution){xAddTriangle(surf,v2,v1,v3); xAddTriangle(surf,v2,v0,v1);}}
return surf;}
//----------------------------------------------------
Handle C_Plane_m(Handle surf,int resol, int posx, int posy){
for(int i=0;i<=resol;i++){for(int j=0;j<=resol;j++){int v0=xAddVertex(surf,i*4+posx,0,j*4+posy,i*4+posx,j*4+posy);xVertexNormal(surf,v0,0,1,0);}}
int qvert=xCountVertices(surf);
for(int i=0;i<qvert-resol-1;i++){int v0=i; int v1=i+1; int v2=i+resol+1; int v3=v2+1;
if(v3<qvert && xMod(i,resol+1)!=resol){xAddTriangle(surf,v2,v1,v3); xAddTriangle(surf,v2,v0,v1);}}
return surf;}
//---------------------------------------------------
//----------------------------------------------------
//*******************************************************
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];}
}
//заполнение краев
if(strip[a][b][0][0]==0){ strip[a][b][0][0]=seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b,uppersize)];}
if(strip[a][b][size][0]==0) {strip[a][b][size][0]=seed[xMod(x/resolution+a+1,uppersize)][xMod(y/resolution+b,uppersize)];}
if(strip[a][b][0][size]==0) {strip[a][b][0][size]=seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b+1,uppersize)];}
if(strip[a][b][size][size]==0) {strip[a][b][size][size]=seed[xMod(x/resolution+a+1,uppersize)][xMod(y/resolution+b+1,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=strip[a][b][i-step][j-step];
float val01=strip[a][b][i-step][j+step];
float val10=strip[a][b][i+step][j-step];
float val11=strip[a][b][i+step][j+step];
if(strip[a][b][i][j]==0){strip[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(strip[a][b][i-step][j]==0){strip[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(strip[a][b][i+step][j]==0){strip[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(strip[a][b][i][j-step]==0){strip[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(strip[a][b][i][j+step]==0){strip[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}
}
}
step=step>>1;}
}
//********************************************************
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];}
}
//заполнение краев
if(strip[a][b][0][0]==0){ strip[a][b][0][0]=seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b,uppersize)];}
if(strip[a][b][size][0]==0) {strip[a][b][size][0]=seed[xMod(x/resolution+a+1,uppersize)][xMod(y/resolution+b,uppersize)];}
if(strip[a][b][0][size]==0) {strip[a][b][0][size]=seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b+1,uppersize)];}
if(strip[a][b][size][size]==0) {strip[a][b][size][size]=seed[xMod(x/resolution+a+1,uppersize)][xMod(y/resolution+b+1,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=strip[a][b][i-step][j-step];
float val01=strip[a][b][i-step][j+step];
float val10=strip[a][b][i+step][j-step];
float val11=strip[a][b][i+step][j+step];
if(strip[a][b][i][j]==0){strip[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(strip[a][b][i-step][j]==0){strip[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(strip[a][b][i+step][j]==0){strip[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(strip[a][b][i][j-step]==0){strip[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(strip[a][b][i][j+step]==0){strip[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}
}
}
step=step>>1;}
}
//********************************************************
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];}
}
//заполнение краев
if(strip[a][b][0][0]==0){ strip[a][b][0][0]=seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b,uppersize)];}
if(strip[a][b][size][0]==0) {strip[a][b][size][0]=seed[xMod(x/resolution+a+1,uppersize)][xMod(y/resolution+b,uppersize)];}
if(strip[a][b][0][size]==0) {strip[a][b][0][size]=seed[xMod(x/resolution+a,uppersize)][xMod(y/resolution+b+1,uppersize)];}
if(strip[a][b][size][size]==0) {strip[a][b][size][size]=seed[xMod(x/resolution+a+1,uppersize)][xMod(y/resolution+b+1,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=strip[a][b][i-step][j-step];
float val01=strip[a][b][i-step][j+step];
float val10=strip[a][b][i+step][j-step];
float val11=strip[a][b][i+step][j+step];
if(strip[a][b][i][j]==0){strip[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(strip[a][b][i-step][j]==0){strip[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(strip[a][b][i+step][j]==0){strip[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(strip[a][b][i][j-step]==0){strip[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(strip[a][b][i][j+step]==0){strip[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}
}
}
step=step>>1;}
}
//*-**-*-*-*-*--*-*-*-*-*-*
//*******************************************************
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,uppersize)][xMod(y/resolution+b,uppersize)]);
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];}
}
//заполнение краев
if(stripm[a][b][0][0]==0){ stripm[a][b][0][0]=seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b-number,uppersize)];}
if(stripm[a][b][size][0]==0) {stripm[a][b][size][0]=seed[xMod(x/resolution+a+1-number,uppersize)][xMod(y/resolution+b-number,uppersize)];}
if(stripm[a][b][0][size]==0) {stripm[a][b][0][size]=seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b+1-number,uppersize)];}
if(stripm[a][b][size][size]==0) {stripm[a][b][size][size]=seed[xMod(x/resolution+a+1-number,uppersize)][xMod(y/resolution+b+1-number,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=stripm[a][b][i-step][j-step];
float val01=stripm[a][b][i-step][j+step];
float val10=stripm[a][b][i+step][j-step];
float val11=stripm[a][b][i+step][j+step];
if(stripm[a][b][i][j]==0){stripm[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(stripm[a][b][i-step][j]==0){stripm[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i+step][j]==0){stripm[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i][j-step]==0){stripm[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i][j+step]==0){stripm[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}
}
}
step=step>>1;}
}
//********************************************************
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];}
}
//заполнение краев
if(stripm[a][b][0][0]==0){ stripm[a][b][0][0]=seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b-number,uppersize)];}
if(stripm[a][b][size][0]==0) {stripm[a][b][size][0]=seed[xMod(x/resolution+a+1-number,uppersize)][xMod(y/resolution+b-number,uppersize)];}
if(stripm[a][b][0][size]==0) {stripm[a][b][0][size]=seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b+1-number,uppersize)];}
if(stripm[a][b][size][size]==0) {stripm[a][b][size][size]=seed[xMod(x/resolution+a+1-number,uppersize)][xMod(y/resolution+b+1-number,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=stripm[a][b][i-step][j-step];
float val01=stripm[a][b][i-step][j+step];
float val10=stripm[a][b][i+step][j-step];
float val11=stripm[a][b][i+step][j+step];
if(stripm[a][b][i][j]==0){stripm[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(stripm[a][b][i-step][j]==0){stripm[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i+step][j]==0){stripm[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i][j-step]==0){stripm[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i][j+step]==0){stripm[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}
}
}
step=step>>1;}
}
//********************************************************
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];}
}
//заполнение краев
if(stripm[a][b][0][0]==0){ stripm[a][b][0][0]=seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b-number,uppersize)];}
if(stripm[a][b][size][0]==0) {stripm[a][b][size][0]=seed[xMod(x/resolution+a+1-number,uppersize)][xMod(y/resolution+b-number,uppersize)];}
if(stripm[a][b][0][size]==0) {stripm[a][b][0][size]=seed[xMod(x/resolution+a-number,uppersize)][xMod(y/resolution+b+1-number,uppersize)];}
if(stripm[a][b][size][size]==0) {stripm[a][b][size][size]=seed[xMod(x/resolution+a+1-number,uppersize)][xMod(y/resolution+b+1-number,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=stripm[a][b][i-step][j-step];
float val01=stripm[a][b][i-step][j+step];
float val10=stripm[a][b][i+step][j-step];
float val11=stripm[a][b][i+step][j+step];
if(stripm[a][b][i][j]==0){stripm[a][b][i][j]=0.25f*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(stripm[a][b][i-step][j]==0){stripm[a][b][i-step][j]=0.5f*(val00+val01+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i+step][j]==0){stripm[a][b][i+step][j]=0.5f*(val10+val11+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i][j-step]==0){stripm[a][b][i][j-step]=0.5f*(val00+val10+step*xRnd(-sharp,sharp));}
if(stripm[a][b][i][j+step]==0){stripm[a][b][i][j+step]=0.5f*(val01+val11+step*xRnd(-sharp,sharp));}
}
}
step=step>>1;}
}
//********************************************************
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, float sharp, int diff , int height){
float max=-10000.01;
srand(grain);
//создается массив для значений
seed=new float*[size+1];
for(int i=0;i<=size;i++){
seed[i]= new float[size+1];
}
for(int i=0;i<=size;i++){
for(int j=0;j<=size;j++){
seed[i][j]=0;
}
}
for(int i=0;i<=size;i=i+(size>>2)){
for(int j=0;j<=size;j=j+(size>>2)){
seed[i][j]=xRnd(-height,height);
}
}
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=seed[i-step][j-step];
float val01=seed[i-step][j+step];
float val10=seed[i+step][j-step];
float val11=seed[i+step][j+step];
if(seed[i][j]==0 && val00!=0 && val01!=0 && val10!=0 && val11!=0){seed[i][j]=0.25*(val00+val01+val10+val11)+step*xRnd(-sharp,sharp);}
if(seed[i-step][j]==0 && val00!=0 && val01!=0){seed[i-step][j]=0.5*(val00+val01)+0.5*step*xRnd(-sharp,sharp);}
if(seed[i+step][j]==0 && val10!=0 && val11!=0){seed[i+step][j]=0.5*(val10+val11)+0.5*step*xRnd(-sharp,sharp);}
if(seed[i][j-step]==0 && val00!=0 && val10!=0){seed[i][j-step]=0.5*(val00+val10)+0.5*step*xRnd(-sharp,sharp);}
if(seed[i][j+step]==0 && val01!=0 && val11!=0){seed[i][j+step]=0.5*(val01+val11)+0.5*step*xRnd(-sharp,sharp);}
}
}
step=step>>1;
}
for(int i=0;i<=size;i++){for(int j=0;j<=size;j++){
if(seed[i][j]<minimum){minimum=seed[i][j];}
if(seed[i][j]>max){max=seed[i][j];}
}}
height=max-minimum;
}
//********************************************************
int xMod(int a,int b){
int c=a-b*floor(a/b);
if(c<0) {c=c+b;}
return c;
}
//********************************************************
};
|
(Offline)
|
|
20.10.2011, 01:10
|
#132
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: Странное.
Мне почему-то кажется, что код можно неплохо укоротить, если использовать (написать) библиотеку для работы с матрицами с адекватным интерфейсом (перегруженные операторы = * и прочее).
Но, возможно, только кажется
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
20.10.2011, 03:14
|
#133
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: Странное.
Да, быстр пробегаясь по коду, замечаешь симетрии и шаблоны, значит можно вывезти в отдельные мелкие рутины и использовать их.
|
(Offline)
|
|
20.10.2011, 09:10
|
#134
|
Мастер
Регистрация: 09.05.2010
Адрес: Самара
Сообщений: 1,083
Написано 254 полезных сообщений (для 533 пользователей)
|
Ответ: Странное.
Сообщение от impersonalis
Мне почему-то кажется, что код можно неплохо укоротить, если использовать (написать) библиотеку для работы с матрицами с адекватным интерфейсом (перегруженные операторы = * и прочее).
Но, возможно, только кажется
|
А я давно предлагал почитать книгу =) столько бы проблем решилось
|
(Offline)
|
|
20.10.2011, 10:33
|
#135
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Странное.
А мне кажется для ~100 часов опытов в с++ не такой уж и ужасный код
Перегрузку операторов, всякие там виртуальные функции, наследование, шаблоны и т.д. я еще не пробовал, но планирую освоить.
И да, дьявол кроется в деталях. Может смещения и получится унифицировать как получилось объединить деформацию и обновление нормалей, но вряд ли там довольно разные вещи в зависимости от направления происходят.
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:56.
|