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 901, Fri May 28 19:15:30 2010 UTC revision 1017, Tue Jan 18 22:19:53 2011 UTC
# Line 24  Line 24 
24          pos : IR.var,           (* vec3 *)          pos : IR.var,           (* vec3 *)
25          vel : IR.var,           (* vec3 *)          vel : IR.var,           (* vec3 *)
26          size : IR.var,          (* float *)          size : IR.var,          (* float *)
27          isDead : IR.var,        (* bool *)          ttl : IR.var,           (* float *)
28          color : IR.var,         (* vec3 (NOTE: should be vector4) *)          color : IR.var,         (* vec3 (NOTE: should be vector4) *)
29          pos2 : IR.var,          (* vec3 *)          pos2 : IR.var,          (* vec3 *)
30          dummy : IR.var          dummy : IR.var
31        }        }
32    
33    (* special PSV global variables *)    (* special PSV global variables *)
     val timeStep = PSV.new("g_timeStep", PSV.T_FLOAT)   (* physics timestep *)  
     val numDead = PSV.new("g_numDead", PSV.T_INT)       (* # of dead particles *)  
34      val epsilon = PSV.constf(0.00001)      val epsilon = PSV.constf(0.00001)
35    
36    (* constants *)    (* constants *)
# Line 53  Line 51 
51    
52    
53      fun retState s = let      fun retState s = let
54        val PS{pos, vel, size, isDead, color, pos2, dummy} = s        val PS{pos, vel, size, ttl, color, pos2, dummy} = s
55       in       in
56        IR.mkRETURN [pos, vel, size, isDead, color, pos2, dummy]        IR.mkRETURN (
57            [pos, vel, size, ttl, color, pos2, dummy],
58            [IR.POS, IR.VEL, IR.SZ, IR.TTL, IR.COLOR, IR.POS2, IR.DUMMY]
59          )
60       end       end
61    
62    (* translation environment *)    (* translation environment *)
# Line 73  Line 74 
74            val pos = IR.newParam ("ps_pos", IR.T_VEC)            val pos = IR.newParam ("ps_pos", IR.T_VEC)
75            val vel = IR.newParam ("ps_vel", IR.T_VEC)            val vel = IR.newParam ("ps_vel", IR.T_VEC)
76            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
77            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val ttl = IR.newParam ("ps_ttl", IR.T_FLOAT)
78            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
79            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
80            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
81            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, pos2=pos2, dummy=dummy}            val state = PS{pos=pos, vel=vel, size=size, ttl=ttl, color=color, pos2=pos2, dummy=dummy}
82            val blk = IR.newBlock ([pos, vel, size, isDead, color, pos2, dummy], k state)            val blk = IR.newBlock ([pos, vel, size, ttl, color, pos2, dummy], k state)
83            in            in
84              blks := blk :: !blks;              blks := blk :: !blks;
85              blk              blk
# Line 88  Line 89 
89            val pos = IR.newParam ("ps_pos", IR.T_VEC)            val pos = IR.newParam ("ps_pos", IR.T_VEC)
90            val vel = IR.newParam ("ps_vel", IR.T_VEC)            val vel = IR.newParam ("ps_vel", IR.T_VEC)
91            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
92            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val ttl = IR.newParam ("ps_ttl", IR.T_FLOAT)
93            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
94            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
95            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
96            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, pos2=pos2, dummy = dummy}            val state = PS{pos=pos, vel=vel, size=size, ttl=ttl, color=color, pos2=pos2, dummy = dummy}
97            val blk = IR.newBlock ([pos, vel, size, isDead, color, pos2, dummy] @ args, k state)            val blk = IR.newBlock ([pos, vel, size, ttl, color, pos2, dummy] @ args, k state)
98            in            in
99              blks := blk :: !blks;              blks := blk :: !blks;
100              blk              blk
101            end            end
102    
103      fun goto (PS{pos, vel, size, isDead, color, pos2, dummy}, blk) =      fun goto (PS{pos, vel, size, ttl, color, pos2, dummy}, blk) =
104            IR.mkGOTO(blk, [pos, vel, size, isDead, color, pos2, dummy])            IR.mkGOTO(blk, [pos, vel, size, ttl, color, pos2, dummy])
105    
106          fun gotoWithArgs(PS{pos, vel, size, isDead, color, pos2, dummy}, args, blk) =          fun gotoWithArgs(PS{pos, vel, size, ttl, color, pos2, dummy}, args, blk) =
107            IR.mkGOTO(blk, [pos, vel, size, isDead, color, pos2, dummy] @ args)            IR.mkGOTO(blk, [pos, vel, size, ttl, color, pos2, dummy] @ args)
108    
109      fun letPRIM (x, ty, p, args, body) = let      fun letPRIM (x, ty, p, args, body) = let
110            val x' = IR.newLocal(x, ty, (p, args))            val x' = IR.newLocal(x, ty, (p, args))
# Line 128  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 294  Line 340 
340               * behind it (with respect to the normal)               * behind it (with respect to the normal)
341               *)               *)
342                | P.D_PLANE{pt, normal} =>                | P.D_PLANE{pt, normal} =>
343                    letPRIM("posToPt", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt), pos], fn posToPt =>                    letPRIM("posToPt", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, pt)], fn posToPt =>
344                    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 =>
345                    letPRIM(boolVar, IR.T_BOOL, IR.GT, [dotProd, IR.newConst("zero", IR.C_FLOAT 0.0)], stmt)))                    letPRIM(boolVar, IR.T_BOOL, IR.GT, [dotProd, IR.newConst("zero", IR.C_FLOAT 0.0)], stmt)))
346    
# Line 305  Line 351 
351               * orad.               * orad.
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, [psvToIRVar(env, pt), pos], 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 345  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              letSPRIM ("ps_isDead", IR.T_BOOL, IR.COPY, [IR.newConst("fbool", IR.C_BOOL false)], fn newIsDead =>              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 =>
409                k(PS{pos = newPos,                k(PS{pos = newPos,
410                     vel = newVel,                     vel = newVel,
411                     size = newSize,                     size = newSize,
412                     isDead = newIsDead,                     ttl = newIsDead,
413                     color = newCol,                     color = newCol,
414                     pos2 = IR.newConst("p2", 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("dmy", 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 397  Line 456 
456    
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{isDead, ...} = 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 =>
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, 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 =>
470         letPRIM("t3", IR.T_BOOL, IR.GT, [prob, r], fn t3 =>         letPRIM("t3", IR.T_BOOL, IR.GT, [prob, r], fn t3 =>
# Line 415  Line 475 
475          (* else *)          (* else *)
476          IR.DISCARD)))))),          IR.DISCARD)))))),
477         (* else *)         (* else *)
478         retState state)         retState state))
479       end       end
480    
481          fun trPred(pred, env, state, thenk : particle_state -> IR.stmt, elsek : particle_state -> IR.stmt) = let          fun trPred(pred, env, state, thenk : particle_state -> IR.stmt, elsek : particle_state -> IR.stmt) = let
# Line 430  Line 490 
490           end           end
491    
492      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let
493            val PS{pos, vel, size, isDead, color, pos2, dummy} = state            val PS{pos, vel, size, ttl, color, pos2, dummy} = state
494            in            in
495              case action              case action
496               of P.BOUNCE{friction, resilience, cutoff, d} => let               of P.BOUNCE{friction, resilience, cutoff, d} => let
497                    val blk = newBlock (env, k)                    val blk = newBlock (env, k)
498                    val negOne = IR.newConst("negOne", IR.C_FLOAT ~1.0)                    val negOne = IR.newConst("negOne", IR.C_FLOAT ~1.0)
499                    in                    in
500                      letPRIM("vs", IR.T_VEC, IR.SCALE, [psvToIRVar(env, 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, isDead=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'
510                            in                            in
511                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>
512                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>
# Line 462  Line 525 
525                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>
526                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>
527                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>
528                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, ttl=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy}, blk)
529                              )))),                              )))),
530                               (*else*)                               (*else*)
531                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>
532                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>                               letPRIM("ps_vel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>
533                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, ttl=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy}, blk)
534                               ))                               ))
535                           )))))))))                           )))))))))
536                           end                           end
537                        ),                        ),
538                        (*else*)                        (*else*)
539                        goto(state, blk)))))                        goto(state, blk))))))))
540                    end                    end
541    
542                | P.GRAVITY(dir) =>                | P.ACCEL dir =>
543                      letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, timeStep), psvToIRVar(env, dir)], fn theScale =>                      letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, PSV.timeStep), psvToIRVar(env, dir)], fn theScale =>
544                      letPRIM("nextVel", IR.T_VEC, IR.ADD_VEC, [theScale, vel], fn newVel =>                      letPRIM("ps_vel", IR.T_VEC, IR.ADD_VEC, [theScale, vel], fn newVel =>
545                        k(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, pos2=pos2, dummy=dummy})))                        k(PS{pos = pos, vel = newVel, size = size, ttl = ttl, color = color, pos2=pos2, dummy=dummy})))
546    
547                | P.MOVE =>                | P.MOVE =>
548                  letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, timeStep), vel], fn theScale =>                  letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, PSV.timeStep), vel], fn theScale =>
549                      letPRIM("nextPos", IR.T_VEC, IR.ADD_VEC, [theScale, pos], fn newPos =>                      letPRIM("ps_pos", IR.T_VEC, IR.ADD_VEC, [theScale, pos], fn newPos =>
550                        k(PS{pos = newPos, vel = vel, size = size, isDead = isDead, color = color, pos2=pos2, dummy=dummy})))                        k(PS{pos = newPos, vel = vel, size = size, ttl = ttl, color = color, pos2=pos2, dummy=dummy})))
551                (*                (*
552                | P.SINK({d, kill_inside}) =>                | P.SINK({d, kill_inside}) =>
553                      mkWithinVar("isWithin", env, state, d, fn withinVal =>                      mkWithinVar("isWithin", env, state, d, fn withinVal =>
554                      mkXOR ("shouldNotKill", withinVal, psvToIRVar(env, kill_inside),                      mkXOR ("shouldNotKill", withinVal, psvToIRVar(env, kill_inside),
555                        fn shouldNotKill =>                        fn shouldNotKill =>
556                      letPRIM("shouldKill", IR.T_BOOL, IR.NOT, [shouldNotKill], fn shouldKill =>                      letPRIM("shouldKill", IR.T_BOOL, IR.NOT, [shouldNotKill], fn shouldKill =>
557                      letPRIM("isReallyDead", IR.T_BOOL, IR.OR, [shouldKill, isDead], fn isReallyDead =>                      letPRIM("isReallyDead", IR.T_BOOL, IR.OR, [shouldKill, ttl], fn isReallyDead =>
558                      k(PS{pos = pos, vel = vel, size = size, isDead = isReallyDead, color = color})                      k(PS{pos = pos, vel = vel, size = size, ttl = isReallyDead, color = color})
559                          ))))                          ))))
560                *)                *)
561    
# Line 516  Line 579 
579                    letPRIM("magRatio", IR.T_FLOAT, IR.DIV, [distToP, psvToIRVar(env, maxRad)], fn magRatio =>                    letPRIM("magRatio", IR.T_FLOAT, IR.DIV, [distToP, psvToIRVar(env, maxRad)], fn magRatio =>
580                    letPRIM("oneMinMR", IR.T_FLOAT, IR.SUB, [IR.newConst("one", IR.C_FLOAT 1.0), magRatio], fn oneMinMR =>                    letPRIM("oneMinMR", IR.T_FLOAT, IR.SUB, [IR.newConst("one", IR.C_FLOAT 1.0), magRatio], fn oneMinMR =>
581                    letPRIM("gravityMag", IR.T_FLOAT, IR.MULT, [oneMinMR, psvToIRVar(env, mag)], fn gravityMag =>                    letPRIM("gravityMag", IR.T_FLOAT, IR.MULT, [oneMinMR, psvToIRVar(env, mag)], fn gravityMag =>
582                    letPRIM("totalMag", IR.T_FLOAT, IR.MULT, [gravityMag, psvToIRVar(env, timeStep)], fn totMag =>                    letPRIM("totalMag", IR.T_FLOAT, IR.MULT, [gravityMag, psvToIRVar(env, PSV.timeStep)], fn totMag =>
583                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>
584                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>
585                    letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [vel, acc], fn newVel =>                    letPRIM("ps_vel", IR.T_VEC, IR.ADD_VEC, [vel, acc], fn newVel =>
586                    goto(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, pos2=pos2, dummy=dummy}, blk)                    goto(PS{pos = pos, vel = newVel, size = size, ttl = ttl, color = color, pos2=pos2, dummy=dummy}, blk)
587                    )))))))                    )))))))
588                  )))))))))))                  )))))))))))
589                  end                  end
590    
591                (* just kill it. *)                (* just kill it. *)
592                (* | P.DIE => k(PS{pos = pos, vel = vel, size = size, isDead = IR.newConst("falseVar", IR.C_BOOL true), color = color, dummy=dummy}) *)                (* | P.DIE => k(PS{pos = pos, vel = vel, size = size, ttl = IR.newConst("falseVar", IR.C_BOOL true), color = color, dummy=dummy}) *)
593                | P.DIE => IR.DISCARD                | P.DIE => IR.DISCARD
594                | _ => raise Fail("Action not implemented...")                | _ => raise Fail("Action not implemented...")
595              (* end case *)              (* end case *)
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, numDead, 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)
# Line 551  Line 614 
614                                | (PSV.T_FLOAT, PSV.FLOAT floatVal) => IR.newConst(name, IR.C_FLOAT(floatVal))                                | (PSV.T_FLOAT, PSV.FLOAT floatVal) => IR.newConst(name, IR.C_FLOAT(floatVal))
615                                | (PSV.T_VEC3F, PSV.UNDEF) => IR.newGlobal(x, IR.T_VEC)                                | (PSV.T_VEC3F, PSV.UNDEF) => IR.newGlobal(x, IR.T_VEC)
616                                | (PSV.T_VEC3F, PSV.VEC3F vecVal) => IR.newConst(name, IR.C_VEC(vecVal))                                | (PSV.T_VEC3F, PSV.VEC3F vecVal) => IR.newConst(name, IR.C_VEC(vecVal))
617                                | _ => raise Fail("Error in setup, type mismatch between IR and PSV vars.")                                | _ => raise Fail("Error in setup, type mismatch between PSV vars and their binding.")
618                              (* end case *))                              (* end case *))
619                        in                        in
620                          PSV.Map.insert (map, x, x')                          PSV.Map.insert (map, x, x')
# Line 560  Line 623 
623                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)
624                  end                  end
625    
   
626            fun evalActs f [] state = f [] state            fun evalActs f [] state = f [] state
627              | evalActs f (psa :: psal) state = (case psa              | evalActs f (psa :: psal) state = (case psa
628                of P.SEQ(acts) => (case acts                of P.SEQ(acts) => (case acts
# Line 579  Line 641 
641    
642            (* At the highest level, we want to return when we reach the end of the action list *)            (* At the highest level, we want to return when we reach the end of the action list *)
643            fun trActs [] state = let            fun trActs [] state = let
644                  val PS{pos, vel, size, isDead, color, pos2, dummy} = state                  val PS{pos, vel, size, ttl, color, pos2, dummy} = state
645                  in                  in
646                    IR.mkRETURN[ pos, vel, size, isDead, color, pos2, dummy ]                    IR.mkRETURN (
647                        [ pos, vel, size, ttl, color, pos2, dummy ],
648                        [IR.POS, IR.VEL, IR.SZ, IR.TTL, IR.COLOR, IR.POS2, IR.DUMMY]
649                      )
650                  end (* trActs *)                  end (* trActs *)
651              | trActs _ _ = raise Fail "Should never reach here"              | trActs _ _ = raise Fail "Should never reach here"
652    
# Line 597  Line 662 
662            )            )
663    
664            (* The entry block is the emitter, and the rest of the blocks define the physics processing. *)            (* The entry block is the emitter, and the rest of the blocks define the physics processing. *)
665    
666          fun isGlobal(IR.V{scope, ...}) = (case scope
667            of IR.S_GLOBAL(v) => true
668             | _ => false
669            (* end case *))
670    
671          fun extractVarMap(TE(blks, map)) = map
672    
673            val outPgm = PSysIR.PGM {            val outPgm = PSysIR.PGM {
674                globals = PSV.Map.filter isGlobal (extractVarMap env),
675              emitter = entryBlock,              emitter = entryBlock,
676              physics = List.drop(!blks, 1),              physics = List.nth(!blks, 1),
677              render = render              render = render
678            }            }
679    
680            val optimized = if (Checker.checkIR(outPgm)) then Optimize.optimizeIR(outPgm) else outPgm            val optimized = if (Checker.checkIR(outPgm)) then (printErr "Pre-optimization complete."; Optimize.optimizeIR(outPgm)) else outPgm
681    
682            in            in
683              IR.outputPgm(TextIO.stdErr, outPgm);              (* IR.outputPgm(TextIO.stdErr, outPgm); *)
684              if Checker.checkIR(optimized) then              if Checker.checkIR(optimized) then
685               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)
686              else              else
687               ();               ();
             IR.outputPgm(TextIO.stdErr, optimized);  
688              optimized              optimized
689            end (* compile *)            end (* compile *)
690    

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

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