Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] Diff of /trunk/sml3d/src/particles/compiler/translate.sml
ViewVC logotype

Diff of /trunk/sml3d/src/particles/compiler/translate.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 974, Tue Aug 31 23:03:51 2010 UTC revision 1017, Tue Jan 18 22:19:53 2011 UTC
# Line 129  Line 129 
129            letPRIM("testNAND", IR.T_BOOL, IR.NOT, [testAND], fn testNAND =>            letPRIM("testNAND", IR.T_BOOL, IR.NOT, [testAND], fn testNAND =>
130            letPRIM(result, IR.T_BOOL, IR.AND, [testOR, testNAND], stmt))))            letPRIM(result, IR.T_BOOL, IR.AND, [testOR, testNAND], stmt))))
131    
132        fun genFloatVar (fltVar, env, domain : Float.float P.domain, dist, stmt : IR.var -> IR.stmt) = let
133          fun genRandVal(var, stmt : IR.var -> IR.stmt) = (case dist
134            of P.DIST_UNIFORM =>
135              letPRIM(var, IR.T_FLOAT, IR.RAND, [], stmt)
136    
137             (* The PDF here is f(x) = 2x when 0 < x <= 1, so the CDF is going
138              * to be the integral of f from 0 -> y => y^2. Hence, whenever we
139              * generate a random number, in order to get the random value according
140              * to this probability distribution, we just square it.
141              *)
142             | P.DIST_INC_LIN =>
143              letPRIM("randVal", IR.T_FLOAT, IR.RAND, [], fn randVal =>
144              letPRIM(var, IR.T_FLOAT, IR.MULT, [randVal, randVal], stmt))
145    
146             (* The PDF here is f(x) = -2x + 2 when 0 <= x < 1, so the CDF is going
147              * to be the integral of f from 0 -> y => -(y^2) + 2y. Hence, whenever we
148              * generate a random number, in order to get the random value according
149              * to this probability distribution, we just square it.
150              *)
151             | P.DIST_DEC_LIN =>
152              letPRIM("randVal", IR.T_FLOAT, IR.RAND, [], fn randVal =>
153              letPRIM("randSq", IR.T_FLOAT, IR.MULT, [randVal, randVal], fn randSq =>
154              letPRIM("termOne", IR.T_FLOAT, IR.MULT, [randSq, IR.newConst("negOne", IR.C_FLOAT ~1.0)], fn termOne =>
155              letPRIM("termTwo", IR.T_FLOAT, IR.MULT, [randVal, IR.newConst("negOne", IR.C_FLOAT 2.0)], fn termTwo =>
156              letPRIM(var, IR.T_FLOAT, IR.ADD, [termOne, termTwo], stmt)
157              ))))
158    
159             | _ => raise Fail "Unable to create random float for specified distribution."
160           (* end case *))
161         in
162         (case domain
163          of P.D_POINT(pt) =>
164             (* Our options here are pretty limited... *)
165             letPRIM (fltVar, IR.T_FLOAT, IR.COPY, [psvToIRVar(env, pt)], stmt)
166    
167           | P.D_BOX{max, min} =>
168             genRandVal("randf", fn rand =>
169             letPRIM("boxDiff", IR.T_FLOAT, IR.SUB, [psvToIRVar(env, max), psvToIRVar(env, max)], fn diff =>
170             letPRIM("scale", IR.T_FLOAT, IR.MULT, [diff, rand], fn scale =>
171             letPRIM( fltVar, IR.T_FLOAT, IR.ADD, [psvToIRVar(env, max), scale], stmt )
172             )))
173           | _ => raise Fail "Cannot generate float in specified domain."
174         (* end case *))
175        end
176    
177    (* Generates a random vector within the given domain and puts it in vecVar *)    (* Generates a random vector within the given domain and puts it in vecVar *)
178      fun genVecVar (vecVar, env, domain, stmt : IR.var -> IR.stmt) = (case domain      fun genVecVar (vecVar, env, domain : Vec3f.vec3 P.domain, stmt : IR.var -> IR.stmt) = (case domain
179             of P.D_POINT(pt) =>             of P.D_POINT(pt) =>
180               (* Our options here are pretty limited... *)               (* Our options here are pretty limited... *)
181                  letPRIM (vecVar, IR.T_VEC, IR.COPY, [psvToIRVar(env, pt)], stmt)                  letPRIM (vecVar, IR.T_VEC, IR.COPY, [psvToIRVar(env, pt)], stmt)
# Line 307  Line 352 
352               *)               *)
353                | P.D_DISC{pt, normal, orad, irad} =>                | P.D_DISC{pt, normal, orad, irad} =>
354                    letPRIM("posToPt", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, pt)], fn posToPt =>                    letPRIM("posToPt", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, pt)], fn posToPt =>
                   letPRIM("posToPtLen", IR.T_FLOAT, IR.LEN, [posToPt], fn posToPtLen =>  
355                    letPRIM("dot", IR.T_FLOAT, IR.DOT, [posToPt, psvToIRVar(env, normal)], fn dotProd =>                    letPRIM("dot", IR.T_FLOAT, IR.DOT, [posToPt, psvToIRVar(env, normal)], fn dotProd =>
356                    letPRIM("inDisc", IR.T_BOOL, IR.GT, [IR.newConst("small", IR.C_FLOAT 0.01), dotProd], fn inDisc =>                    letPRIM("inDisc", IR.T_BOOL, IR.GT, [IR.newConst("small", IR.C_FLOAT 0.01), dotProd], fn inDisc =>
357                    letPRIM("inOrad", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), posToPtLen], fn inOrad =>  
358                    letPRIM("inIrad", IR.T_BOOL, IR.GT, [posToPtLen, psvToIRVar(env, irad)], fn inIrad =>                    letPRIM("parPosToP", IR.T_VEC, IR.SCALE, [dotProd, psvToIRVar(env, normal)], fn posToPtParallelToNormal =>
359                      letPRIM("perpPosToP", IR.T_VEC, IR.SUB_VEC, [posToPt, posToPtParallelToNormal], fn posToPtPerpToNormal =>
360                      letPRIM("inDiscLen", IR.T_FLOAT, IR.LEN, [posToPtPerpToNormal], fn posToPtLen =>
361    
362                      letPRIM("inOradGt", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), posToPtLen], fn inOradGt =>
363                      letPRIM("inOradEq", IR.T_BOOL, IR.EQUALS, [psvToIRVar(env, orad), posToPtLen], fn inOradEq =>
364                      letPRIM("inOrad", IR.T_BOOL, IR.OR, [inOradGt, inOradEq], fn inOrad =>
365    
366                      letPRIM("inIradGt", IR.T_BOOL, IR.GT, [posToPtLen, psvToIRVar(env, irad)], fn inIradGt =>
367                      letPRIM("inIradEq", IR.T_BOOL, IR.EQUALS, [posToPtLen, psvToIRVar(env, irad)], fn inIradEq =>
368                      letPRIM("inIrad", IR.T_BOOL, IR.OR, [inIradGt, inIradEq], fn inIrad =>
369    
370                    letPRIM("inBothRad", IR.T_BOOL, IR.AND, [inIrad, inOrad], fn inBothRad =>                    letPRIM("inBothRad", IR.T_BOOL, IR.AND, [inIrad, inOrad], fn inBothRad =>
371                    letPRIM(boolVar, IR.T_BOOL, IR.AND, [inDisc, inBothRad], stmt))))))))  
372                      letPRIM(boolVar, IR.T_BOOL, IR.AND, [inDisc, inBothRad], stmt))))))))))))))
373    
374              (* Simply see whether or not the distance from the center is within the              (* Simply see whether or not the distance from the center is within the
375               * specified bounds.               * specified bounds.
# Line 346  Line 402 
402              genVecVar("ps_pos", env, posDomain, fn newPos =>              genVecVar("ps_pos", env, posDomain, fn newPos =>
403              genVecVar("ps_vel", env, velDomain, fn newVel =>              genVecVar("ps_vel", env, velDomain, fn newVel =>
404              genVecVar("ps_col", env, colDomain, fn newCol =>              genVecVar("ps_col", env, colDomain, fn newCol =>
405              letSPRIM ("ps_size", IR.T_FLOAT, IR.RAND, [], fn newSize =>              letPRIM ("randSize", IR.T_FLOAT, IR.RAND, [], fn randSize =>
406                letPRIM ("halvedSize", IR.T_FLOAT, IR.MULT, [randSize, IR.newConst("halver", IR.C_FLOAT 0.5)], fn halfSize =>
407                letSPRIM("ps_size", IR.T_FLOAT, IR.ADD, [halfSize, IR.newConst("scalar", IR.C_FLOAT 0.5)], fn newSize =>
408              letSPRIM ("ps_ttl", IR.T_FLOAT, IR.COPY, [IR.newConst("fbool", IR.C_FLOAT 10000.0)], fn newIsDead =>              letSPRIM ("ps_ttl", IR.T_FLOAT, IR.COPY, [IR.newConst("fbool", IR.C_FLOAT 10000.0)], fn newIsDead =>
409                k(PS{pos = newPos,                k(PS{pos = newPos,
410                     vel = newVel,                     vel = newVel,
# Line 355  Line 413 
413                     color = newCol,                     color = newCol,
414                     pos2 = IR.newConst("ps_pos2", IR.C_VEC {x=0.0, y=0.0, z=0.0}),                     pos2 = IR.newConst("ps_pos2", IR.C_VEC {x=0.0, y=0.0, z=0.0}),
415                     dummy = IR.newConst("ps_dummy", IR.C_FLOAT 0.01)})                     dummy = IR.newConst("ps_dummy", IR.C_FLOAT 0.01)})
416              )))))              )))))))
417    
418      (* Find the normal at the given position of the particle for the specified      (* Find the normal at the given position of the particle for the specified
419       * domain. Note, that the particle doesn't necessarily need to be on the       * domain. Note, that the particle doesn't necessarily need to be on the
# Line 399  Line 457 
457          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let
458    
459            val PS{ttl, ...} = state            val PS{ttl, ...} = state
460            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit            val P.EMIT{range, dist, posDomain, velDomain, colDomain, ...} = emit
461            val blk = newBlock (env, k)            val blk = newBlock (env, k)
462           in           in
463            letPRIM("isDead", IR.T_BOOL, IR.GT, [IR.newConst("small", IR.C_FLOAT 0.1), ttl], fn isDead =>            letPRIM("isDead", IR.T_BOOL, IR.GT, [IR.newConst("small", IR.C_FLOAT 0.1), ttl], fn isDead =>
464        IR.mkIF(isDead,        IR.mkIF(isDead,
465         (* then *)         (* then *)
466         letPRIM("t1", IR.T_FLOAT, IR.ITOF, [psvToIRVar (env, maxNum)], fn t1 =>         genFloatVar("t1", env, range, dist, fn t1 =>
467         letPRIM("t2", IR.T_FLOAT, IR.ITOF, [psvToIRVar (env, PSV.numDead)], fn t2 =>         letPRIM("t2", IR.T_FLOAT, IR.ITOF, [psvToIRVar (env, PSV.numDead)], fn t2 =>
468         letPRIM("prob", IR.T_FLOAT, IR.DIV, [t1, t2], fn prob =>         letPRIM("prob", IR.T_FLOAT, IR.DIV, [t1, t2], fn prob =>
469         letPRIM("r", IR.T_FLOAT, IR.RAND, [], fn r =>         letPRIM("r", IR.T_FLOAT, IR.RAND, [], fn r =>
# Line 441  Line 499 
499                    in                    in
500                      letPRIM("vs", IR.T_VEC, IR.SCALE, [psvToIRVar(env, PSV.timeStep), vel], fn velScale =>                      letPRIM("vs", IR.T_VEC, IR.SCALE, [psvToIRVar(env, PSV.timeStep), vel], fn velScale =>
501                      letPRIM("np", IR.T_VEC, IR.ADD_VEC, [pos, velScale], fn nextPos =>                      letPRIM("np", IR.T_VEC, IR.ADD_VEC, [pos, velScale], fn nextPos =>
502                      mkWithinVar("wnp", env, pos, d, fn withinNextPos =>                      mkWithinVar("wcp", env, pos, d, fn withinCurPos =>
503                      IR.mkIF(withinNextPos,                      mkWithinVar("wnp", env, nextPos, d, fn withinNextPos =>
504                        letPRIM("nwcp", IR.T_BOOL, IR.NOT, [withinCurPos], fn notWithinCurPos =>
505                        letPRIM("sb", IR.T_BOOL, IR.AND, [notWithinCurPos, withinNextPos], fn shouldBounce =>
506                        IR.mkIF(shouldBounce,
507                        (*then*)                        (*then*)
508                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let
509                 val PS{pos=nextPos, vel=nextVel, size=nextSize, ttl=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy} = state'                 val PS{pos=nextPos, vel=nextVel, size=nextSize, ttl=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy} = state'
# Line 475  Line 536 
536                           end                           end
537                        ),                        ),
538                        (*else*)                        (*else*)
539                        goto(state, blk)))))                        goto(state, blk))))))))
540                    end                    end
541    
542                | P.ACCEL dir =>                | P.ACCEL dir =>
# Line 535  Line 596 
596            end            end
597    
598      fun compile (P.PG{      fun compile (P.PG{
599         emit as P.EMIT{maxNum, vars=emitVars, ...},         emit as P.EMIT{vars=emitVars, ...},
600         act as P.PSAE{action=root_act, vars=actionVars},         act as P.PSAE{action=root_act, vars=actionVars},
601         render         render
602      }) = let      }) = let
603            val blks = ref[]            val blks = ref[]
604            val env = let            val env = let
605                (* add special globals to free vars *)                (* add special globals to free vars *)
606                  val vars = PSV.Set.union(emitVars, PSV.Set.addList(actionVars, [maxNum, PSV.numDead, PSV.timeStep, epsilon]))                  val vars = PSV.Set.union(emitVars, PSV.Set.addList(actionVars, [PSV.numDead, PSV.timeStep, epsilon]))
607                  fun ins (x as PSV.V{name, ty, binding, id, ...}, map) = let                  fun ins (x as PSV.V{name, ty, binding, id, ...}, map) = let
608                        val x' = (case (ty, !binding)                        val x' = (case (ty, !binding)
609                               of (PSV.T_BOOL,  PSV.UNDEF) => IR.newGlobal(x, IR.T_BOOL)                               of (PSV.T_BOOL,  PSV.UNDEF) => IR.newGlobal(x, IR.T_BOOL)

Legend:
Removed from v.974  
changed lines
  Added in v.1017

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0