Updated how labels and text meshes are created/updated. Removed duplicates.

This commit is contained in:
Michael Mainguy 2024-04-17 15:00:52 -05:00
parent 469d4a5116
commit 2387fe53ef
3 changed files with 126 additions and 6 deletions

View File

@ -1,4 +1,14 @@
import {AbstractMesh, Color3, DynamicTexture, Material, MeshBuilder, StandardMaterial} from "@babylonjs/core"; import {
AbstractMesh,
Color3,
DynamicTexture,
Material,
Mesh,
MeshBuilder,
Scene,
StandardMaterial,
Vector3
} from "@babylonjs/core";
import log from "loglevel"; import log from "loglevel";
@ -10,10 +20,11 @@ export function updateTextNode(mesh: AbstractMesh, text: string) {
return null; return null;
} }
const textNodes = mesh.getChildren((node) => { const textNodes = mesh.getChildren((node) => {
return node.metadata?.text == true; return node.metadata?.label == true;
}); });
if (textNodes && textNodes.length > 0) { if (textNodes && textNodes.length > 0) {
textNodes.forEach((node) => { textNodes.forEach((node) => {
node.parent = null;
node.dispose(false, true); node.dispose(false, true);
}); });
} }
@ -23,7 +34,7 @@ export function updateTextNode(mesh: AbstractMesh, text: string) {
} }
//Set font //Set font
const height = 0.05; const height = 0.08;
const font_size = 24; const font_size = 24;
const font = "bold " + font_size + "px Arial"; const font = "bold " + font_size + "px Arial";
//Set height for dynamic texture //Set height for dynamic texture
@ -39,19 +50,22 @@ export function updateTextNode(mesh: AbstractMesh, text: string) {
//Calculate width the plane has to be //Calculate width the plane has to be
const planeWidth = DTWidth * ratio; const planeWidth = DTWidth * ratio;
temp.dispose();
//Create dynamic texture and write the text //Create dynamic texture and write the text
const dynamicTexture = new DynamicTexture("DynamicTexture", { const dynamicTexture = new DynamicTexture("DynamicTexture", {
width: DTWidth, width: DTWidth,
height: DTHeight height: DTHeight
}, mesh.getScene(), false); }, mesh.getScene(), false);
dynamicTexture.drawText(text, null, null, font, "#ffffff", "#000000", true);
const mat = new StandardMaterial("mat", mesh.getScene()); const mat = new StandardMaterial("mat", mesh.getScene());
mat.diffuseColor = Color3.Black(); mat.diffuseColor = Color3.Black();
mat.disableLighting = true; mat.disableLighting = true;
mat.backFaceCulling = true; mat.backFaceCulling = true;
mat.emissiveTexture = dynamicTexture; mat.emissiveTexture = dynamicTexture;
mat.freeze();
//mat.emissiveColor = Color3.White(); //mat.emissiveColor = Color3.White();
dynamicTexture.drawText(text, null, null, font, "#ffffff", "#000000", true);
//Create plane and set dynamic texture as material //Create plane and set dynamic texture as material
//const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene()); //const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene());
const plane1 = createPlane(mat, mesh, text, planeWidth, height); const plane1 = createPlane(mat, mesh, text, planeWidth, height);
@ -77,6 +91,22 @@ function createPlane(mat: Material, mesh: AbstractMesh, text: string, planeWidth
} else { } else {
plane.position.y = yOffset + (height * plane.scaling.y); plane.position.y = yOffset + (height * plane.scaling.y);
} }
//plane.addLODLevel(5, getDistantPlane(mesh.getScene(), plane.scaling, planeWidth, height));
plane.addLODLevel(3, null);
return plane; return plane;
} }
let distantPlane = null;
function getDistantPlane(scene: Scene, scaling: Vector3, planeWidth: number, planeHeight: number): Mesh {
//if (distantPlane == null) {
distantPlane = MeshBuilder.CreatePlane("distantPlane", {width: planeWidth, height: planeHeight}, scene);
distantPlane.scaling = scaling;
//distantPlane.scaling.y = distantPlane.scaling.y /4;
const material = new StandardMaterial("distantPlaneMaterial", scene);
material.emissiveColor = Color3.White()
material.freeze()
distantPlane.material = material;
// }
return distantPlane;
}

View File

@ -0,0 +1,78 @@
import {
Color3,
DynamicTexture,
InstancedMesh,
Mesh,
MeshBuilder,
Scene,
StandardMaterial,
TransformNode
} from "@babylonjs/core";
import {DefaultScene} from "../defaultScene";
export class TextMeshGenerator {
private _scene: Scene;
private _textMeshes: Map<string, Mesh> = new Map<string, Mesh>();
constructor() {
this._scene = DefaultScene.Scene;
this.initialize();
}
public getMesh(input: string): TransformNode {
const transformNode = new TransformNode("textMesh-" + input, this._scene);
let x = 0;
for (const char of input) {
const mesh = new InstancedMesh("instance_" + input, this._textMeshes.get(char));
mesh.parent = transformNode;
x = x + Math.abs(mesh.getBoundingInfo().boundingBox.minimum.x);
mesh.position.x = x;
x = x + mesh.getBoundingInfo().boundingBox.maximum.x;
}
return transformNode;
}
public generateCharMesh(input: string): Mesh {
console.log("Generating text mesh for: " + input);
//Set font
const height = 0.05;
const font_size = 28;
const font = "bold " + font_size + "px Arial";
//Set height for dynamic texture
const DTHeight = 1.5 * font_size; //or set as wished
//Calc Ratio
const ratio = height / DTHeight;
//Use a temporary dynamic texture to calculate the length of the text on the dynamic texture canvas
const temp = new DynamicTexture("DynamicTexture", 32, this._scene);
const tmpctx = temp.getContext();
tmpctx.font = font;
const DTWidth = tmpctx.measureText(input).width + 8;
//Calculate width the plane has to be
const planeWidth = DTWidth * ratio;
const dynamicTexture = new DynamicTexture("DynamicTexture", {
width: DTWidth,
height: DTHeight
}, this._scene, false);
dynamicTexture.drawText(input, null, null, font, "#ffffff", "#000000", true);
temp.dispose();
const mat = new StandardMaterial("mat", this._scene);
mat.diffuseColor = Color3.Black();
mat.disableLighting = true;
mat.backFaceCulling = true;
mat.emissiveTexture = dynamicTexture;
const plane = MeshBuilder.CreatePlane("character" + input, {width: planeWidth, height: height}, this._scene);
plane.material = mat;
return plane;
}
private initialize() {
for (let i = 32; i < 127; ++i) {
const mesh = this.generateCharMesh(String.fromCharCode(i));
this._textMeshes.set(String.fromCharCode(i), mesh);
}
}
}

View File

@ -71,6 +71,18 @@ export class VrApp {
}) })
} }
this.logger.info('keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer'); this.logger.info('keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer');
/*
const textGen = new TextMeshGenerator();
let y = .1;
for (let i = 0; i < 1000; i++) {
const text = textGen.generateCharMesh("hijklmnop Hello World");
text.position.y = y;
text.position.z = -5;
text.rotation.y = Math.PI;
y+=.1;
}
*/
let i = 0; let i = 0;
this.engine.runRenderLoop(() => { this.engine.runRenderLoop(() => {
scene.render(); scene.render();