summaryrefslogtreecommitdiff
path: root/src/noise.h
blob: ed75f316dca7d4fcca2ef48136f51951b49beacb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef NOISE_HEADER
#define NOISE_HEADER

#include "debug.h"

class PseudoRandom
{
public:
	PseudoRandom(): m_next(0)
	{
	}
	PseudoRandom(int seed): m_next(seed)
	{
	}
	void seed(int seed)
	{
		m_next = seed;
	}
	// Returns 0...32767
	int next()
	{
		m_next = m_next * 1103515245 + 12345;
		return((unsigned)(m_next/65536) % 32768);
	}
	int range(int min, int max)
	{
		if(max-min > 32768/10)
		{
			//dstream<<"WARNING: PseudoRandom::range: max > 32767"<<std::endl;
			assert(0);
		}
		if(min > max)
		{
			assert(0);
			return max;
		}
		return (next()%(max-min+1))+min;
	}
private:
	int m_next;
};

double easeCurve(double t);
 
// Return value: -1 ... 1
double noise2d(int x, int y, int seed);
double noise3d(int x, int y, int z, int seed);

double noise2d_gradient(double x, double y, int seed);
double noise3d_gradient(double x, double y, double z, int seed);

double noise2d_perlin(double x, double y, int seed,
		int octaves, double persistence);

double noise2d_perlin_abs(double x, double y, int seed,
		int octaves, double persistence);

double noise3d_perlin(double x, double y, double z, int seed,
		int octaves, double persistence);

double noise3d_perlin_abs(double x, double y, double z, int seed,
		int octaves, double persistence);

enum NoiseType
{
	NOISE_CONSTANT_ONE,
	NOISE_PERLIN,
	NOISE_PERLIN_ABS,
	NOISE_PERLIN_CONTOUR,
	NOISE_PERLIN_CONTOUR_FLIP_YZ,
};

struct NoiseParams
{
	NoiseType type;
	int seed;
	int octaves;
	double persistence;
	double pos_scale;
	double noise_scale; // Useful for contour noises
	
	NoiseParams(NoiseType type_=NOISE_PERLIN, int seed_=0,
			int octaves_=3, double persistence_=0.5,
			double pos_scale_=100.0, double noise_scale_=1.0):
		type(type_),
		seed(seed_),
		octaves(octaves_),
		persistence(persistence_),
		pos_scale(pos_scale_),
		noise_scale(noise_scale_)
	{
	}
};

double noise3d_param(const NoiseParams &param, double x, double y, double z);

class NoiseBuffer
{
public:
	NoiseBuffer();
	~NoiseBuffer();
	
	void clear();
	void create(const NoiseParams &param,
			double first_x, double first_y, double first_z,
			double last_x, double last_y, double last_z,
			double samplelength_x, double samplelength_y, double samplelength_z);
	void multiply(const NoiseParams &param);
	// Deprecated
	void create(int seed, int octaves, double persistence,
			bool abs,
			double first_x, double first_y, double first_z,
			double last_x, double last_y, double last_z,
			double samplelength_x, double samplelength_y, double samplelength_z);

	void intSet(int x, int y, int z, double d);
	void intMultiply(int x, int y, int z, double d);
	double intGet(int x, int y, int z);
	double get(double x, double y, double z);
	//bool contains(double x, double y, double z);

private:
	double *m_data;
	double m_start_x, m_start_y, m_start_z;
	double m_samplelength_x, m_samplelength_y, m_samplelength_z;
	int m_size_x, m_size_y, m_size_z;
};

#endif

t] + K; e = d; d = c; c = lrot(b,30); b = a; a = temp; //printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e ); } /* add variables */ H0 += a; H1 += b; H2 += c; H3 += d; H4 += e; //printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 ); /* all bytes have been processed */ unprocessedBytes = 0; } // addBytes ********************************************************** void SHA1::addBytes( const char* data, int num ) { assert( data ); assert( num > 0 ); // add these bytes to the running total size += num; // repeat until all data is processed while( num > 0 ) { // number of bytes required to complete block int needed = 64 - unprocessedBytes; assert( needed > 0 ); // number of bytes to copy (use smaller of two) int toCopy = (num < needed) ? num : needed; // Copy the bytes memcpy( bytes + unprocessedBytes, data, toCopy ); // Bytes have been copied num -= toCopy; data += toCopy; unprocessedBytes += toCopy; // there is a full block if( unprocessedBytes == 64 ) process(); } } // digest ************************************************************ unsigned char* SHA1::getDigest() { // save the message size Uint32 totalBitsL = size << 3; Uint32 totalBitsH = size >> 29; // add 0x80 to the message addBytes( "\x80", 1 ); unsigned char footer[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // block has no room for 8-byte filesize, so finish it if( unprocessedBytes > 56 ) addBytes( (char*)footer, 64 - unprocessedBytes); assert( unprocessedBytes <= 56 ); // how many zeros do we need int neededZeros = 56 - unprocessedBytes; // store file size (in bits) in big-endian format storeBigEndianUint32( footer + neededZeros , totalBitsH ); storeBigEndianUint32( footer + neededZeros + 4, totalBitsL ); // finish the final block addBytes( (char*)footer, neededZeros + 8 ); // allocate memory for the digest bytes unsigned char* digest = (unsigned char*)malloc( 20 ); // copy the digest bytes storeBigEndianUint32( digest, H0 ); storeBigEndianUint32( digest + 4, H1 ); storeBigEndianUint32( digest + 8, H2 ); storeBigEndianUint32( digest + 12, H3 ); storeBigEndianUint32( digest + 16, H4 ); // return the digest return digest; }