ianmackenzie / elm-3d-scene / Scene3d.Mesh.Decode

These JSON decoders allow you to decode meshes that have been saved as JSON using Encode.mesh or Encode.shadow (or from JSON that you generate yourself; read on!). All the decoders correspond to particular functions in the Mesh module. For example, if you had

facetsMesh =
    Scene3d.Mesh.facets listOfTriangles

which you then encoded as

meshJson =
    Scene3d.Mesh.Encode.mesh facetsMesh

you could then decode it with something like

decodeResult =
    Json.Decode.decodeValue
        Scene3d.Mesh.Decode.facets
        meshJson

where decodeResult should be Ok decodedMesh, with decodedMesh being equal to the original facetsMesh (within numerical roundoff).

Each function documents what JSON format it expects, so if you have some existing 3D models then it should be possible to write a small script (in whatever language you prefer) that converts those models into JSON that elm-3d-scene can decode. For example, you might write a command-line tool using Assimp that reads in data from one of Assimp's supported file formats and writes out JSON, or write a Blender script that exports the currently selected Blender object as JSON.

Hopefully at some point there will be good pure-Elm ways to load lots of different 3D model formats directly, but in the meantime this JSON-based approach should give you a path to using existing 3D assets without too much difficulty.

points : { radius : Quantity Basics.Float Pixels } -> Json.Decode.Decoder (Scene3d.Mesh.Plain coordinates)

Decode a mesh of points, passing in the point radius to use. This expects JSON of the form

[ { "x" : x1, "y" : y1, "z" : z1 }
, { "x" : x2, "y" : y2, "z" : z2 }
, ...
]

Corresponds to Mesh.points.

lineSegments : Json.Decode.Decoder (Scene3d.Mesh.Plain coordinates)

Decode a mesh of line segments. This expects JSON of the form

[ [ { "x" : x1, "y" : y1, "z" : z1 }
  , { "x" : x2, "y" : y2, "z" : z2 }
  ]
, [ { "x" : x3, "y" : y3, "z" : z3 }
  , { "x" : x4, "y" : y4, "z" : z4 }
  ]
, ...
]

Corresponds to Mesh.lineSegments.

polyline : Json.Decode.Decoder (Scene3d.Mesh.Plain coordinates)

Decode a polyline mesh. This expects JSON of the form

[ { "x" : x1, "y" : y1, "z" : z1 }
, { "x" : x2, "y" : y2, "z" : z2 }
, ...
]

Corresponds to Mesh.polyline.

triangles : Json.Decode.Decoder (Scene3d.Mesh.Plain coordinates)

Decode a mesh of triangles. This expects JSON of the form

[ [ { "x" : x1, "y" : y1, "z" : z1 }
  , { "x" : x2, "y" : y2, "z" : z2 }
  , { "x" : x3, "y" : y3, "z" : z3 }
  ]
, [ { "x" : x4, "y" : y4, "z" : z4 }
  , { "x" : x5, "y" : y5, "z" : z5 }
  , { "x" : x6, "y" : y6, "z" : z6 }
  ]
, ...
]

Corresponds to Mesh.triangles.

facets : Json.Decode.Decoder (Scene3d.Mesh.Uniform coordinates)

Decode a mesh of facets. This expects JSON of the form

[ [ { "x" : x1, "y" : y1, "z" : z1 }
  , { "x" : x2, "y" : y2, "z" : z2 }
  , { "x" : x3, "y" : y3, "z" : z3 }
  ]
, [ { "x" : x4, "y" : y4, "z" : z4 }
  , { "x" : x5, "y" : y5, "z" : z5 }
  , { "x" : x6, "y" : y6, "z" : z6 }
  ]
, ...
]

Corresponds to Mesh.facets.

Indexed meshes

The following functions all decode indexed meshes of the form

{ "vertices" :
    [ <vertex>
    , <vertex>
    , <vertex>
    ],
, "faces":
    [ [ i, j, k ]
    , [ l, m, n ]
    , ...
    ]
}

where the type of entries in the "vertices" list depends on the type of mesh being decoded, but the entries in the "faces" list are always lists of three zero-based indices into the list of vertices (the format used by TriangularMesh.indexed).

indexedTriangles : Json.Decode.Decoder (Scene3d.Mesh.Plain coordinates)

Decode an indexed mesh of triangles where each vertex is of the form

{ "x" : x, "y" : y, "z" : z }

Corresponds to Mesh.indexedTriangles.

indexedFacets : Json.Decode.Decoder (Scene3d.Mesh.Uniform coordinates)

Decode an indexed mesh of facets where each vertex is of the form

{ "x" : x, "y" : y, "z" : z }

Corresponds to Mesh.indexedFacets.

indexedFaces : Json.Decode.Decoder (Scene3d.Mesh.Uniform coordinates)

Decode an indexed mesh of faces where each vertex is of the form

{ "x" : x
, "y" : y
, "z" : z
, "nx" : nx
, "ny" : ny
, "nz" : nz
}

Corresponds to Mesh.indexedFaces.

texturedTriangles : Json.Decode.Decoder (Scene3d.Mesh.Unlit coordinates)

Decode an indexed mesh of textured triangles where each vertex is of the form

{ "x" : x
, "y" : y
, "z" : z
, "u" : u
, "v" : v
}

Corresponds to Mesh.texturedTriangles.

texturedFacets : Json.Decode.Decoder (Scene3d.Mesh.Textured coordinates)

Decode an indexed mesh of textured facets where each vertex is of the form

{ "x" : x
, "y" : y
, "z" : z
, "u" : u
, "v" : v
}

Corresponds to Mesh.texturedFacets.

texturedFaces : Json.Decode.Decoder (Scene3d.Mesh.Textured coordinates)

Decode an indexed mesh of textured faces where each vertex is of the form

{ "x" : x
, "y" : y
, "z" : z
, "nx" : nx
, "ny" : ny
, "nz" : nz
, "u" : u
, "v" : v
}

Corresponds to Mesh.texturedFaces.

Shadows

shadow : Json.Decode.Decoder (Scene3d.Mesh.Shadow coordinates)

Decode a Shadow value. This expects a mesh in the same form as indexedFaces, but the mesh itself has to be constructed in a very special way that generates a large number of auxiliary zero-area faces. In general you should only use this to decode a value produced by Encode.shadow.

If you are interested in generating properly-encoded shadow values yourself, please reach out to me (@ianmackenzie) on the Elm Slack.