- data Rayint
- nearest :: Rayint -> Rayint -> Rayint
- furthest :: Rayint -> Rayint -> Rayint
- hit :: Rayint -> Bool
- dist :: Rayint -> Flt
- data PacketResult = PacketResult !Rayint !Rayint !Rayint !Rayint
- nearest_packetresult :: PacketResult -> PacketResult -> PacketResult
- rayint_advance :: SolidItem -> Ray -> Flt -> Texture -> Flt -> Rayint
- data Material = Material {}
- type Texture = Rayint -> Material
- showTexture :: Texture -> String
- t_uniform :: Material -> Texture
- interp :: Flt -> Flt -> Flt -> Flt
- m_interp :: Material -> Material -> Flt -> Material
- newtype Pcount = Pcount (Int, Int, Int)
- pcadd :: Pcount -> Pcount -> Pcount
- asbound :: Pcount -> Pcount
- pcsinglexfm :: Pcount
- pcsingleprim :: Pcount
- pcsinglebound :: Pcount
- pcnone :: Pcount
- debug_wrap :: (Rayint, Int) -> Int -> (Rayint, Int)
- nearest_debug :: (Rayint, Int) -> (Rayint, Int) -> (Rayint, Int)
- class Show a => Solid a where
- rayint :: a -> Ray -> Flt -> Texture -> Rayint
- rayint_debug :: a -> Ray -> Flt -> Texture -> (Rayint, Int)
- packetint :: a -> Ray -> Ray -> Ray -> Ray -> Flt -> Texture -> PacketResult
- shadow :: a -> Ray -> Flt -> Bool
- inside :: a -> Vec -> Bool
- bound :: a -> Bbox
- tolist :: a -> [SolidItem]
- transform :: a -> [Xfm] -> SolidItem
- transform_leaf :: a -> [Xfm] -> SolidItem
- flatten_transform :: a -> [SolidItem]
- primcount :: a -> Pcount
- data SolidItem = forall a . Solid a => SolidItem a
- group :: [SolidItem] -> SolidItem
- flatten_group :: [SolidItem] -> [SolidItem]
- rayint_group :: [SolidItem] -> Ray -> Flt -> Texture -> Rayint
- packetint_group :: [SolidItem] -> Ray -> Ray -> Ray -> Ray -> Flt -> Texture -> PacketResult
- rayint_debug_group :: [SolidItem] -> Ray -> Flt -> Texture -> (Rayint, Int)
- shadow_group :: [SolidItem] -> Ray -> Flt -> Bool
- inside_group :: [SolidItem] -> Vec -> Bool
- bound_group :: [SolidItem] -> Bbox
- transform_leaf_group :: [SolidItem] -> [Xfm] -> SolidItem
- primcount_group :: [SolidItem] -> Pcount
- data Void = Void
- data Instance = Instance SolidItem Xfm
- rayint_instance :: Instance -> Ray -> Flt -> Texture -> Rayint
- packetint_instance :: Instance -> Ray -> Ray -> Ray -> Ray -> Flt -> Texture -> PacketResult
- rayint_debug_instance :: Instance -> Ray -> Flt -> Texture -> (Rayint, Int)
- shadow_instance :: Instance -> Ray -> Flt -> Bool
- inside_instance :: Instance -> Vec -> Bool
- bound_instance :: Instance -> Bbox
- transform_instance :: Instance -> [Xfm] -> SolidItem
- transform_leaf_instance :: Instance -> [Xfm] -> SolidItem
- flatten_transform_instance :: Instance -> [SolidItem]
- primcount_instance :: Instance -> Pcount
Documentation
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.
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
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.
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
m_interp :: Material -> Material -> Flt -> MaterialSource
Interpolate between textures. Not really correct, but we'll go with it for now.
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 | 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.
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.
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
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
packetint_group :: [SolidItem] -> Ray -> Ray -> Ray -> Ray -> Flt -> Texture -> PacketResultSource
inside_group :: [SolidItem] -> Vec -> BoolSource
bound_group :: [SolidItem] -> BboxSource
transform_leaf_group :: [SolidItem] -> [Xfm] -> SolidItemSource
primcount_group :: [SolidItem] -> PcountSource
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
packetint_instance :: Instance -> Ray -> Ray -> Ray -> Ray -> Flt -> Texture -> PacketResultSource
inside_instance :: Instance -> Vec -> BoolSource
bound_instance :: Instance -> BboxSource
transform_instance :: Instance -> [Xfm] -> SolidItemSource
transform_leaf_instance :: Instance -> [Xfm] -> SolidItemSource