three-glyph
Version:
Provide geometry and material in THREE.js for MSDF (multi-channel signed distance fields) glyph and more
98 lines (81 loc) • 2.68 kB
JavaScript
import {
Box3,
BufferGeometry,
BufferAttribute,
Sphere
} from 'three/webgpu'
import createIndices from 'quad-indices'
import { createLayout } from './pure/layout-text'
import * as vertices from './pure/vertices'
import { computeBox, computeSphere } from './pure/utils'
export default class GlyphGeometry extends BufferGeometry {
constructor(opt){
super(opt);
this._opt = Object.assign({}, opt)
if (opt) this.update(opt)
}
update(opt) {
if (typeof opt === 'string') {
opt = { text: opt }
}
opt = Object.assign({}, this._opt, opt)
if (!opt.font) {
throw new TypeError('must specify a { font } in options')
}
this.layout = createLayout(opt)
var flipY = opt.flipY !== false
var font = opt.font
var texWidth = font.common.scaleW
var texHeight = font.common.scaleH
var glyphs = this.layout.glyphs.filter(function (glyph) {
var bitmap = glyph.data
return bitmap.width * bitmap.height > 0
})
this.visibleGlyphs = glyphs
var indices = createIndices([], {
clockwise: true,
type: 'uint16',
count: glyphs.length,
})
var index = vertices.indices(glyphs)
var positions = vertices.positions(glyphs)
var uvs = vertices.uvs(glyphs, texWidth, texHeight, flipY)
var guvs = vertices.guvs(glyphs, texWidth, texHeight, flipY)
this.setIndex(indices)
this.setAttribute('index', new BufferAttribute(index, 1));
this.setAttribute('position', new BufferAttribute(positions, 3))
this.setAttribute('uv', new BufferAttribute(uvs, 2))
this.setAttribute('guv', new BufferAttribute(guvs, 2));
}
computeBoundingSphere() {
if (this.boundingSphere === null) {
this.boundingSphere = new Sphere()
}
var positions = this.attributes.position.array
var itemSize = this.attributes.position.itemSize
if (!positions || !itemSize || positions.length < 2) {
this.boundingSphere.radius = 0
this.boundingSphere.center.set(0, 0, 0)
return
}
computeSphere(positions, this.boundingSphere)
if (isNaN(this.boundingSphere.radius)) {
console.error('THREE.BufferGeometry.computeBoundingSphere(): ' +
'Computed radius is NaN. The ' +
'"position" attribute is likely to have NaN values.')
}
}
computeBoundingBox() {
if (this.boundingBox === null) {
this.boundingBox = new Box3()
}
var bbox = this.boundingBox
var positions = this.attributes.position.array
var itemSize = this.attributes.position.itemSize
if (!positions || !itemSize || positions.length < 2) {
bbox.makeEmpty()
return
}
computeBox(positions, bbox)
}
}