GlomeTrace-0.1.2: Ray Tracing Library




data Rayint Source

Ray intersection type. If we hit, we store the distance from the ray origin, the position, the normal, and the texture attached to the object. We could just as easily have created a hit type and wrapped it in a Maybe.




depth :: !Flt
pos :: !Vec
norm :: !Vec
texture :: Texture


nearest :: Rayint -> Rayint -> RayintSource

Pick the closest of two Rayints

furthest :: Rayint -> Rayint -> RayintSource

Pick the furthest of two Rayints

hit :: Rayint -> BoolSource

Test if a Rayint is a hit or a miss

dist :: Rayint -> FltSource

Extract a distance from a Rayint, with infinity for a miss

data PacketResult Source

Sometimes, it's more efficient to trace multiple rays against an acceleration structure at the same time, provided the rays are almost identical. A PacketResult is the result of tracing 4 rays at once.

rayint_advance :: SolidItem -> Ray -> Flt -> Texture -> Flt -> RayintSource

Move a ray forward and test the new ray against an object. Fix the depth of the result. Useful in CSG

data Material Source

Surface properties at a point on an object's surface. We have color, reflection amount, refraction amount index of refraction, kd, ks, and shine. These are parameters to a Whitted - style illumination model.




clr :: !Color
refl :: !Flt
refr :: !Flt
ior :: !Flt
kd :: !Flt
ks :: !Flt
shine :: !Flt


type Texture = Rayint -> MaterialSource

A texture is a function that takes a Rayint and returns a Material. In other words, textures can vary based on location, normal, etc... in arbitrary ways.

showTexture :: Texture -> StringSource

This is sort of a no-op; textures are functions, and we don't have a good way to show an arbitrary function

t_uniform :: Material -> TextureSource

Uniform white material

Uniform texture

interp :: Flt -> Flt -> Flt -> FltSource

m_interp :: Material -> Material -> Flt -> MaterialSource

Interpolate between textures. Not really correct, but we'll go with it for now.

newtype Pcount Source


Pcount (Int, Int, Int) 


class Show a => Solid a whereSource

A solid is something we can test a ray against or do inside/outside tests. Some of these are simple solids like Sphere or Triangle, but others are composite solids than have other solids as children.




:: a

object to test against

-> Ray


-> Flt

maximum distance we care about

-> Texture

default texture

-> Rayint

we return a Rayint describing the hit location

Test a ray against a solid, returning a ray intersection. The distance parameter is used to specify a max distance. If it's further away, we aren't interested in the intersection. The texture parameter is a default texture we use, if it's not overridden by a more specific texture.

rayint_debug :: a -> Ray -> Flt -> Texture -> (Rayint, Int)Source

Same as rayint, but return a count of the number of primitives checked. Useful for optimizing acceleration structures.

packetint :: a -> Ray -> Ray -> Ray -> Ray -> Flt -> Texture -> PacketResultSource

Trace four rays at once against a solid.

shadow :: a -> Ray -> Flt -> BoolSource

Shadow test - we just return a Bool rather than return a a full Rayint.

inside :: a -> Vec -> BoolSource

Test if a point is inside an object. Useful for CSG. Objects with no volume just return False.

bound :: a -> BboxSource

Generate an axis-aligned bounding box than completely encloses the object. For performance, it is important that this fits as tight as possible.

tolist :: a -> [SolidItem]Source

Most simple objects just return themselves as a singleton list, but for composite objects, we flatten the structure out and return a list. We usually do this prior to re-building a composite object in a (hopefully) more efficient fashion.

transform :: a -> [Xfm] -> SolidItemSource

Create a new object transformed by some transformation. The reason this method exists is so we can override it for the Instance type - if we transform a transformation, we should combine the two matricies into one. Most objects can use the default implementation.

transform_leaf :: a -> [Xfm] -> SolidItemSource

Used by flatten_transform. I don't really remember how it works.

flatten_transform :: a -> [SolidItem]Source

Take a composite object inside a transform, and turn it into a group of individually-transformed objects. Most objects can use the defaut implementation.

primcount :: a -> PcountSource

Count the number of primitives, transforms, and bounding objects in a scene. Simple objects can just use the default, which is to return a single primitive.


Solid Instance 
Solid Void 
Solid SolidItem 
Solid Sphere 
Solid TriangleNorm 
Solid Triangle 
Solid Bih 
Solid Intersection 
Solid Difference 
Solid Plane 
Solid Box 
Solid Bound 
Solid Cone 
Solid Cylinder 
Solid Disc 
Solid Tex 
Solid [SolidItem] 

data SolidItem Source

We create an existential type for solids so we can emded them in composite types without know what kind of solid it is. http:notes-on-haskell.blogspot.com200701/proxies-and-delegation-vs-existential.html


forall a . Solid a => SolidItem a 

group :: [SolidItem] -> SolidItemSource

A group is just a list of objects. Sometimes its convenient to be able to treat a group as if it were a single object, and that is exactly what we do here. The ray intersection routine tests the ray against each object in turn. Not very efficient for large groups, but this is a useful building block for constructing the leaves of acceleration structures. (See the bih module.)

flatten_group :: [SolidItem] -> [SolidItem]Source

Smash a group of groups into a single group, so we can build an efficient bounding heirarchy

data Void Source

A Void is a non-object, that we treat as if it were one. This is functionally equivalent to an empty Group. (Originally I called this Nothing, but that conflicted with the prelude maybe type, so I call it Void instead)




data Instance Source

An instance is a primitive that has been modified by a transformation (i.e. some combination of translation, rotation, and scaling). This is a reasonably space-efficient way of making multiple copies of a complex object.

Usually, the application doesn't need to create an instance directly, but should use transform on an existing object.

It's unfortunate that instance is also a reserved word. instance Solid Instance where... is a little confusing.

This would be better in its own module, but we need Instance to be defined here so we can define the default implementation of transform in terms on Instance. (Mutually recursive modules would be useful, if I could get them to work.)

Another good reason to include Instance in Solid.hs is that it's referenced from Cone.hs


Instance SolidItem Xfm