ThreeJS源码学习3Texture

Texture

先贴第一段代码。通过这段时间学习,可以基本摸索出ThreeJS的代码风格。定义一个新方法,首先在主函数中确定必要属性

function Texture(image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) {
		Object.defineProperty(this, 'id', {
			value: textureId++
		});
		this.uuid = MathUtils.generateUUID();
		this.name = '';
		this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
		this.mipmaps = [];
		this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
		this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
		this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
		this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
		this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter;
		this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
		this.format = format !== undefined ? format : RGBAFormat;
		this.internalFormat = null;
		this.type = type !== undefined ? type : UnsignedByteType;
		this.offset = new Vector2(0, 0);
		this.repeat = new Vector2(1, 1);
		this.center = new Vector2(0, 0);
		this.rotation = 0;
		this.matrixAutoUpdate = true;
		this.matrix = new Matrix3();
		this.generateMipmaps = true;
		this.premultiplyAlpha = false;
		this.flipY = true;
		this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
		// 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.

		this.encoding = encoding !== undefined ? encoding : LinearEncoding;
		this.version = 0;
		this.onUpdate = null;
	}

然后通过改变prototype指向的方法实现继承父类与自己的内部方法。

Texture.prototype = Object.assign(Object.create(EventDispatcher.prototype), {
		constructor: Texture,
		isTexture: true,
		updateMatrix: function updateMatrix() {
			this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
		},
		clone: function clone() {
			return new this.constructor().copy(this);
		},
		copy: function copy(source) {
			this.name = source.name;
			this.image = source.image;
			this.mipmaps = source.mipmaps.slice(0);
			this.mapping = source.mapping;
			this.wrapS = source.wrapS;
			this.wrapT = source.wrapT;
			this.magFilter = source.magFilter;
			this.minFilter = source.minFilter;
			this.anisotropy = source.anisotropy;
			this.format = source.format;
			this.internalFormat = source.internalFormat;
			this.type = source.type;
			this.offset.copy(source.offset);
			this.repeat.copy(source.repeat);
			this.center.copy(source.center);
			this.rotation = source.rotation;
			this.matrixAutoUpdate = source.matrixAutoUpdate;
			this.matrix.copy(source.matrix);
			this.generateMipmaps = source.generateMipmaps;
			this.premultiplyAlpha = source.premultiplyAlpha;
			this.flipY = source.flipY;
			this.unpackAlignment = source.unpackAlignment;
			this.encoding = source.encoding;
			return this;
		},
		toJSON: function toJSON(meta) {
			var isRootObject = meta === undefined || typeof meta === 'string';

			if (!isRootObject && meta.textures[this.uuid] !== undefined) {
				return meta.textures[this.uuid];
			}

			var output = {
				metadata: {
					version: 4.5,
					type: 'Texture',
					generator: 'Texture.toJSON'
				},
				uuid: this.uuid,
				name: this.name,
				mapping: this.mapping,
				repeat: [this.repeat.x, this.repeat.y],
				offset: [this.offset.x, this.offset.y],
				center: [this.center.x, this.center.y],
				rotation: this.rotation,
				wrap: [this.wrapS, this.wrapT],
				format: this.format,
				type: this.type,
				encoding: this.encoding,
				minFilter: this.minFilter,
				magFilter: this.magFilter,
				anisotropy: this.anisotropy,
				flipY: this.flipY,
				premultiplyAlpha: this.premultiplyAlpha,
				unpackAlignment: this.unpackAlignment
			};

			if (this.image !== undefined) {
				// TODO: Move to THREE.Image
				var image = this.image;

				if (image.uuid === undefined) {
					image.uuid = MathUtils.generateUUID(); // UGH
				}

				if (!isRootObject && meta.images[image.uuid] === undefined) {
					var url;

					if (Array.isArray(image)) {
						// process array of images e.g. CubeTexture
						url = [];

						for (var i = 0, l = image.length; i < l; i++) {
							url.push(ImageUtils.getDataURL(image[i]));
						}
					} else {
						// process single image
						url = ImageUtils.getDataURL(image);
					}

					meta.images[image.uuid] = {
						uuid: image.uuid,
						url: url
					};
				}

				output.image = image.uuid;
			}

			if (!isRootObject) {
				meta.textures[this.uuid] = output;
			}

			return output;
		},
		dispose: function dispose() {
			this.dispatchEvent({
				type: 'dispose'
			});
		},
		transformUv: function transformUv(uv) {
			if (this.mapping !== UVMapping) return uv;
			uv.applyMatrix3(this.matrix);

			if (uv.x < 0 || uv.x > 1) {
				switch (this.wrapS) {
					case RepeatWrapping:
						uv.x = uv.x - Math.floor(uv.x);
						break;

					case ClampToEdgeWrapping:
						uv.x = uv.x < 0 ? 0 : 1;
						break;

					case MirroredRepeatWrapping:
						if (Math.abs(Math.floor(uv.x) % 2) === 1) {
							uv.x = Math.ceil(uv.x) - uv.x;
						} else {
							uv.x = uv.x - Math.floor(uv.x);
						}

						break;
				}
			}

			if (uv.y < 0 || uv.y > 1) {
				switch (this.wrapT) {
					case RepeatWrapping:
						uv.y = uv.y - Math.floor(uv.y);
						break;

					case ClampToEdgeWrapping:
						uv.y = uv.y < 0 ? 0 : 1;
						break;

					case MirroredRepeatWrapping:
						if (Math.abs(Math.floor(uv.y) % 2) === 1) {
							uv.y = Math.ceil(uv.y) - uv.y;
						} else {
							uv.y = uv.y - Math.floor(uv.y);
						}

						break;
				}
			}

			if (this.flipY) {
				uv.y = 1 - uv.y;
			}

			return uv;
		}
	});

其中许多方法在虚实融合中是用不到的,对我们自定义的针对于虚实融合的三维引擎库FOVAR来说,这些在处女版本中可以丢弃,起到精简的作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值