Another post about loading Wavefront Obj files into GameObjects.Mesh
I touched upon the issue of OBJ files with “o” not being rendered properly in my post of
Reading OBJ files with quad faces into Phaser Mesh objects - Examples - Phaser.
This issue arises because the Geom.Mesh.ParseObj method (which creates a <Geom.Mesh.OBJData> object) splits the “mesh object” into separate "model"s every time the parser encounters an “o”. More specifically, during the parsing process not only are the elements (i.e. face information with indices into the vertices) stored in the individual “model” but also the actual vertex/normal/texturecoords data are segregated into individual "model"s. The result is that that the indices (which are numbered from 1 to the total number of vertices) become “out of sync”.
I do not know why vertex data (as opposed to face elements) are split into separate "object"s. However, since the vertices are de-indexed into a contiguous vertex array in GenerateObjVerts method anyway I believe the issue of “o” OBJ files can be worked around quite safely by either:
- amending GenerateObjVerts method so that the vertex data of the models are concatenated into one, at the beginning of the method, or
- amending the ParseObj method so that it does not split the vertex data into individual models, only the face elements data.
Below is approach (1) - very “hacky” but requires only small amendment.
Loading OBJ file with groups in Phaser 3, version 1 (codepen.io)
Below is approach (2) - less “hacky” but end up having to load the obj and material files separately as text files when passing to addVerticesFromObj method, so quite cumbersome. And there’s a lot of code - although 99% of it is simply copy&paste of phaser’s original code.
Loading OBJ file with groups in Phaser 3, version 2 (codepen.io)
I also added a few lines in GenerateObjVerts to read the vertex normals data (which is parsed in ParseObj method, but ignored in the original GenerateObjVerts - probably because Phaser’s WebGLRenderer does not use normals). I have created a new class called Mesh2, which extends Phaser.GameObjects.Mesh, trying to keep things as consistent with the original.
With these amendments, I believe you can load every model that is available on Phaser’s examples repository and render something (of course no shading, and much of materials information is ignored).
If you are interested in expanding the range of obj models that can be read into Mesh (without resorting to ThreeJS!), please do play with the examples above.