Critical steps:
- Finish semantics (partially done)
- Detect and untie cycles in let exprs (done)
- Add complete syntax for particles/emitters (done)
- Make operations over vectors and scalars handle better
- Try to reimplement examples from other systems, such as Fran, etc.)
- Write some larger examples
- Finalise and document the language
- Implement CSE
- Implement GPU-compilation (decide on Vertigo or Cg)
- Test the compiler with tricky expressions
- Finalise and document the optimizer/compiler
- Implement rapid geometry transfer (using gl-extensions)
- Implement complete app output (glut-framework)
- Finalise and document C++ backend
- Make nice color slides, present thesis
- Graduate ;-)
Non-critical issues: (no ordering)
-
Smart Constructors
Effectively eliminating LocalOpt.hs. This will ensure that
we always have optimal expressions (locally), instead of the current
situation were we run localopt on the expression only once and
modify it afterwards, resulting in possibly unoptimal expressions.
-
Internal error checking
Write a DExp validity checker, that checks types and the arity of each op. A
lot of code just assumes things are correct and it would be nice to certify
that it is so before doing anything.
-
Exp -> Code
Make it easy to substitute particle commands for other commands, so
that the compiler can be used for other purposes. A well designed set
of type classes should do nicely.
-
Vector type
Skip Vector3, Vector4, make Vector Int instead. Make Matrix Int Int too?
-
Scalar/Vector ops
Am having problem with numeric literals. It works for my types, but
not for simple literals.
-
Comparision of vectors?
Comparision only works with scalar expressions. Should comparision of vector
exps give a vector of 0,1 floats? (i.e. (1,2,3,4) < (4,3,2,1) =>
(1,1,0,0)) This could perhaps be useful in vertex programs (GF3/GF4-class), as
they have this form of conditionals.
-
QuickCheck
Use QuickCheck
to verify the system? Will probably take quite some time to implement, but
definitely seems to be a suitable framework.
This serves as an aid to the diary.
Done:
-
Removed lots of issues that are void with the new design.
-
Rewrote Vec [DExp] as O Vec [DExp].. i.e. only one recursive case
for the DExp datatype, which simplifies many operations.
-
Sorts out literals in multiple arity ops and folds these.
-
Removed constructor checks in DExp. Need not clutter that file with typechecks.
Will write a checker Real Soon Now (tm).
-
Added LetRand & NewVar to DExp, to fix randomization optmimization problem.
Also made:
class Random a where
rand :: (a -> Exp b) -> Exp b
with instantiations for FloatE, Float3E, Float4E and (2,3,4-element) tuples. Makes it really
easy to write expressions with random variables.
-
Made Min/Max,&&* and ||* multiple-arity ops like * and +, and also added list-versions
of these.
-
Unified Local, Particle and Environment variables into one.
DExp = ... | Var Type Id Scope | ...
data Scope = Temp | Local | Global
Temp is used by the CSE/Randomization system. Local variables represent particle properties
(read/write and variant) and global
variables correspond to the environment (read-only and unform).
Solved:
-
Vector 'op' scalar
How to use a single operator/function to multiply scalars and vectors
in all permutations? Fran/Pan does not attempt to solve this, but it would be
nice to mimic mathematical notation. (This is something that users simply
expect to work. As do I. :)
Solution: Multi-parameter typeclasses.
It is not standard Haskell 98, but both GHC and Hugs support it
through extensions.
data Vector = Vector Float Float deriving Show
class Vec a b where add :: a -> b -> Vector
instance Vec Vector Float where add (Vector a b) c = Vector (a+c) (a+c)
instance Vec Float Vector where add a (Vector b c) = Vector (a+b) (a+c)
instance Vec Vector Vector where add (Vector a b) (Vector c d) = Vector (a+c) (b+d)
This means that I can use add (or any similar operator) to make any componentwise
operation possible without explicit scalar->vector expansion. Neat!
(Might need to use functional dependecies.)
-
Optimisation of random values?
Subexpressions with randomization in them are not equal, although the derived
Eq instance surely says so. Massage all exps tagging each rand with a number? I
do not want to expose my own let to the user (one which is used by the
CSE-system), so how to distingush between the following two rows?
r1 = let r = rand
in vec3 (r,r,r)
r2 = vec3 (rand, rand, rand)
Solution, introduce special let for randomization:
Extend DExp, define rand with var and use rand giving a function:
LetRand String (Exp -> Exp) | NewVar (Var -> Exp)
rand :: (Exp -> Exp) -> Exp
rand f = NewVar $ \v -> LetRand v (f v)
rand3 :: (Exp ->Exp -> Exp -> Exp) -> Exp
rand3 f = rand $ \r1 -> rand $ \r2 -> rand $ \r3 -> f r1 r2 r3
The two rows above would then be implemented as:
r1 = rand $ \r -> vec3 (r,r,r)
r2 = rand3 $ \r1 r2 r3 -> vec3 (r1,r2,r3)
Of course, we do not want to handle DExp:s with functions during optimization,
so we process all expressions and create new local variables at each NewVar
expression found. We should also check after CSE to see if the rand-vars are
used only once, and inline the call to rand().
|