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

Unknown node type 'ProtoDeclare' 'ProtoBody' 'InstancedShape' #175

Closed Wagyx closed 6 months ago

Wagyx commented 6 months ago

Hello there, I would like to test the Proto stuff and the InstancedShape but they throw an error when creating them with JavaScript. Here is the code.

init();
function init() {
    const xBrowser = X3D.getBrowser();
    const scene = xBrowser.currentScene;

    const protoDeclare = scene.createNode("ProtoDeclare");
    const protoBody = scene.createNode("ProtoBody");
    const instShape = scene.createNode("InstancedShape");
}

Am I missing a kind of include or setting somewhere ?

create3000 commented 6 months ago

Prototype can only be created using declarative syntax, they are not made to be created per scripting. You would create a function which returns one or more nodes, which is almost what a prototype does.

Wagyx commented 6 months ago

Okay, what about InstancedShape ? I would like to display thousands of spheres and cylinders in the scene with a specific transform for each. For now, I am creating thousands of shapes making the browser slow to load and decreasing the framerate. What if I use fromXmlString to load a node ? I could also create the geometry for one sphere myself and duplicate and merge them into a large TriangleSet. I'll be trying these solutions today, will report back on what works. If you have other ideas about what might work, please let me know.

create3000 commented 6 months ago

InstancedShape is made for this task. Of course you can use Browser.createX3DFromString to load a data with a protoype.

const scene = await browser .createX3DFromString (`PROTO Foo [
# fields come here
]
{
# Body comes here
}`);

// Now create an instance:
const instance = scene .createProto ("Foo");
Wagyx commented 6 months ago

Okay, I have tried the InstancedShape in a simple X3D scene. No JS is involved. I noticed that you need to add a header with a X_ITE component before the Scene tag like so:

<head>
    <component name='X_ITE' level='1'/>
</head>

Otherwise I get the following error in the Chrome browser and the Shape does not display

XML Parser: Unknown node type 'InstancedShape', you probably have insufficient component/profile statements and/or an inappropriate specification version.

I am just putting this here in case it helps other people. I guess the InstancedShape is not standard X3D and I missed the place in the doc where this component stuff was indicated.

Wagyx commented 6 months ago

Found it in the InstancedShape description ... Just need to find how to tell the browser to use this component with JS now.

Wagyx commented 6 months ago

This works for modifying the header

    const comp = xBrowser.getComponent ("X_ITE", 1);
    scene.addComponent(comp);

But I still get Unknown node type 'InstancedShape' when creating the node const instShape = scene.createNode("InstancedShape");

create3000 commented 6 months ago
const scene = await browser .createX3DFromString (`

COMPONENT X_ITE : 1

PROTO Foo [
# fields come here
]
{
# Body comes here
}`);

// Now create an instance:
const instance = scene .createProto ("Foo");

Add a component statement like the above.

create3000 commented 6 months ago

If you do it in the parser, you must first load the components:

scene .addComponent (browser .getComponent (componentName));

this .loadComponents () .then (() =>
{
     this .resolve (scene);
})
.catch (this .reject);

Where loadComponents is defined in X3DParser.

Wagyx commented 6 months ago

Thank you very much, that did the trick ! Is there a way to change the color of each instance ? Defining a color array in the material perhaps ? or having a colors property in the instancedShape like the rotations would be pretty neat.

create3000 commented 6 months ago

No this is not possible. If you have only a few colors, you could create a InstancedShape node for every color, otherwise you can create one big geometry with all faces and colors.