UNPKG

oxygen-core

Version:

Oxygen game engine (Xenon Core for browsers)

191 lines (159 loc) 4.98 kB
import RectangleRenderer from './RectangleRenderer'; import { vec2 } from '../utils/gl-matrix'; export default class Sprite extends RectangleRenderer { static factory() { return new Sprite(); } static get propsTypes() { return { visible: RectangleRenderer.propsTypes.visible, shader: RectangleRenderer.propsTypes.shader, overrideUniforms: RectangleRenderer.propsTypes.overrideUniforms, overrideSamplers: RectangleRenderer.propsTypes.overrideSamplers, layers: RectangleRenderer.propsTypes.layers, width: RectangleRenderer.propsTypes.width, height: RectangleRenderer.propsTypes.height, xOffset: RectangleRenderer.propsTypes.xOffset, yOffset: RectangleRenderer.propsTypes.yOffset, xOrigin: RectangleRenderer.propsTypes.xOrigin, yOrigin: RectangleRenderer.propsTypes.yOrigin, color: RectangleRenderer.propsTypes.color, overrideBaseTexture: 'string_null', overrideBaseFiltering: 'enum(nearest, linear)', frameTopLeft: 'vec2', frameBottomRight: 'vec2' }; } get overrideBaseTexture() { const { overrideSamplers } = this; const sampler = overrideSamplers.sBase; return !!sampler ? sampler.texture : null; } set overrideBaseTexture(value) { const { overrideSamplers } = this; if (!value) { delete overrideSamplers.sBase; this.overrideSamplers = overrideSamplers; return; } if (typeof value !== 'string') { throw new Error('`value` is not type of String!'); } const sampler = overrideSamplers.sBase; if (!sampler) { overrideSamplers.sBase = { texture: value, filtering: 'linear' }; } else { sampler.texture = value; } this.overrideSamplers = overrideSamplers; } get overrideBaseFiltering() { const { overrideSamplers } = this; const sampler = overrideSamplers.get('sBase'); return !!sampler ? sampler.filtering : null; } set overrideBaseFiltering(value) { const { overrideSamplers } = this; if (typeof value !== 'string') { throw new Error('`value` is not type of String!'); } const sampler = overrideSamplers.sBase; if (!sampler) { overrideSamplers.sBase = { texture: '', filtering: value }; } else { sampler.filtering = value; } this.overrideSamplers = overrideSamplers; } get frameTopLeft() { return this._frameTopLeft; } set frameTopLeft(value) { if (!(value instanceof Array)) { throw new Error('`value` is not type of Array!'); } if (value.length < 2) { throw new Error('`value` must have at least 2 elements!'); } vec2.copy(this._frameTopLeft, value); this._rebuild = true; } get frameBottomRight() { return this._frameBottomRight; } set frameBottomRight(value) { if (!(value instanceof Array)) { throw new Error('`value` is not type of Array!'); } if (value.length < 2) { throw new Error('`value` must have at least 2 elements!'); } vec2.copy(this._frameBottomRight, value); this._rebuild = true; } constructor() { super(); this._frameTopLeft = vec2.fromValues(0, 0); this._frameBottomRight = vec2.fromValues(1, 1); } onPropertySerialize(name, value) { if (name === 'frameTopLeft' || name === 'frameBottomRight') { return [ ...value ]; } else if (name === 'overrideSamplers') { const result = super.onPropertySerialize(name, value); if (!result) { return null; } delete result.sBase; return Object.keys(result).length > 0 ? result : null; } else { return super.onPropertySerialize(name, value); } } ensureVertices(renderer) { if (!this._rebuild) { return; } let { _width, _height } = this; const { _xOffset, _yOffset, _xOrigin, _yOrigin, _frameTopLeft, _frameBottomRight } = this; if (_width < 0 || _height < 0) { const meta = renderer.getTextureMeta(this.overrideBaseTexture); if (_width < 0) { _width = !!meta ? meta.width : 0; } if (_height < 0) { _height = !!meta ? meta.height : 0; } } const xo = -_xOffset - (_xOrigin * _width); const yo = -_yOffset - (_yOrigin * _height); this.vertices = [ xo, yo, _frameTopLeft[0], _frameTopLeft[1], _width + xo, yo, _frameBottomRight[0], _frameTopLeft[1], _width + xo, _height + yo, _frameBottomRight[0], _frameBottomRight[1], xo, _height + yo, _frameTopLeft[0], _frameBottomRight[1] ]; this.indices = [ 0, 1, 2, 2, 3, 0 ]; this._rebuild = false; } }