UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

164 lines 5.48 kB
import { Color, RepeatWrapping, Vector2, VideoTexture } from "three"; import loadTexture from "../../utils/loaders/loadTexture"; import { Reactive } from "@lincode/reactivity"; import queueDebounce from "../../../utils/queueDebounce"; import { deg2Rad } from "@lincode/math"; const mapNames = ["map", "alphaMap"]; const queueTextureRepeat = queueDebounce(); export default class TexturedBasicMixin { materialCloned; tryCloneMaterial() { if (this.materialCloned) return; this.materialCloned = true; //@ts-ignore this.material = this.nativeObject3d.material = this.material.clone(); //@ts-ignore this.then(() => this.material.dispose()); } get color() { return "#" + this.material.color.getHexString(); } set color(val) { this.tryCloneMaterial(); this.material.color = new Color(val); } get fog() { return this.material.fog; } set fog(val) { this.tryCloneMaterial(); this.material.fog = val; } _opacity; get opacity() { return (this._opacity ??= 1); } set opacity(val) { this.tryCloneMaterial(); this._opacity = val; this.material.opacity = val; this.material.transparent = val <= 1; //@ts-ignore this.nativeObject3d.visible = !!val; } applyTexture(mapNames) { const repeat = this._textureRepeat; const flipY = this._textureFlipY; const rotation = this._textureRotation; queueTextureRepeat(this, () => { this.tryCloneMaterial(); for (const name of mapNames) { //@ts-ignore const map = this.material[name]; if (!map) return; repeat !== undefined && (map.repeat = repeat); flipY !== undefined && (map.flipY = flipY); rotation !== undefined && (map.rotation = rotation * deg2Rad); map.needsUpdate = true; } }); } videoTextureState; textureState; initTexture() { if (this.textureState) return; this.tryCloneMaterial(); const videoTextureState = (this.videoTextureState = new Reactive(undefined)); const textureState = (this.textureState = new Reactive(undefined)); //@ts-ignore this.createEffect(() => { const url = textureState.get(); const videoURL = videoTextureState.get(); if (videoURL) { let video; if (typeof videoURL === "string") { video = document.createElement("video"); video.crossOrigin = "anonymous"; video.src = videoURL; video.loop = true; video.autoplay = true; video.muted = true; video.playsInline = true; video.play(); } else video = videoURL; const videoTexture = new VideoTexture(video, undefined, RepeatWrapping, RepeatWrapping); const { material } = this; const { map } = material; material.map = videoTexture; material.needsUpdate = true; this.applyTexture(mapNames); return () => { video.pause(); videoTexture.dispose(); material.map = map; material.needsUpdate = true; }; } if (!url) return; const { material } = this; const { map } = material; material.map = loadTexture(url); this.applyTexture(mapNames); return () => { material.map = map; this.material.needsUpdate = true; }; }, [videoTextureState.get, textureState.get]); } get videoTexture() { return this.videoTextureState?.get(); } set videoTexture(url) { this.initTexture(); this.videoTextureState.set(url); } get texture() { return this.textureState?.get(); } set texture(url) { this.initTexture(); this.textureState.set(url); } _alphaMap; get alphaMap() { return this._alphaMap; } set alphaMap(val) { this.tryCloneMaterial(); this._alphaMap = val; this.material.alphaMap = val ? loadTexture(val) : null; this.applyTexture(mapNames); } _textureRepeat; get textureRepeat() { return this._textureRepeat; } set textureRepeat(val) { typeof val === "number" && (val = new Vector2(val, val)); this._textureRepeat = val; this.applyTexture(mapNames); } _textureFlipY; get textureFlipY() { return this._textureFlipY; } set textureFlipY(val) { this._textureFlipY = val; this.applyTexture(mapNames); } _textureRotation; get textureRotation() { return this._textureRotation; } set textureRotation(val) { this._textureRotation = val; this.applyTexture(mapNames); } } //# sourceMappingURL=TexturedBasicMixin.js.map