create3000 / x_ite

X_ITE X3D Browser, view and manipulate X3D, VRML, glTF and other 3D sources in HTML.
https://create3000.github.io/x_ite/
Other
67 stars 15 forks source link

Question: Is it possible to build nodes in JavaScript and add them to a scene? #151

Closed gwhitney closed 1 year ago

gwhitney commented 1 year ago

I mean, other than by parsing a URL or a string, e.g. by createX3DFromString -- I have successfully parsed a string into a dummy scene, and then traversed the node tree starting from scene.rootNodes and extracted nodes and inserted them into the currentScene of a browser. But I meant by calling node constructor functions and supplying field values, all within JavaScript. (Two points of motivation -- if I have a data structure that corresponds well to X3D's node hierarchy, it seems wasteful to generate a string from it and then have x_ite re-parse that string; and second, for adding just a node now and then, it seems like I could do it synchronously, whereas I have to await the createX3DFromString operation.)

I note that on the X3D object, there is a property with the same name as each node type that seems to work as a constructor. I tried new X3D.Cylinder(scene) and it produced a JavaScript entity that looked reasonable to be a Cylinder in the console. I called the .intialize() method on the resulting object, as that seemed to be necessary. But when I set the geometry field of the only Shape node in my scene to this Cylinder (with ordinary JavaScript assignment), I couldn't see anything, only an all-black browser.

Is generating nodes in JavaScript and inserting them into a scene a reasonable thing to try to do? Are there any examples out there of doing so? I tried to look through the documentation site and this repository, but couldn't find anything. Thanks for thoughts/pointers.

create3000 commented 1 year ago

There is the official way to programmatically create nodes:

const scene    = browser .currentScene;
const cylinder = scene .createNode ("Cylinder");

cylinder .height = 4.2;
someShape .geometry = cylinder;

If this is not enough you can create PROTOs: https://create3000.github.io/x_ite/tutorials/improving-performance#use-prototypes

If this is not enough there are ways to extend X_ITE with "real" custom nodes.

gwhitney commented 1 year ago

Aha, I had tried new X3D.SFNode('Cylinder { height 4.2 }') but the documentation warned it would throw an error if called directly, and it did throw. So I thought there must be some other way to manufacture nodes, but I missed it in Scene services -- thanks for the pointer! (One possible suggestion would be to add a sentence like "Try using scene.createNode() instead.", next to the comment that X3D.SFNode will error.)

create3000 commented 1 year ago

Thanks for the hint, I have updated the documentation in this way.

https://create3000.github.io/x_ite/reference/field-services-and-objects#sfnode-object

gwhitney commented 1 year ago

(As far as I am concerned, this issue is complete -- I can create the objects I need now. Did you want me to close it? Or perhaps you are leaving it open on purpose for others to see the answer?)

create3000 commented 1 year ago

If an issue is complete I want to close it normally, either I do or you can do. There is still the possibility to reopen an issue if there are further questions to talk about.