Hi
Bad news first: I cannot replicate this issue Whatever I do in the playground, I cannot replicate it. As you can see here https://playground.babylonjs.com/#MZ7QRG#2267 I investigated issues with transparency, animations, bones, and overlapping meshes.
But since there is a good chance there might be a real bug (typecast issue?) I hope this code-only post is alright.
So, when I call
linesUnique.forEach((line, i)=>{
this.scene.MeshBuilder.CreateLines("WalkableAreaBorderSegment"+i, {points: [line.a, line.b], material: this.material})
});
with the material parameter set, I get:
Uncaught TypeError: Cannot create property '_needNormals' on string '#define NUM_BONE_INFLUENCERS 0\n#define GLOW'
I was able to trace it to class StandardMaterial.isReadForSubmesh at the call to MaterialHelper.PrepareDefinesForLights.
It appears that subMesh.materialDefines, that normally is an object of properties, gets stringified somehow. In StandardMaterial.isReadForSubmesh, it comes in already as string but should be of Type âStandardMaterialDefinesâ as declared at the top of standardMaterial.ts.
Console.logging âsubMesh.materialDefinesâ indicates that it mostly is undefined and gets assigned a new instance of type StandardMaterialDefines. Except in case of the error described where it comes in as string.
The error does not occur if I leave out the material parameter. All lines render just fine.
The error occurs right at the first lines mesh (i==0). It occurs the first time I run my code.
When the error occurs you briefly see a couple of lines rendered, and then the screen goes blackâish / dark blueâish.
Included below is my code triggering the exception.
FYI: latest Babylon (just downloaded from NPM), latest Chrome.
Please let me know if you need any more information.
Best wishes
Joe
Appendix
// never mind it's dirty and unoptimised; not sure if I keep that feature in
import {ReachableTiles} from "../sceneControllers/PlayerPositionController.js";
type Line = {a:Vector3, b:Vector3}
export default class WalkableArea {
private scene;
private meshes = [];
private material;
public constructor(scene) {
this.scene = scene;
this.material = new this.scene.StandardMaterial("WalkableAreaTileMaterial");
this.material.diffuseColor = this.scene.Color3.Blue();
//this.material.alpha = 0.3;
//this.material.alphaMode = 1;
}
public show(tiles : ReachableTiles, tileSize = 1) {
const included : Vector3[] = [];
const temp = this.scene.Vector3.Zero();
tiles.forEach((short)=>{
included.push(new this.scene.Vector3(short[1], short[2]+0.05, short[3]))
});
function comparePoint(p1, p2) {
return p1.x === p2.x && p1.z === p2.z;
}
function compareLines(l1, l2) {
return (comparePoint(l1.a, l2.a) && comparePoint(l1.b, l2.b)) ||
(comparePoint(l1.b, l2.a) && comparePoint(l1.a, l2.b));
}
const linesAll : Line[] = [];
const linesUnique : Line[] = [];
const tileHalf = 0.5;
for(let i=0; i<included.length; i++) {
const x = included[i].x;
const y = included[i].z;
const h = included[i].y;
const north = {
a: temp.clone().set(x-tileHalf, h, y-tileHalf),
b: temp.clone().set(x+tileHalf, h, y-tileHalf)
};
const south = {
a: temp.clone().set(x-tileHalf, h, y+tileHalf),
b: temp.clone().set(x+tileHalf, h, y+tileHalf)
};
const east = {
a: temp.clone().set(x+tileHalf, h, y-tileHalf),
b: temp.clone().set(x+tileHalf, h, y+tileHalf)
};
const west = {
a: temp.clone().set(x-tileHalf, h, y-tileHalf),
b: temp.clone().set(x-tileHalf, h, y+tileHalf)
};
linesAll.push(north, east, south, west);
}
for(let i=0; i<linesAll.length; i++) {
const testLine = linesAll[i];
const count = linesAll.filter((line)=>(compareLines(testLine, line)));
if(count.length === 1) {
linesUnique.push(linesAll[i]);
}
}
console.log({linesUnique})
linesUnique.forEach((line, i)=>{
//@ts-expect-error //no pun intended
if( !(line.a instanceof BABYLON.Vector3) ) {
throw new Error(i+" line.a");
}
//@ts-expect-error
if( !(line.b instanceof BABYLON.Vector3) ) {
throw new Error(i+" line.b");
}
this.scene.MeshBuilder.CreateLines("WalkableAreaBorderSegment"+i, {points: [line.a, line.b], material: this.material, updatable: false})
});
}
}