create3000 / x_ite

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

Way to get the DEFines for all viewpoints in VRML screne in an array #183

Open olafgithub opened 2 hours ago

olafgithub commented 2 hours ago

Hi,

When I have a VRML scene: ... ... DEF "VP_1" Viewpoint { .... } DEF "VP_2" Viewpoint { .... } DEF "VP_3" Viewpoint { .... } ... ...

Is there an elegant way with Javascript running on the HTML page to create an array like:

const vp_def = [ "VP_1", "VP_2", "VP_3", ... ... ]

That is without duplicating everything, just by accessing the VRML scene. The X_ITE browser does something similar to create the list of Viewpoints in the context menu from the viewpoint's description.

Thanks,

Olaf

create3000 commented 2 hours ago

Maybe this is something for you:

const scene = Browser .currentScene;
const viewpoints = Array .from ({ length: 10 }, (_, i) => scene .getNamedNode (`VP_${i}`));
olafgithub commented 2 hours ago

That would only work if all the VP definitions were in the same format and also in order.

I like to use a more generic way to find each Viewpoint node in the VRML scene in order and get the DEFine for it. just as you do to fill in the right-click menu with the description of the Viewpoint. The order should be the same as presented in the right-click menu.

My example was a bit too easy :-)

I was looking for a way to do it like it is possible with HTML:

buttons = document.querySelectorAll( '[is-button]' )

Olaf

create3000 commented 1 hour ago

Another way to get some or all viewpoints is this, but the viewpoints will be in no particular order:

const scene = Browser .currentScene;
const viewpoints = [... scene .namedNodes] .filter (node => node .getNodeType () .includes (X3DConstants .X3DViewpointNode));

The DEF name can be accessed using node .getNodeName ().

I think what you are really looking for is a traverse function, you can start at scene .rootNodes check the field definitions of each node to traverse its children (SFNode and MFNode field) and so on. During this you can check the type or name.

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

olafgithub commented 1 hour ago

Thanks for the very fast answer.

I will look into it. Renaming the VPs to VP_1 ... VP_109 may be the easier solution for this particular thing. I did it before and it works fine. I had to fill an HTML select element. (Dropdown thing) with the description of the Viewpoints.

Olaf

create3000 commented 1 hour ago

Another way would be to collect all viewpoints is to create a invisible Group with the USEd viewpoints:

DEF Viewpoints Group {
   visible FALSE
   children [USE VP1, USE VP2, ...]
}

You can then access this node with scene .getNamedNode ("Viewpoints").

olafgithub commented 52 minutes ago

That is a clever way, but you must duplicate all the DEF names: one in the definition and once in the Group. But at least it is all in the VRML file.

I hoped there was a clever and elegant way to retrieve ALL viewpoints from a VRML scene without the need to edit the VRML file, and without the need to duplicate the DEF names.

Mmm...

Maybe:

DEF Viewpoints Transform { children [ DEF VP_Entry Viewpoint{ ... } DEF VP_Room1 Viewpoint{ ... } DEF VP_Room2 Viewpoint{ ... } ... ... DEF VP_Exit Viewpoint{ ... } ] }

and then:

scene .getNamedNode ("Viewpoints").

I noticed that you can have all the Viewpoints enclosed by a Transform and move and rotate all the viewpoints at once.

Have a nice weekend,

Olaf