Serialization using JSON.stringify() stores Vector3 as something like
{“_isDirty”:true,“_x”:1,“_y”:2,“_z”:3}
Deserialization, using JSON.parse(), does not creat an instance of Vector3.
see
https://playground.babylonjs.com/#R1F8YU#1561
https://playground.babylonjs.com/#R1F8YU#1563
let vs = JSON.stringify(v);
console.log(vs);
let v2_data = JSON.parse(vs);
let v2 = new BABYLON.Vector3(v2_data.x, v2_data.y, v2_data.z);
console.log(v2 instanceof BABYLON.Vector3);
let v3 = v2.add(v);
console.log(JSON.stringify(v3));
thats a workaround , not a soln.
Proposal: Improve Vector3 JSON Handling
The issue users face with v2.add is not a function after JSON.parse() is a JavaScript feature, not a Babylon.js bug; JSON.parse() doesn’t restore class methods.
To provide a cleaner solution, I propose adding two methods to the BABYLON.Vector3 class:
1. Parse(data) Static Method
Allows easy reconstruction of a Vector3 from JSON data.
/**
* Creates a new BABYLON.Vector3 instance from data or JSON string.
*/
public static Parse(data: any): BABYLON.Vector3 {
const parsedData = typeof data === 'string' ? JSON.parse(data) : data;
const x = parsedData.x ?? parsedData._x;
const y = parsedData.y ?? parsedData._y;
const z = parsedData.z ?? parsedData._z;
if ([x, y, z].includes(undefined)) throw new Error("Invalid Vector3 data.");
return new BABYLON.Vector3(x, y, z);
}
2. toJSON() Instance Method
Ensures JSON.stringify() outputs clean properties ({x, y, z}).
/**
* Serializes the Vector3 instance into a clean JSON object.
*/
public toJSON(): any {
return { x: this.x, y: this.y, z: this.z };
}
Yeah right, how dare they not fixing the stupid ECMA script specification that cannot handle Babylon data structures.
You already have toArray and fromArray. Users have to manage de/serialization in their code anyway. So whether they call toJson / toArray does not seem to matter too much. Adding another toJson seems redundant. The Vector interface is quite big alredy.
I agree with you. I was just suggesting a way to simplify life; I didn’t realize how widespread this problem is. I haven’t encountered it myself; I apply data to Vectors quite selectively.
But the beauty of BabylonJS is that it is very compact, and we must try to keep it clean and simple.
Why would JSON.Parse return the class instance? It just turns strings into objects it does not instantiate anything.
const stringV3 = JSON.stringify(new BABYLON.Vector3(1, 2, 3))
const parseV3 = (string) => {
const temp = JSON.parse(string)
return new BABYLON.Vector3(temp._x, temp._y, temp._z)
}
const v3 = parseV3(stringV3)
Just make a support function?
Why not relying on asArray and fromArray which is what we use in the babylon format for conciseness ?
JSON is a standard library utility unaware of any babybylon structures or even its existance.
You need to use serialization and parsing facilities provided by babylon.
They work for some big entities like meshes, transformnodes, gui controls and other stuff, but not for individual vectors.
However, vector properties of objects are serialized/parsed (as long as they are marked by @serializable in class definition)
What ! BabylonJS is not an ECMA standard !![]()
On a serious note though, you guys are right.
I did not think through this properly.
Thanks for weighing in.