Texture.js 5.7 KB
Newer Older
R
Rich Harris 已提交
1 2 3 4 5 6
import { EventDispatcher } from '../core/EventDispatcher';
import { UVMapping } from '../constants';
import { MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, LinearEncoding, UnsignedByteType, RGBAFormat, LinearMipMapLinearFilter, LinearFilter } from '../constants';
import { _Math } from '../math/Math';
import { Vector2 } from '../math/Vector2';

M
Mr.doob 已提交
7
/**
M
Mr.doob 已提交
8
 * @author mrdoob / http://mrdoob.com/
9
 * @author alteredq / http://alteredqualia.com/
10
 * @author szimek / https://github.com/szimek/
M
Mr.doob 已提交
11 12
 */

13 14
var textureId = 0;

M
Mr.doob 已提交
15
function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
M
Mr.doob 已提交
16

17
	Object.defineProperty( this, 'id', { value: textureId ++ } );
M
Mr.doob 已提交
18

R
Rich Harris 已提交
19
	this.uuid = _Math.generateUUID();
M
Mr.doob 已提交
20

21 22
	this.name = '';

R
Rich Harris 已提交
23
	this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
24
	this.mipmaps = [];
25

R
Rich Harris 已提交
26
	this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
27

R
Rich Harris 已提交
28 29
	this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
	this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
M
Mr.doob 已提交
30

R
Rich Harris 已提交
31 32
	this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
	this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;
33

34 35
	this.anisotropy = anisotropy !== undefined ? anisotropy : 1;

R
Rich Harris 已提交
36 37
	this.format = format !== undefined ? format : RGBAFormat;
	this.type = type !== undefined ? type : UnsignedByteType;
38

R
Rich Harris 已提交
39 40
	this.offset = new Vector2( 0, 0 );
	this.repeat = new Vector2( 1, 1 );
41

42
	this.generateMipmaps = true;
43
	this.premultiplyAlpha = false;
44
	this.flipY = true;
45
	this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
46 47 48 49 50 51


	// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
	//
	// Also changing the encoding after already used by a Material will not automatically make the Material
	// update.  You need to explicitly call Material.needsUpdate to trigger it to recompile.
52
	this.encoding = encoding !== undefined ? encoding : LinearEncoding;
53

54
	this.version = 0;
55
	this.onUpdate = null;
56

M
Mr.doob 已提交
57
}
M
Mr.doob 已提交
58

R
Rich Harris 已提交
59 60
Texture.DEFAULT_IMAGE = undefined;
Texture.DEFAULT_MAPPING = UVMapping;
61

R
Rich Harris 已提交
62
Texture.prototype = {
M
Mr.doob 已提交
63

R
Rich Harris 已提交
64
	constructor: Texture,
65

66 67
	isTexture: true,

68
	set needsUpdate( value ) {
M
Mr.doob 已提交
69

M
Mr.doob 已提交
70
		if ( value === true ) this.version ++;
M
Mr.doob 已提交
71 72 73

	},

74
	clone: function () {
75

76
		return new this.constructor().copy( this );
77

78 79
	},

D
dubejf 已提交
80
	copy: function ( source ) {
81

82 83 84

		this.name = source.name + " (Copy)";

85
		this.image = source.image;
86
		this.mipmaps = source.mipmaps.slice( 0 );
M
Mr.doob 已提交
87 88 89 90 91 92 93 94 95 96 97

		this.mapping = source.mapping;

		this.wrapS = source.wrapS;
		this.wrapT = source.wrapT;

		this.magFilter = source.magFilter;
		this.minFilter = source.minFilter;

		this.anisotropy = source.anisotropy;

M
Mr.doob 已提交
98
		this.format = source.format;
99
		this.type = source.type;
100

101 102
		this.offset.copy( source.offset );
		this.repeat.copy( source.repeat );
M
Mr.doob 已提交
103

104 105 106 107
		this.generateMipmaps = source.generateMipmaps;
		this.premultiplyAlpha = source.premultiplyAlpha;
		this.flipY = source.flipY;
		this.unpackAlignment = source.unpackAlignment;
108
		this.encoding = source.encoding;
M
Mr.doob 已提交
109

110
		return this;
111

112 113
	},

114 115 116 117 118 119 120
	toJSON: function ( meta ) {

		if ( meta.textures[ this.uuid ] !== undefined ) {

			return meta.textures[ this.uuid ];

		}
E
elephantatwork 已提交
121

M
Mr.doob 已提交
122 123 124 125 126 127 128 129 130 131
		function getDataURL( image ) {

			var canvas;

			if ( image.toDataURL !== undefined ) {

				canvas = image;

			} else {

E
Eli Grey 已提交
132
				canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
M
Mr.doob 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
				canvas.width = image.width;
				canvas.height = image.height;

				canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );

			}

			if ( canvas.width > 2048 || canvas.height > 2048 ) {

				return canvas.toDataURL( 'image/jpeg', 0.6 );

			} else {

				return canvas.toDataURL( 'image/png' );

			}

		}

E
elephantatwork 已提交
152 153
		var output = {
			metadata: {
154
				version: 4.4,
E
elephantatwork 已提交
155
				type: 'Texture',
156
				generator: 'Texture.toJSON'
E
elephantatwork 已提交
157
			},
158

159
			uuid: this.uuid,
160 161 162 163 164 165 166 167 168 169
			name: this.name,

			mapping: this.mapping,

			repeat: [ this.repeat.x, this.repeat.y ],
			offset: [ this.offset.x, this.offset.y ],
			wrap: [ this.wrapS, this.wrapT ],

			minFilter: this.minFilter,
			magFilter: this.magFilter,
M
Mr.doob 已提交
170 171 172
			anisotropy: this.anisotropy,

			flipY: this.flipY
E
elephantatwork 已提交
173 174
		};

175
		if ( this.image !== undefined ) {
E
elephantatwork 已提交
176

177
			// TODO: Move to THREE.Image
E
elephantatwork 已提交
178

179
			var image = this.image;
E
elephantatwork 已提交
180

181
			if ( image.uuid === undefined ) {
E
elephantatwork 已提交
182

R
Rich Harris 已提交
183
				image.uuid = _Math.generateUUID(); // UGH
E
elephantatwork 已提交
184

185
			}
E
elephantatwork 已提交
186

187 188 189 190 191 192
			if ( meta.images[ image.uuid ] === undefined ) {

				meta.images[ image.uuid ] = {
					uuid: image.uuid,
					url: getDataURL( image )
				};
193 194 195 196

			}

			output.image = image.uuid;
E
elephantatwork 已提交
197 198 199

		}

200 201
		meta.textures[ this.uuid ] = output;

E
elephantatwork 已提交
202
		return output;
203

E
elephantatwork 已提交
204 205
	},

206
	dispose: function () {
207

208
		this.dispatchEvent( { type: 'dispose' } );
209

210 211 212 213
	},

	transformUv: function ( uv ) {

214
		if ( this.mapping !== UVMapping ) return;
215 216 217 218 219

		uv.multiply( this.repeat );
		uv.add( this.offset );

		if ( uv.x < 0 || uv.x > 1 ) {
R
rfm1201 已提交
220

221
			switch ( this.wrapS ) {
R
rfm1201 已提交
222

R
Rich Harris 已提交
223
				case RepeatWrapping:
R
rfm1201 已提交
224

225 226
					uv.x = uv.x - Math.floor( uv.x );
					break;
R
rfm1201 已提交
227

R
Rich Harris 已提交
228
				case ClampToEdgeWrapping:
R
rfm1201 已提交
229

230 231
					uv.x = uv.x < 0 ? 0 : 1;
					break;
R
rfm1201 已提交
232

R
Rich Harris 已提交
233
				case MirroredRepeatWrapping:
R
rfm1201 已提交
234 235 236

					if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {

237
						uv.x = Math.ceil( uv.x ) - uv.x;
R
rfm1201 已提交
238

239
					} else {
R
rfm1201 已提交
240

241
						uv.x = uv.x - Math.floor( uv.x );
R
rfm1201 已提交
242

243
					}
R
rfm1201 已提交
244 245
					break;

246
			}
R
rfm1201 已提交
247

248 249 250
		}

		if ( uv.y < 0 || uv.y > 1 ) {
R
rfm1201 已提交
251

252
			switch ( this.wrapT ) {
R
rfm1201 已提交
253

R
Rich Harris 已提交
254
				case RepeatWrapping:
R
rfm1201 已提交
255

256 257
					uv.y = uv.y - Math.floor( uv.y );
					break;
R
rfm1201 已提交
258

R
Rich Harris 已提交
259
				case ClampToEdgeWrapping:
R
rfm1201 已提交
260

261 262
					uv.y = uv.y < 0 ? 0 : 1;
					break;
R
rfm1201 已提交
263

R
Rich Harris 已提交
264
				case MirroredRepeatWrapping:
R
rfm1201 已提交
265

266
					if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
R
rfm1201 已提交
267

268
						uv.y = Math.ceil( uv.y ) - uv.y;
R
rfm1201 已提交
269

270
					} else {
R
rfm1201 已提交
271

272
						uv.y = uv.y - Math.floor( uv.y );
R
rfm1201 已提交
273

274 275
					}
					break;
R
rfm1201 已提交
276

277
			}
R
rfm1201 已提交
278

279 280 281
		}

		if ( this.flipY ) {
R
rfm1201 已提交
282

283
			uv.y = 1 - uv.y;
R
rfm1201 已提交
284

285
		}
R
rfm1201 已提交
286

287
	}
M
Mr.doob 已提交
288 289

};
290

R
Rich Harris 已提交
291 292
Object.assign( Texture.prototype, EventDispatcher.prototype );

293
export { Texture };