Strange Multimaterial behavior

Hi folk! )

Please, explain mе behavior of Multymaterial. I noticed .subMaterials property return not only subMaterials, but also two function. Try and get:

In console:
var mm = new BJS.MultiMaterial(‘name’, myScene);
mm.subMaterials
out: [push: ƒ, splice: ƒ]

what i don’t understand?

Hiya Blax.

Let’s look here: MultiMaterial.ts line 28.

When mm.subMaterials is “set” (given members), a special func called ._hookArray() is called.

Scroll down to line 57 area, and we see line 59 installing a CUSTOM .push() method onto that array.

Scroll down to line 68, and we see a custom .splice() method installed, too. Those two custom Array-class methods… are what you are seeing.

Now, as-for WHY that was done/needed, I dunno. Possibly, it is because the author wanted to “insert” an automatic call to this._markAllSubMeshesAsTexturesDirty(); whenever anyone used push() or splice()… on a mm.subMaterials array.

Stay tuned for more comments about that, if you need more info.

2 Likes

Thank you, @Wingnut for help, but i anyway dont understand why with submaterials ( we wait array with submaterials) we get some functions to in this array. Perhaps bug? Look at 22 - return only array with mat. Mystic…

Not true. It returns a CUSTOMIZED array. https://www.babylonjs-playground.com/#2Q4S2S#52

Line 43 reports:

get subM: 
(3) […]
​0: Object { checkReadyOnEveryCall: false, checkReadyOnlyOnce: false, _alpha: 1, … }
​1: Object { checkReadyOnEveryCall: false, checkReadyOnlyOnce: false, _alpha: 0.3, … }
​2: Object { checkReadyOnEveryCall: false, checkReadyOnlyOnce: false, _alpha: 0.3, … }
​length: 3
​push: function push()
​splice: function splice()

Yes, still an array, but with CUSTOM/special push() and splice() methods.

I see no bug possibility, here. Customized array seems to be acting correctly.

Do you need a STANDARD version of subMaterials array, for some reason?

I think THAT is the reason it was coded.

Please re-explain/re-word your reasons for thinking it is a bug, if I haven’t addressed those. I am no pro, and I may be mis-understanding your thoughts/words.

We welcome comments from others, too… esp if I am telling Blax wrong things. I don’t like telling people wrong things. :slight_smile:

1 Like

Customization of the array is clear idea, but then how to use such an entity?
Why methods are placed near the nodes of the scene?

Say it is necessary to iterate on submaterials in materials. Usually we write: for (var index in myMulitiMat) {…

In this case, we will receive “mixed content” ). It would be logical to wrap all the materials with one key in this case. Or collect only submaterial in getSubmaterials method

The documentation says that we should expect an array of materials, and nothing more:
subMaterials: Nullable /Material/ [ ]

But I’m not sure … maybe it should be, but rather not, than yes.

@Wingnut, thank you for attention and help!

Not true. The custom push() and splice() are not inside the array’s “data storage tank”. :slight_smile:

Did you test it? https://www.babylonjs-playground.com/#2Q4S2S#53 Lines 43-45… standard iteration… returns 3 items, not 5. console.log(multimat.subMaterials.length) returns 3, not 5. It is acting exactly like any other JS Array-class object.

For YOUR purposes… I think you can simply ignore the existence of the custom push and splice. Just pretend it is a standard array.

Array objects have MANY methods… but most of them are not shown to us when we “dump” the array to console (unless you click-on the grayed-out __proto__: Array [] link at the bottom of the console dump).

If you ask WHY those two custom funcs are shown to us… when we dump the array to console… that I do not know.

Speculation: Normally, you can see ALL the methods on the Array-class object… by looking at its “prototype” layer. When author installed these custom funcs, they were installed “above” the prototype layer, and therefore… those 2 funcs are shown to us… with a standard dump. That’s just a theory of mine, and is not backed-up by any knowledge of prototypes. :slight_smile:

Perhaps others will comment, soon. I’m not sure that I am answering well. Did you want @Deltakosh or others who are JS pro… to comment? I’m sure they would be glad to do so.

In general, you need-not be concerned that it is a custom array. It will have near-identical functionality as any other array.

Are the custom functions conflicting-with your scene coding, somehow? (other than showing their names in the console dump). If so, tell us how.

1 Like

Ok, I understood (I thought I understood prototyping in JS, but now I’m not sure)
In any case, I think that the user of the engine can wait for other results for the iterator “in”), maybe I will understand this later.

%D0%92%D1%8B%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_023

%D0%92%D1%8B%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_022

Blockquote
Are the custom functions conflicting-with your scene coding, somehow? (other than showing their names in the console dump). If so, tell us how.

only one problem - not understand ( we can always use other iterators )
Thank you for help, I still have a lot to learn! )