diff --git a/src/mol-geo/geometry/text/text-builder.ts b/src/mol-geo/geometry/text/text-builder.ts index 200beecffddbb876fd72e60ffea978968275e01e..622043cb74281685fc48328831a500f93deb8323 100644 --- a/src/mol-geo/geometry/text/text-builder.ts +++ b/src/mol-geo/geometry/text/text-builder.ts @@ -16,7 +16,7 @@ const quadIndices = new Uint16Array([ ]) export interface TextBuilder { - add(str: string, x: number, y: number, z: number, group: number): void + add(str: string, x: number, y: number, z: number, depth: number, group: number): void getText(): Text } @@ -26,6 +26,7 @@ export namespace TextBuilder { chunkSize *= 2 const centers = ChunkedArray.create(Float32Array, 3, chunkSize, text ? text.centerBuffer.ref.value : initialCount); const mappings = ChunkedArray.create(Float32Array, 2, chunkSize, text ? text.mappingBuffer.ref.value : initialCount); + const depths = ChunkedArray.create(Float32Array, 1, chunkSize, text ? text.depthBuffer.ref.value : initialCount); const indices = ChunkedArray.create(Uint32Array, 3, chunkSize, text ? text.indexBuffer.ref.value : initialCount); const groups = ChunkedArray.create(Float32Array, 1, chunkSize, text ? text.groupBuffer.ref.value : initialCount); const tcoords = ChunkedArray.create(Float32Array, 2, chunkSize, text ? text.tcoordBuffer.ref.value : initialCount); @@ -38,7 +39,7 @@ export namespace TextBuilder { const outline = fontAtlas.buffer / fontAtlas.lineHeight return { - add: (str: string, x: number, y: number, z: number, group: number) => { + add: (str: string, x: number, y: number, z: number, depth: number, group: number) => { let xadvance = 0 const nChar = str.length @@ -76,6 +77,7 @@ export namespace TextBuilder { for (let i = 0; i < 4; ++i) { ChunkedArray.add2(tcoords, 10, 10) ChunkedArray.add3(centers, x, y, z); + ChunkedArray.add(depths, depth); ChunkedArray.add(groups, group); } ChunkedArray.add3(indices, offset + quadIndices[0], offset + quadIndices[1], offset + quadIndices[2]) @@ -107,6 +109,7 @@ export namespace TextBuilder { const offset = centers.elementCount for (let i = 0; i < 4; ++i) { ChunkedArray.add3(centers, x, y, z); + ChunkedArray.add(depths, depth); ChunkedArray.add(groups, group); } ChunkedArray.add3(indices, offset + quadIndices[0], offset + quadIndices[1], offset + quadIndices[2]) @@ -114,18 +117,20 @@ export namespace TextBuilder { } }, getText: () => { + const ft = fontAtlas.texture const cb = ChunkedArray.compact(centers, true) as Float32Array const mb = ChunkedArray.compact(mappings, true) as Float32Array + const db = ChunkedArray.compact(depths, true) as Float32Array const ib = ChunkedArray.compact(indices, true) as Uint32Array const gb = ChunkedArray.compact(groups, true) as Float32Array const tb = ChunkedArray.compact(tcoords, true) as Float32Array - const ft = fontAtlas.texture return { kind: 'text', charCount: indices.elementCount / 2, fontTexture: text ? ValueCell.update(text.fontTexture, ft) : ValueCell.create(ft), centerBuffer: text ? ValueCell.update(text.centerBuffer, cb) : ValueCell.create(cb), mappingBuffer: text ? ValueCell.update(text.mappingBuffer, mb) : ValueCell.create(mb), + depthBuffer: text ? ValueCell.update(text.depthBuffer, db) : ValueCell.create(db), indexBuffer: text ? ValueCell.update(text.indexBuffer, ib) : ValueCell.create(ib), groupBuffer: text ? ValueCell.update(text.groupBuffer, gb) : ValueCell.create(gb), tcoordBuffer: text ? ValueCell.update(text.tcoordBuffer, tb) : ValueCell.create(tb), diff --git a/src/mol-geo/geometry/text/text.ts b/src/mol-geo/geometry/text/text.ts index 6b2534891a0c565e25411da64ce68bf6e93a56d6..d8b82920149e957d23744a00c24b31a1a1325677 100644 --- a/src/mol-geo/geometry/text/text.ts +++ b/src/mol-geo/geometry/text/text.ts @@ -44,6 +44,8 @@ export interface Text { readonly centerBuffer: ValueCell<Float32Array>, /** Mapping buffer as array of xy values wrapped in a value cell */ readonly mappingBuffer: ValueCell<Float32Array>, + /** Depth buffer as array of z values wrapped in a value cell */ + readonly depthBuffer: ValueCell<Float32Array>, /** Index buffer as array of center index triplets wrapped in a value cell */ readonly indexBuffer: ValueCell<Uint32Array>, /** Group buffer as array of group ids for each vertex wrapped in a value cell */ @@ -54,18 +56,20 @@ export interface Text { export namespace Text { export function createEmpty(text?: Text): Text { + const ft = text ? text.fontTexture.ref.value : createTextureImage(0, 1) const cb = text ? text.centerBuffer.ref.value : new Float32Array(0) const mb = text ? text.mappingBuffer.ref.value : new Float32Array(0) + const db = text ? text.depthBuffer.ref.value : new Float32Array(0) const ib = text ? text.indexBuffer.ref.value : new Uint32Array(0) const gb = text ? text.groupBuffer.ref.value : new Float32Array(0) const tb = text ? text.tcoordBuffer.ref.value : new Float32Array(0) - const ft = text ? text.fontTexture.ref.value : createTextureImage(0, 1) return { kind: 'text', charCount: 0, fontTexture: text ? ValueCell.update(text.fontTexture, ft) : ValueCell.create(ft), centerBuffer: text ? ValueCell.update(text.centerBuffer, cb) : ValueCell.create(cb), mappingBuffer: text ? ValueCell.update(text.mappingBuffer, mb) : ValueCell.create(mb), + depthBuffer: text ? ValueCell.update(text.depthBuffer, db) : ValueCell.create(db), indexBuffer: text ? ValueCell.update(text.indexBuffer, ib) : ValueCell.create(ib), groupBuffer: text ? ValueCell.update(text.groupBuffer, gb) : ValueCell.create(gb), tcoordBuffer: text ? ValueCell.update(text.tcoordBuffer, tb) : ValueCell.create(tb) @@ -118,7 +122,7 @@ export namespace Text { const counts = { drawCount: text.charCount * 2 * 3, groupCount, instanceCount } - const padding = getPadding(text.mappingBuffer.ref.value, text.charCount, getMaxSize(size)) + const padding = getPadding(text.mappingBuffer.ref.value, text.depthBuffer.ref.value, text.charCount, getMaxSize(size)) const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( text.centerBuffer.ref.value, text.charCount * 4, transform.aTransform.ref.value, instanceCount, padding @@ -127,6 +131,7 @@ export namespace Text { return { aPosition: text.centerBuffer, aMapping: text.mappingBuffer, + aDepth: text.depthBuffer, aGroup: text.groupBuffer, elements: text.indexBuffer, boundingSphere: ValueCell.create(boundingSphere), @@ -179,7 +184,7 @@ export namespace Text { } function updateBoundingSphere(values: TextValues, text: Text) { - const padding = getPadding(values.aMapping.ref.value, text.charCount, getMaxSize(values)) + const padding = getPadding(values.aMapping.ref.value, values.aDepth.ref.value, text.charCount, getMaxSize(values)) const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( values.aPosition.ref.value, text.charCount * 4, values.aTransform.ref.value, values.instanceCount.ref.value, padding @@ -205,13 +210,19 @@ export namespace Text { } } -function getPadding(mapping: Float32Array, charCount: number, maxSize: number) { +function getPadding(mappings: Float32Array, depths: Float32Array, charCount: number, maxSize: number) { let maxOffset = 0 + let maxDepth = 0 for (let i = 0, il = charCount * 4; i < il; ++i) { - const ox = Math.abs(mapping[i]) + const i2 = 2 * i + const ox = Math.abs(mappings[i2]) if (ox > maxOffset) maxOffset = ox - const oy = Math.abs(mapping[i + 1]) + const oy = Math.abs(mappings[i2 + 1]) if (oy > maxOffset) maxOffset = oy + const d = Math.abs(depths[i]) + if (d > maxDepth) maxDepth = d } - return maxSize + maxSize * maxOffset + // console.log(maxDepth + maxSize, maxDepth, maxSize, maxSize + maxSize * maxOffset, depths) + return Math.max(maxDepth, maxSize + maxSize * maxOffset) + // return maxSize + maxSize * maxOffset + maxDepth } \ No newline at end of file diff --git a/src/mol-gl/renderable/text.ts b/src/mol-gl/renderable/text.ts index 7e633f37d8ae6e8b832d6e87a2068cd1dee25cf3..6f10a8fad2fc94589cfe215d39f0bbd8466b5c0e 100644 --- a/src/mol-gl/renderable/text.ts +++ b/src/mol-gl/renderable/text.ts @@ -16,6 +16,7 @@ export const TextSchema = { ...SizeSchema, aPosition: AttributeSpec('float32', 3, 0), aMapping: AttributeSpec('float32', 2, 0), + aDepth: AttributeSpec('float32', 1, 0), elements: ElementsSpec('uint32'), aTexCoord: AttributeSpec('float32', 2, 0), diff --git a/src/mol-gl/shader/text.vert b/src/mol-gl/shader/text.vert index 54266ddc7ac0eb7207da4542dab9f96fa6b3a26a..e307dfb08f11dbc8e2c69c36d684d9a2d6460891 100644 --- a/src/mol-gl/shader/text.vert +++ b/src/mol-gl/shader/text.vert @@ -15,6 +15,7 @@ uniform mat4 uModelView; attribute vec3 aPosition; attribute vec2 aMapping; +attribute float aDepth; attribute vec2 aTexCoord; attribute mat4 aTransform; attribute float aInstance; @@ -43,7 +44,7 @@ void main(void){ float offsetX = uOffsetX * scale; float offsetY = uOffsetY * scale; - float offsetZ = uOffsetZ * scale; + float offsetZ = (uOffsetZ + aDepth * 0.95) * scale; if (vTexCoord.x == 10.0) { offsetZ -= 0.01; } diff --git a/src/tests/browser/render-text.ts b/src/tests/browser/render-text.ts index a299d3cefae15e1c68d64b835462b4893e3a31a0..4eca7abaacd59f9de06ca0315d58ebf7174b5af6 100644 --- a/src/tests/browser/render-text.ts +++ b/src/tests/browser/render-text.ts @@ -37,11 +37,11 @@ function textRepr() { } const textBuilder = TextBuilder.create(props, 1, 1) - textBuilder.add('Hello world', 0, 0, 0, 0) - textBuilder.add('Добрый день', 0, 1, 0, 0) - textBuilder.add('美好的一天', 0, 2, 0, 0) - textBuilder.add('¿Cómo estás?', 0, -1, 0, 0) - textBuilder.add('αβγ Å', 0, -2, 0, 0) + textBuilder.add('Hello world', 0, 0, 0, 0, 0) + textBuilder.add('Добрый день', 0, 1, 0, 0, 0) + textBuilder.add('美好的一天', 0, 2, 0, 0, 0) + textBuilder.add('¿Cómo estás?', 0, -1, 0, 0, 0) + textBuilder.add('αβγ Å', 0, -2, 0, 0, 0) const text = textBuilder.getText() const values = Text.Utils.createValuesSimple(text, props, Color(0xFFDD00), 1)