Updated how labels and text meshes are created/updated. Removed duplicates.
This commit is contained in:
parent
469d4a5116
commit
2387fe53ef
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
78
src/util/textMeshGenerator.ts
Normal file
78
src/util/textMeshGenerator.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
12
src/vrApp.ts
12
src/vrApp.ts
@ -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();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user