UNPKG

mylingo3d

Version:

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

90 lines (78 loc) 2.92 kB
import { Reactive } from "@lincode/reactivity" import { planeGeometry } from "./primitives/Plane" import { sphereGeometry } from "./primitives/Sphere" import loadTexture from "./utils/loaders/loadTexture" import { dt } from "../engine/eventLoop" import { onBeforeRender } from "../events/onBeforeRender" import IWater, { waterDefaults, waterSchema } from "../interface/IWater" import { WATERNORMALS_URL } from "../globals" import ObjectManager from "./core/ObjectManager" export default class Water extends ObjectManager implements IWater { public static componentName = "water" public static defaults = waterDefaults public static schema = waterSchema private shapeState = new Reactive<"plane" | "sphere">("plane") public get shape() { return this.shapeState.get() } public set shape(val) { this.shapeState.set(val) } private normalMapState = new Reactive(WATERNORMALS_URL) public get normalMap() { return this.normalMapState.get() } public set normalMap(val) { this.normalMapState.set(val) } private resolutionState = new Reactive(512) public get resolution() { return this.resolutionState.get() } public set resolution(val) { this.resolutionState.set(val) } private speedState = new Reactive(1) public get speed() { return this.speedState.get() } public set speed(val) { this.speedState.set(val) } public constructor() { super() this.rotationX = -90 import("three/examples/jsm/objects/Water").then(({ Water }) => { this.createEffect(() => { const normalMap = this.normalMapState.get() if (!normalMap) return const isPlane = this.shapeState.get() === "plane" const waterGeometry = isPlane ? planeGeometry : sphereGeometry const res = this.resolutionState.get() const water = new Water(waterGeometry, { textureWidth: res, textureHeight: res, waterNormals: loadTexture(normalMap), // sunDirection: new Vector3(), sunColor: 0xffffff, waterColor: 0x001e0f, distortionScale: 3.7 }) const speed = this.speedState.get() this.object3d.add(water) const handle = onBeforeRender(() => { water.material.uniforms["time"].value += dt[0] * speed }) return () => { this.object3d.remove(water) handle.cancel() } }, [ this.shapeState.get, this.normalMapState.get, this.resolutionState.get, this.speedState.get ]) }) } }