@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
130 lines (103 loc) • 3.67 kB
JavaScript
import GUIElement from "../ecs/gui/GUIElement.js";
import { Transform } from "../ecs/transform/Transform.js";
import Mesh from "../graphics/ecs/mesh/Mesh.js";
import Tween from "./Tween.js";
function doMaterial(m, what) {
const materials = m.materials;
if (materials !== undefined) {
let i = 0;
const l = materials.length;
for (; i < l; i++) {
doMaterial(materials[i], what);
}
} else {
what(m);
}
}
/**
*
* @param {number} entity
* @param {EntityComponentDataset} ecd
* @param {Vector3} parameter destination in local offset from current position
* @param {number} time duration
* @param {function(x:number):number} transitionFunction
* @returns {Tween}
*/
function translate(entity, ecd, parameter, time, transitionFunction) {
const transform = ecd.getComponent(entity, Transform);
const origin = transform.position.clone();
const target = origin.clone().add(parameter);
const temp = origin.clone();
return new Tween(function (v) {
const position = transform.position;
temp.copy(origin).lerp(target, v);
position.copy(temp);
}, 0, 1, time, transitionFunction);
}
/**
*
* @param {number} entity
* @param {EntityComponentDataset} ecd
* @param {Vector3} parameter final opacity, 1 - fully opaque, 0 - fully transparent
* @param {number} time duration
* @param {function(x:number):number} transitionFunction
* @returns {Tween}
*/
function fade(entity, ecd, parameter, time, transitionFunction) {
const tweenUpdateCallbacks = [];
const tweenEndCallbacks = [];
let original = 1;
/**
*
* @type {Mesh}
*/
const model3d = ecd.getComponent(entity, Mesh);
if (model3d !== undefined && model3d.mesh !== undefined && model3d.mesh.material !== undefined) {
const material = model3d.mesh.material.clone();
//duplicate material so we can modify it
model3d.mesh.material = material;
if (parameter < 1) {
console.warn('Will modify material, this is dangerous as it can impact other objects that share the material', model3d.url);
//hide shadows, as in THREE it is currently not possible to adjust strength of shadows per object
model3d.mesh.castShadow = false;
model3d.castShadow = false;
doMaterial(material, function (m) {
m.transparent = true;
});
}
doMaterial(material, function (m) {
original = m.opacity;
});
tweenUpdateCallbacks.push(function (v) {
doMaterial(material, function (m) {
m.opacity = v;
m.needsUpdate = true;
model3d.opacity = v;
});
});
tweenEndCallbacks.push(function () {
doMaterial(material, function (m) {
m.visible = true;
});
});
}
const guiElement = ecd.getComponent(entity, GUIElement);
if (guiElement !== undefined) {
tweenUpdateCallbacks.push(function (v) {
guiElement.view.el.style.opacity = v;
});
}
const tween = new Tween(function (v) {
for (let i = 0; i < tweenUpdateCallbacks.length; i++) {
tweenUpdateCallbacks[i](v);
}
}, original, parameter, time, transitionFunction);
tweenEndCallbacks.forEach(function (cb) {
tween.on.ended.add(cb);
});
return tween;
}
export default {
translate: translate,
fade: fade
};