<commit_before>module Collision exposing (Body, Bounds, Face, face, collide, create, empty, encode, decode, BoundingBox, collisionMap)

{-| Detect collisions between rigid three-dimensional objects. The process goes like this:

1. Start with a set of triangular faces that describe the shape of an object.

2. Use `create` to convert the list of faces into a `Bounds` value. Creating the bounds can be time-consuming, so you will want to do this before you start the time loop.

3. If you want to create your bounds ahead of time, you can `encode` them to JSON and `decode` them later.

4. Once your simulation/game is running, test for collisions using `collide`.

This module will not work for 2D objects.

# Collision Detection
@docs Face, face, Bounds, create, empty, Body, collide

# Working with JSON
@docs encode, decode

# Debugging

Chances are you won't need to use the functions below. They are used by the Collision Visualizer. You can use them along with the `Collision.Tree` module to examine the collision trees.

@docs BoundingBox, collisionMap
-}

import Set exposing (Set)
import Json.Encode exposing (Value)
import Json.Decode exposing (Decoder)
import Vector exposing (Vector)
import Frame exposing (Frame)
import Collision.OBBTree as OBBTree
import Collision.Face as Face
import Collision.Tree exposing (Tree)


{-| A triangle. The surface of your colliding objects is described by a collection of triangular faces.
-}
type alias Face =
    { p : Vector
    , q : Vector
    , r : Vector
    }


{-| Create a triangular face, given the positions of its three vertexes. The vertexes can be given in any order.
-}
face : Vector -> Vector -> Vector -> Face
face =
    Face.face


{-| The boundary data for an object, stored as an OBBTree.
-}
type alias Bounds =
    Tree BoundingBox Face


{-| An object that is positioned and oriented in three-dimensional space. The bounds of the object are given in the body's reference frame. Before testing for a collision, we use the position and orientation to move the bounds into the world's reference frame.

This way, we can move our objects through the world, but we don't have to re-compute the bounds (as long as the object does not change shape).
-}
type alias Body a =
    { a
        | frame : Frame
        , bounds : Bounds
    }


{-| Generate the bounding tree for an object. The list of faces defines the surface.

The overall time to build the OBBTree is O(n log^2 n), where n is the number of faces.
-}
create : List Face -> Bounds
create =
    OBBTree.create


{-| Create an empty bounding tree. This will not collide with anything.
-}
empty : Bounds
empty =<commit_msg>Link to geo3d Vector & Frame types in docs<commit_after>module Collision exposing (Body, Bounds, Face, face, collide, create, empty, encode, decode, BoundingBox, collisionMap)

{-| Detect collisions between rigid three-dimensional objects. The process goes like this:

1. Start with a set of triangular faces that describe the shape of an object.

2. Use `create` to convert the list of faces into a `Bounds` value. Creating the bounds can be time-consuming, so you will want to do this before you start the time loop.

3. If you want to create your bounds ahead of time, you can `encode` them to JSON and `decode` them later.

4. Once your simulation/game is running, test for collisions using `collide`.

This module will not work for 2D objects.

# Collision Detection
@docs Face, face, Bounds, create, empty, Body, collide

# Working with JSON
@docs encode, decode

# Debugging

Chances are you won't need to use the functions below. They are used by the Collision Visualizer. You can use them along with the `Collision.Tree` module to examine the collision trees.

@docs BoundingBox, collisionMap
-}

import Set exposing (Set)
import Json.Encode exposing (Value)
import Json.Decode exposing (Decoder)
import Vector exposing (Vector)
import Frame exposing (Frame)
import Collision.OBBTree as OBBTree
import Collision.Face as Face
import Collision.Tree exposing (Tree)


{-| A triangle. The surface of your colliding objects is described by a collection of triangular faces. The `Vector` type is defined in [nphollon/geo3d](package.elm-lang.org/packages/nphollon/geo3d/latest/Vector).
-}
type alias Face =
    { p : Vector
    , q : Vector
    , r : Vector
    }


{-| Create a triangular face, given the positions of its three vertexes. The vertexes can be given in any order.
-}
face : Vector -> Vector -> Vector -> Face
face =
    Face.face


{-| The boundary data for an object, stored as an OBBTree.
-}
type alias Bounds =
    Tree BoundingBox Face


{-| An object that is positioned and oriented in three-dimensional space. The bounds of the object are given in the body's reference frame. The `Frame` type is defined in [nphollon/geo3d](package.elm-lang.org/packages/nphollon/geo3d/latest/Frame).

Before testing for a collision, we use the position and orientation to move the bounds into the world's reference frame. This way, we can move our objects through the world, but we don't have to re-compute the bounds (as long as the object does not change shape).
-}
type alias Body a =
    { a
        | frame : Frame
        , bounds : Bounds
    }


{-| Generate the bounding tree for an object. The list of faces defines the surface.

The overall time to build the OBBTree is O(n log^2 n), where n is the number of faces.
-}
create : List Face -> Bounds
create =
    OBBTree.create


{-| Create an empty bounding tree. This will not collide with anything.
-}
empty : Bounds
empty =
{'fraction_non_alphanumeric': 0.0702292832641271, 'fraction_numerical': 0.003069146055244629, 'mean_word_length': 3.6751054852320677, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6493252', 'n_tokens_mistral': 1569, 'n_tokens_neox': 1502, 'n_words': 805}