[x3d-public] Row/column-order in the SFMatrix*, MFMatrix* fields, I think X3DOM reading order contrasts to what spec says

Michalis Kamburelis michalis at castle-engine.io
Sun Nov 23 02:53:26 PST 2025


An update about this: It seems I was confused. Disregard parts / all of my last email! And what X3DOM is doing is correct.

Thanks to Elmar, the reporter of https://github.com/castle-engine/castle-model-viewer/issues/122 , he pointed me to a statement in X3D spec:

"Since these data types are commonly used for 3D transformation matrices, translation values are stored in the fourth row"

So this contradicts some of my statements in the last mail, sorry for the noise!

This means that the right way to specify translation by (1,2,3) in a matrix in X3D is

1 0 0 0
0 1 0 0
0 0 1 01 2 3 1

This means that

- VRML 1.0 and X3D way of storing matrix in a file is the same.
- X3DOM approach is correct.
- Castle Game Engine / Castle Model Viewer past approach was correct, and my "fix" last week actually made it invalid... argh, I made a bubu :) I have now reverted my change.
- _Now_ Castle Game Engine / Castle Model Viewer approach is again correct, and matching X3DOM.

Sorry everyone for the noise :) I'm smarter now, and happy to have people testing Castle Game Engine / Castle Model Viewer and quickly pointing out my mistake! :)

I have updated the docs and testcases to be all correct, so maybe at least this helps someone to validate their browsers:

- https://github.com/castle-engine/castle-engine/tree/master/tests/data/matrix_vrml_x3d_format
- testcases:
- https://github.com/castle-engine/demo-models/blob/master/x3d/matrix_transform.x3d
- https://github.com/castle-engine/demo-models/blob/master/x3d/matrix_transform.x3dv - https://github.com/castle-engine/demo-models/blob/master/x3d/matrix_transform_x3dom.html

Regards,
Michalis
On Sunday, November 23rd, 2025 at 01:38, Michalis Kamburelis <michalis at castle-engine.io> wrote:

> Short version: Let's make sure our X3D browsers honor the order of values when reading SFMatrix*, MFMatrix* fields :)
>
> - Classic encoding link: https://www.web3d.org/documents/specifications/19776-2/V3.3/Part02/EncodingOfFields.html#SFMatrix4f
>
> - XML encoding link, saying the same:https://www.web3d.org/documents/specifications/19776-1/V3.3/Part01/EncodingOfFields.html#SFMatrix4f
>
> Longer version:
>
> I recently found a mistake in Castle Game Engine's SFMatrix*, MFMatrix* reading/writing code. We were following VRML 1.0 order, while the X3D order (according to both classic and XML encodings specs) is different. So I fixed it, and now Castle Game Engine and Castle Model Viewer follow the proper X3D spec order (when reading/writing X3D).
>
> Namely, X3D classic encoding spec unambiguously says:
>
> """
> The first four single-precision floating point numbers represent the top row of the matrix.
> The second four single-precision floating point numbers represent the second row of the matrix.
> """
>
> Classic encoding link: https://www.web3d.org/documents/specifications/19776-2/V3.3/Part02/EncodingOfFields.html#SFMatrix4f
>
> XML encoding link, saying the same:https://www.web3d.org/documents/specifications/19776-1/V3.3/Part01/EncodingOfFields.html#SFMatrix4f
>
> So this means that e.g. translation by 1 2 3 is encoded in X3D in a way that looks similar to how you would write it in math expressions:
>
> 1 0 0 1
> 0 1 0 2
> 0 0 1 3
> 0 0 0 1
>
> For example, using MatrixTransform node (extension supported by at least Castle Game Engine, X3DOM, Instant Reality), to move object by 1 2 3 you would write this:
>
> MatrixTransform {
> matrix
> 1 0 0 1
> 0 1 0 2
> 0 0 1 3
> 0 0 0 1
> children Shape {
> appearance Appearance {
> material Material { diffuseColor 0 1 0 }
> }
> geometry Sphere { }
> }
> }
>
> To complicate testing a bit,
>
> - VRML 1.0 and X3D specifications here say the opposite things. And VRML 2.0 specification doesn't have a matrix field type. So it's probably easy to make the same mistake I did :) See my docs about it on https://github.com/castle-engine/castle-engine/tree/master/tests/data/matrix_vrml_x3d_format .
>
> - Moreover, not many nodes in spec actually use the matrix field types. Again, see https://github.com/castle-engine/castle-engine/tree/master/tests/data/matrix_vrml_x3d_format where I listed the ones that do. The MatrixTransform, shown above, is only an extension (and I do _not_ propose to make it part of spec; we should encourage authors to use cleaner Transform).
>
> I have been testing MatrixTransform in X3DOM, and I think X3DOM has a bug (just like CGE did, a month ago!) and it expects matrix in transposed order. See testcase on https://github.com/castle-engine/demo-models/blob/master/x3d/matrix_transform_x3dom.html -- only by transposing a matrix I was able to get the correct result.
>
> Regards,
> Michalis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20251123/1f7421c8/attachment-0001.html>


More information about the x3d-public mailing list