GlomeTrace-0.1.2: Ray Tracing Library

Data.Glome.Solid

Synopsis

# Documentation

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.

Constructors

 RayHit Fieldsdepth :: !Flt pos :: !Vec norm :: !Vec texture :: Texture RayMiss

Instances

 Show Rayint Read (Rayint -> Material)

Pick the closest of two Rayints

Pick the furthest of two Rayints

Test if a Rayint is a hit or a miss

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

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.

Constructors

 PacketResult !Rayint !Rayint !Rayint !Rayint

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.

Constructors

 Material Fieldsclr :: !Color refl :: !Flt refr :: !Flt ior :: !Flt kd :: !Flt ks :: !Flt shine :: !Flt

Instances

 Show Material Read (Rayint -> Material)

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.

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

Uniform white material

Uniform texture

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

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

newtype Pcount Source

Constructors

 Pcount (Int, Int, Int)

Instances

 Show Pcount

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.

Methods

Arguments

 :: a object to test against -> Ray 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.

Instances

 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

Constructors

 forall a . Solid a => SolidItem a

Instances

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)

Constructors

 Void

Instances

 Show Void Solid Void

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

Constructors

 Instance SolidItem Xfm

Instances

 Show Instance Solid Instance