This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

OBJ

.obj file loader

The returned models can be rendered using indexedTriangles from WebGL.

WebGL.indexedTriangles mesh.vertices mesh.indices

From URL

All these methods take an URL as the first parameter.

Single model

Use the methods from here if you know whats in your file and if they only contain a single object with a single material. These are just provided for convenience.

loadMeshWithoutTexture : String -> (Result String (MeshWith Vertex) -> msg) -> Cmd msg

Load a model that doesn't have texture coordinates.

loadMesh : String -> (Result String (MeshWith VertexWithTexture) -> msg) -> Cmd msg

Load a model with texture coordinates.

loadMeshWithTangent : String -> (Result String (MeshWith VertexWithTextureAndTangent) -> msg) -> Cmd msg

Load a model with texture coordinate and calculate vertex tangents. This is needed if you want to do tangent space normal mapping.

General

Use these methods if you don't know what kind of files you'll get or if your files contain multiple groups or materials.

loadObjFile : String -> (Result String ObjFile -> msg) -> Cmd msg

Load a .obj file from an URL

loadObjFile url ObjFileLoaded
loadObjFileWith : Settings -> String -> (Result String ObjFile -> msg) -> Cmd msg
type alias Settings = { withTangents : Bool }

withTangents : If true, vertex tangents will be calculated for meshes with texture coordinates. This is needed if you want to do tangent space normal mapping.

defaultSettings : Settings

From String

parseObjStringWith : Settings -> String -> Result String ObjFile

Same as loadObjFile, but works on a string.

module OBJ exposing (..)

{-|


# .obj file loader

The returned models can be rendered using `indexedTriangles` from `WebGL`.

    WebGL.indexedTriangles mesh.vertices mesh.indices


## From URL

All these methods take an URL as the first parameter.


### Single model

Use the methods from here if you know whats in your file
and if they only contain a single object with a single material.
These are just provided for convenience.

@docs loadMeshWithoutTexture, loadMesh, loadMeshWithTangent


### General

Use these methods if you don't know what kind of files you'll get or
if your files contain multiple groups or materials.

@docs loadObjFile, loadObjFileWith, Settings, defaultSettings


## From String

@docs parseObjStringWith

-}

import Dict exposing (Dict)
import Http
import OBJ.Assembler exposing (compile)
import OBJ.Parser exposing (parse)
import OBJ.Types exposing (Mesh, ObjFile)
import Task


--

import OBJ.Assembler exposing (compile)
import OBJ.Parser exposing (parse)
import OBJ.Types exposing (..)


{-| Load a model that doesn't have texture coordinates.
-}
loadMeshWithoutTexture : String -> (Result String (MeshWith Vertex) -> msg) -> Cmd msg
loadMeshWithoutTexture url msg =
    loadObjFile url
        (\res ->
            case res of
                Ok f ->
                    case (Dict.values f |> List.map Dict.values) of
                        [ [ WithoutTexture m ] ] ->
                            msg (Ok m)

                        _ ->
                            msg (Err "file loaded correctly, but there were more than one models.")

                Err e ->
                    msg (Err e)
        )


{-| Load a model with texture coordinates.
-}
loadMesh : String -> (Result String (MeshWith VertexWithTexture) -> msg) -> Cmd msg
loadMesh url msg =
    loadObjFile url
        (\res ->
            case res of
                Ok f ->
                    case (Dict.values f |> List.map Dict.values) of
                        [ [ WithTexture m ] ] ->
                            msg (Ok m)

                        _ ->
                            msg (Err "file loaded correctly, but there were more than one models.")

                Err e ->
                    msg (Err e)
        )


{-| Load a model with texture coordinate and calculate vertex tangents.
This is needed if you want to do tangent space normal mapping.
-}
loadMeshWithTangent : String -> (Result String (MeshWith VertexWithTextureAndTangent) -> msg) -> Cmd msg
loadMeshWithTangent url msg =
    loadObjFileWith { withTangents = True }
        url
        (\res ->
            case res of
                Ok f ->
                    case (Dict.values f |> List.map Dict.values) of
                        [ [ WithTextureAndTangent m ] ] ->
                            msg (Ok m)

                        _ ->
                            msg (Err "file loaded correctly, but there were more than one models.")

                Err e ->
                    msg (Err e)
        )


{-| Load a .obj file from an URL

    loadObjFile url ObjFileLoaded

-}
loadObjFile : String -> (Result String ObjFile -> msg) -> Cmd msg
loadObjFile =
    loadObjFileWith defaultSettings


{-| withTangents : If true, vertex tangents will be calculated for meshes with texture coordinates.
This is needed if you want to do tangent space normal mapping.
-}
type alias Settings =
    { withTangents : Bool }


{-| -}
defaultSettings : Settings
defaultSettings =
    { withTangents = False }


{-| -}
loadObjFileWith : Settings -> String -> (Result String ObjFile -> msg) -> Cmd msg
loadObjFileWith settings url msg =
    Http.toTask (Http.getString url)
        |> Task.andThen
            (\s ->
                parseObjStringWith settings s |> Task.succeed
            )
        |> Task.onError (\e -> Task.succeed (Err ("failed to load:\n" ++ toString e)))
        |> Task.attempt
            (\r ->
                case r of
                    Ok (Ok m) ->
                        msg (Ok m)

                    Ok (Err e) ->
                        msg (Err e)

                    Err e ->
                        msg (Err e)
            )


{-| Same as `loadObjFile`, but works on a string.
-}
parseObjStringWith : Settings -> String -> Result String ObjFile
parseObjStringWith config input =
    parse input
        |> Result.map (compile config)