Matrix.copyFrom stopped to work starting alpha-48

Hi!
Some of you already know that @labris and me are working on the YUKA - A JavaScript library for developing Game AI BabylonJS examples. After switching to BabylonJS 5 beta the Matrix.copyFrom method started to cause issues, our AI vehicles has stopped to move. @labris have found out that something has changed in alpha-48 and that the updateFlag is still the same after using the copyFrom method. We are heavily relying on this method in almost all the examples.

A quick inspection of the BJS 5 Matrix source code revealed, that the updateFlag is copied from the source matrix to the destination matrix.

To be more precise we are copying the matrix data from a YUKA.Matrix and it doesn’t have the updateFlag, obviously. If I update the updateFlag manually, it is working. EDIT: I made a mistake here explaining how it works. :roll_eyes: Actually I create a new BABYLON.Matrix instance at startup. I copy the values from YUKA.Matrix to the BABYLON.Matrix at every frame and I use the copyFrom method from the BABYLON.Matrix I created at startup (it’s the same instance) to the AI vehicle (TransformNode) BABYLON.Matrix.

Is this guys a bug or was it an intention to change the behaviour of this method? If it’s an intention is this ‘hack’ the proper way to mark the matrix ‘dirty’?

I tried to search on the forum but I didn’t find anything about this issue.

Thank you! :vulcan_salute:
r.

1 Like

To be more precise:
All is working with https://cdnjs.cloudflare.com/ajax/libs/babylonjs/5.0.0-alpha.47/babylon.js
Since alpha 48 it stops to work - https://cdnjs.cloudflare.com/ajax/libs/babylonjs/5.0.0-alpha.48/babylon.js
I believe it is somehow related to these commits - Search · updateFlag · GitHub

This line will work from alpha-48 and later

matrix.copyFrom(entityMatrix)

only if add

matrix.updateFlag = updateFlag++

In the API docs - Matrix | Babylon.js Documentation - matrix.copyFrom returns the current updated matrix. And it was so before alpha-48.

1 Like

@bghgary, can you have a look, it looks you worked on this one ?

@labris there is definitely smth going on here.

1 Like

Are you saying you are calling copyFrom with a parameter that is not a BABYLON.Matrix?

Is entityMatrix here not a BABYLON.Matrix?

If this is true, you should probably use Matrix.FromArrayToRef to copy the matrix values.

@labris, sorry for stealing this one. It’s a:

 const entityMatrix = new BABYLON.Matrix()

The code is:

      function sync(entity, renderComponent) {
        entity.worldMatrix.toArray(entityMatrix.m)
        const matrix = renderComponent.getWorldMatrix()
        matrix.copyFrom(entityMatrix)
        matrix.updateFlag = updateFlag++
      }

entity.worldMatrix is the YUKA entity world matrix.
renderComponent is the mesh

You are totally right
This is a bug of Matrix.copyFrom

I’ll fix it!

2 Likes

fix matrix caching updte by deltakosh · Pull Request #11883 · BabylonJS/Babylon.js (github.com)

Won’t that PR result in the matrix with the copied values always being thought different from the source, even if nothing was changed after copying its values? IOT wouldn’t below always be true, even if the matrix values were still the same?

if (matrix.updateFlag !== copiedMatrix.updateFlag) {

Maybe the problem is calling toArray(entityMatrix.m), which alters the matrix directly without changing its updateFlag, so the update flag is always the same unless they change it manually?

1 Like

updateflag is local. It is not an indicator of matrix equality.
It is a way to indicate to external matrix users that the matrix data changed

So copying it in the first place was wrong :slight_smile:

example: scene.ts - GitHub Code Search

1 Like

Here’s the documentation for updateflag which seems to say that it can be used for that purpose thou:
“You can use it to speed the comparison between two versions of the same matrix.”

Or maybe I am misunderstanding it, but it seems that before the PR you could tell if a matrix’s values had been changed after copying them by comparing the two matrices’ update flags…In other words you could compare the matrix with the copied values to the matrix that it was copied from, testing for equality without having to compare all 16 values, by just comparing their flags. :slight_smile:

This is the same object that I was talking about in the doc. Not two entities with same internal values.

Because think about this case:

  • Let’s say we sync the updateFlag during the copy
  • There is a chance that the new updateflag of the receiving matrix will be the same as before ending with an issue
  • What happened if I update Matrix A and B just once each? They will still have the same updateFlag but they will not be the same.

In a nutshell: UpdateFlag is local to each matrix. It only captures if the matrix data changed since the last time you checked (and saved) its flag

The update flags will be different because a static/global seed is incremented, not each matrix’s flag? Currently, after copying the values the flags were equal until one or both matrices was changed, so one could test the flags instead of all 16 elements, unless I’m misunderstanding something?

public _markAsUpdated() {
        this.updateFlag = Matrix._updateFlagSeed++;

Well yes you are correct. It is an interesting side case I was not thinking about. (I forgot about the global counter…I’m getting old).

The problem is that if flags are different it does NOT necessary means the matrices are different (from their values). So it is a risky model to promote the use of the flag to test for equality

1 Like

If _markAsUpdated was made public and was called after modifying the matrix values directly then I think it would work, LOL I didn’t realize it was a side effect thou, it seemed intentional copying the flag value over that way so I made some misassumptions I guess. :slight_smile:

I think we can safely say that if the updateFlag are the same, then the matrices have the same values. Having different updateFlags doesn’t mean they are same or different.

Yes but this is not as simple as I would love it to be. Hence my preference to not use it in the copyFrom

But I’m ok to revert my change. Then we need to better understand by @labris has an issue