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 873, Wed May 5 20:18:00 2010 UTC revision 1050, Fri Jan 21 18:08:14 2011 UTC
# Line 8  Line 8 
8    
9  structure Translate : sig  structure Translate : sig
10    
11      val compile : Particles.particle_group -> PSysIR.program      val compile : Particles.program -> PSysIR.program
12    
13    end = struct    end = struct
14    
# 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            rot : IR.var,           (* float *)
30            pos2 : IR.var,          (* vec3 *)
31          dummy : IR.var          dummy : IR.var
32        }        }
33    
34    (* 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 *)  
35      val epsilon = PSV.constf(0.00001)      val epsilon = PSV.constf(0.00001)
36    
37    (* constants *)    (* constants *)
# Line 52  Line 52 
52    
53    
54      fun retState s = let      fun retState s = let
55        val PS{pos, vel, size, isDead, color, dummy} = s        val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = s
56       in       in
57        IR.mkRETURN [pos, vel, size, isDead, color, dummy]        IR.mkRETURN (
58            [pos, vel, size, ttl, color, rot, pos2, dummy],
59            [IR.POS, IR.VEL, IR.SZ, IR.TTL, IR.COLOR, IR.ROT, IR.POS2, IR.DUMMY]
60          )
61       end       end
62    
63    (* translation environment *)    (* translation environment *)
# Line 72  Line 75 
75            val pos = IR.newParam ("ps_pos", IR.T_VEC)            val pos = IR.newParam ("ps_pos", IR.T_VEC)
76            val vel = IR.newParam ("ps_vel", IR.T_VEC)            val vel = IR.newParam ("ps_vel", IR.T_VEC)
77            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
78            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val ttl = IR.newParam ("ps_ttl", IR.T_FLOAT)
79            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
80              val rot = IR.newParam("ps_rot", IR.T_FLOAT)
81            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
82            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, dummy=dummy}            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
83            val blk = IR.newBlock ([pos, vel, size, isDead, color, dummy], k state)            val state = PS{pos=pos, vel=vel, size=size, ttl=ttl, color=color, rot=rot, pos2=pos2, dummy=dummy}
84              val blk = IR.newBlock ([pos, vel, size, ttl, color, rot, pos2, dummy], k state)
85            in            in
86              blks := blk :: !blks;              blks := blk :: !blks;
87              blk              blk
# Line 86  Line 91 
91            val pos = IR.newParam ("ps_pos", IR.T_VEC)            val pos = IR.newParam ("ps_pos", IR.T_VEC)
92            val vel = IR.newParam ("ps_vel", IR.T_VEC)            val vel = IR.newParam ("ps_vel", IR.T_VEC)
93            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
94            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val ttl = IR.newParam ("ps_ttl", IR.T_FLOAT)
95            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
96              val rot = IR.newParam("ps_rot", IR.T_FLOAT)
97            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
98            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, dummy = dummy}            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
99            val blk = IR.newBlock ([pos, vel, size, isDead, color, dummy] @ args, k state)            val state = PS{pos=pos, vel=vel, size=size, ttl=ttl, color=color, rot=rot, pos2=pos2, dummy=dummy}
100              val blk = IR.newBlock ([pos, vel, size, ttl, color, rot, pos2, dummy] @ args, k state)
101            in            in
102              blks := blk :: !blks;              blks := blk :: !blks;
103              blk              blk
104            end            end
105    
106      fun goto (PS{pos, vel, size, isDead, color, dummy}, blk) =      fun goto (PS{pos, vel, size, ttl, color, rot, pos2, dummy}, blk) =
107            IR.mkGOTO(blk, [pos, vel, size, isDead, color, dummy])            IR.mkGOTO(blk, [pos, vel, size, ttl, color, rot, pos2, dummy])
108    
109          fun gotoWithArgs(PS{pos, vel, size, isDead, color, dummy}, args, blk) =          fun gotoWithArgs(PS{pos, vel, size, ttl, color, rot, pos2, dummy}, args, blk) =
110            IR.mkGOTO(blk, [pos, vel, size, isDead, color, dummy] @ args)            IR.mkGOTO(blk, [pos, vel, size, ttl, color, rot, pos2, dummy] @ args)
111    
112      fun letPRIM (x, ty, p, args, body) = let      fun letPRIM (x, ty, p, args, body) = let
113            val x' = IR.newLocal(x, ty, (p, args))            val x' = IR.newLocal(x, ty, (p, args))
# Line 125  Line 132 
132            letPRIM("testNAND", IR.T_BOOL, IR.NOT, [testAND], fn testNAND =>            letPRIM("testNAND", IR.T_BOOL, IR.NOT, [testAND], fn testNAND =>
133            letPRIM(result, IR.T_BOOL, IR.AND, [testOR, testNAND], stmt))))            letPRIM(result, IR.T_BOOL, IR.AND, [testOR, testNAND], stmt))))
134    
135        fun genFloatVar (fltVar, env, domain : Float.float P.domain, dist, stmt : IR.var -> IR.stmt) = let
136          fun genRandVal(var, stmt : IR.var -> IR.stmt) = (case dist
137            of P.DIST_UNIFORM =>
138              letPRIM(var, IR.T_FLOAT, IR.RAND, [], stmt)
139    
140             (* The PDF here is f(x) = 2x when 0 < x <= 1, so the CDF is going
141              * to be the integral of f from 0 -> y => y^2. Hence, whenever we
142              * generate a random number, in order to get the random value according
143              * to this probability distribution, we just square it.
144              *)
145             | P.DIST_INC_LIN =>
146              letPRIM("randVal", IR.T_FLOAT, IR.RAND, [], fn randVal =>
147              letPRIM(var, IR.T_FLOAT, IR.MULT, [randVal, randVal], stmt))
148    
149             (* The PDF here is f(x) = -2x + 2 when 0 <= x < 1, so the CDF is going
150              * to be the integral of f from 0 -> y => -(y^2) + 2y. Hence, whenever we
151              * generate a random number, in order to get the random value according
152              * to this probability distribution, we just square it.
153              *)
154             | P.DIST_DEC_LIN =>
155              letPRIM("randVal", IR.T_FLOAT, IR.RAND, [], fn randVal =>
156              letPRIM("randSq", IR.T_FLOAT, IR.MULT, [randVal, randVal], fn randSq =>
157              letPRIM("termOne", IR.T_FLOAT, IR.MULT, [randSq, IR.newConst("negOne", IR.C_FLOAT ~1.0)], fn termOne =>
158              letPRIM("termTwo", IR.T_FLOAT, IR.MULT, [randVal, IR.newConst("negOne", IR.C_FLOAT 2.0)], fn termTwo =>
159              letPRIM(var, IR.T_FLOAT, IR.ADD, [termOne, termTwo], stmt)
160              ))))
161    
162             | _ => raise Fail "Unable to create random float for specified distribution."
163           (* end case *))
164         in
165         (case domain
166          of P.D_POINT(pt) =>
167             (* Our options here are pretty limited... *)
168             letPRIM (fltVar, IR.T_FLOAT, IR.COPY, [psvToIRVar(env, pt)], stmt)
169    
170           | P.D_BOX{max, min} =>
171             genRandVal("randf", fn rand =>
172             letPRIM("boxDiff", IR.T_FLOAT, IR.SUB, [psvToIRVar(env, max), psvToIRVar(env, max)], fn diff =>
173             letPRIM("scale", IR.T_FLOAT, IR.MULT, [diff, rand], fn scale =>
174             letPRIM( fltVar, IR.T_FLOAT, IR.ADD, [psvToIRVar(env, max), scale], stmt )
175             )))
176           | _ => raise Fail "Cannot generate float in specified domain."
177         (* end case *))
178        end
179    
180    (* 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 *)
181      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
182             of P.D_POINT(pt) =>             of P.D_POINT(pt) =>
183               (* Our options here are pretty limited... *)               (* Our options here are pretty limited... *)
184                  letPRIM (vecVar, IR.T_VEC, IR.COPY, [psvToIRVar(env, pt)], stmt)                  letPRIM (vecVar, IR.T_VEC, IR.COPY, [psvToIRVar(env, pt)], stmt)
# Line 291  Line 343 
343               * behind it (with respect to the normal)               * behind it (with respect to the normal)
344               *)               *)
345                | P.D_PLANE{pt, normal} =>                | P.D_PLANE{pt, normal} =>
346                    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 =>
347                    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 =>
348                    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)))
349    
# Line 302  Line 354 
354               * orad.               * orad.
355               *)               *)
356                | P.D_DISC{pt, normal, orad, irad} =>                | P.D_DISC{pt, normal, orad, irad} =>
357                    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 =>  
358                    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 =>
359                    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 =>
360                    letPRIM("inOrad", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), posToPtLen], fn inOrad =>  
361                    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 =>
362                      letPRIM("perpPosToP", IR.T_VEC, IR.SUB_VEC, [posToPt, posToPtParallelToNormal], fn posToPtPerpToNormal =>
363                      letPRIM("inDiscLen", IR.T_FLOAT, IR.LEN, [posToPtPerpToNormal], fn posToPtLen =>
364    
365                      letPRIM("inOradGt", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), posToPtLen], fn inOradGt =>
366                      letPRIM("inOradEq", IR.T_BOOL, IR.EQUALS, [psvToIRVar(env, orad), posToPtLen], fn inOradEq =>
367                      letPRIM("inOrad", IR.T_BOOL, IR.OR, [inOradGt, inOradEq], fn inOrad =>
368    
369                      letPRIM("inIradGt", IR.T_BOOL, IR.GT, [posToPtLen, psvToIRVar(env, irad)], fn inIradGt =>
370                      letPRIM("inIradEq", IR.T_BOOL, IR.EQUALS, [posToPtLen, psvToIRVar(env, irad)], fn inIradEq =>
371                      letPRIM("inIrad", IR.T_BOOL, IR.OR, [inIradGt, inIradEq], fn inIrad =>
372    
373                    letPRIM("inBothRad", IR.T_BOOL, IR.AND, [inIrad, inOrad], fn inBothRad =>                    letPRIM("inBothRad", IR.T_BOOL, IR.AND, [inIrad, inOrad], fn inBothRad =>
374                    letPRIM(boolVar, IR.T_BOOL, IR.AND, [inDisc, inBothRad], stmt))))))))  
375                      letPRIM(boolVar, IR.T_BOOL, IR.AND, [inDisc, inBothRad], stmt))))))))))))))
376    
377              (* 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
378               * specified bounds.               * specified bounds.
# Line 342  Line 405 
405              genVecVar("ps_pos", env, posDomain, fn newPos =>              genVecVar("ps_pos", env, posDomain, fn newPos =>
406              genVecVar("ps_vel", env, velDomain, fn newVel =>              genVecVar("ps_vel", env, velDomain, fn newVel =>
407              genVecVar("ps_col", env, colDomain, fn newCol =>              genVecVar("ps_col", env, colDomain, fn newCol =>
408              letSPRIM ("ps_size", IR.T_FLOAT, IR.RAND, [], fn newSize =>              letPRIM ("randSize", IR.T_FLOAT, IR.RAND, [], fn randSize =>
409              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 =>
410                letSPRIM("ps_size", IR.T_FLOAT, IR.ADD, [halfSize, IR.newConst("scalar", IR.C_FLOAT 0.5)], fn newSize =>
411                letSPRIM ("ps_ttl", IR.T_FLOAT, IR.COPY, [IR.newConst("fbool", IR.C_FLOAT 10000.0)], fn newIsDead =>
412                k(PS{pos = newPos,                k(PS{pos = newPos,
413                     vel = newVel,                     vel = newVel,
414                     size = newSize,                     size = newSize,
415                     isDead = newIsDead,                     ttl = newIsDead,
416                     color = newCol,                     color = newCol,
417                     dummy = IR.newConst("dmy", IR.C_FLOAT 0.01)})                     rot = IR.newConst("ps_rot", IR.C_FLOAT 0.0),
418              )))))                     pos2 = IR.newConst("ps_pos2", IR.C_VEC {x=0.0, y=0.0, z=0.0}),
419                       dummy = IR.newConst("ps_dummy", IR.C_FLOAT 0.01)})
420                )))))))
421    
422      (* 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
423       * 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 393  Line 460 
460    
461          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let
462    
463            val PS{isDead, ...} = state            val PS{ttl, ...} = state
464            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit            val P.EMIT{range, dist, posDomain, velDomain, colDomain, ...} = emit
465            val blk = newBlock (env, k)            val blk = newBlock (env, k)
466           in           in
467              letPRIM("isDead", IR.T_BOOL, IR.GT, [IR.newConst("small", IR.C_FLOAT 0.1), ttl], fn isDead =>
468        IR.mkIF(isDead,        IR.mkIF(isDead,
469         (* then *)         (* then *)
470         letPRIM("t1", IR.T_FLOAT, IR.ITOF, [psvToIRVar (env, maxNum)], fn t1 =>         genFloatVar("t1", env, range, dist, fn t1 =>
471         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 =>
472         letPRIM("prob", IR.T_FLOAT, IR.DIV, [t1, t2], fn prob =>         letPRIM("prob", IR.T_FLOAT, IR.DIV, [t1, t2], fn prob =>
473         letPRIM("r", IR.T_FLOAT, IR.RAND, [], fn r =>         letPRIM("r", IR.T_FLOAT, IR.RAND, [], fn r =>
474         letPRIM("t3", IR.T_BOOL, IR.GT, [prob, r], fn t3 =>         letPRIM("t3", IR.T_BOOL, IR.GT, [prob, r], fn t3 =>
# Line 411  Line 479 
479          (* else *)          (* else *)
480          IR.DISCARD)))))),          IR.DISCARD)))))),
481         (* else *)         (* else *)
482         retState state)         retState state))
483       end       end
484    
485          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 426  Line 494 
494           end           end
495    
496      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let
497            val PS{pos, vel, size, isDead, color, dummy} = state            val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = state
498            in            in
499              case action              case action
500               of P.BOUNCE{friction, resilience, cutoff, d} => let               of P.BOUNCE{friction, resilience, cutoff, d} => let
501                    val blk = newBlock (env, k)                    val blk = newBlock (env, k)
502                    val negOne = IR.newConst("negOne", IR.C_FLOAT ~1.0)                    val negOne = IR.newConst("negOne", IR.C_FLOAT ~1.0)
503                    in                    in
504                      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 =>
505                      letPRIM("np", IR.T_VEC, IR.ADD_VEC, [pos, velScale], fn nextPos =>                      letPRIM("np", IR.T_VEC, IR.ADD_VEC, [pos, velScale], fn nextPos =>
506                      mkWithinVar("wnp", env, pos, d, fn withinNextPos =>                      mkWithinVar("wcp", env, pos, d, fn withinCurPos =>
507                      IR.mkIF(withinNextPos,                      mkWithinVar("wnp", env, nextPos, d, fn withinNextPos =>
508                        letPRIM("nwcp", IR.T_BOOL, IR.NOT, [withinCurPos], fn notWithinCurPos =>
509                        letPRIM("sb", IR.T_BOOL, IR.AND, [notWithinCurPos, withinNextPos], fn shouldBounce =>
510                        IR.mkIF(shouldBounce,
511                        (*then*)                        (*then*)
512                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let
513                 val PS{pos=nextPos, vel=nextVel, size=nextSize, isDead=nextIsDead, color=nextColor, dummy=nextDummy} = state'                 val PS{pos=nextPos, vel=nextVel, size=nextSize, ttl=nextIsDead, color=nextColor, rot=nextRot, pos2=nextPos2, dummy=nextDummy} = state'
514                            in                            in
515                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>
516                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>
# Line 458  Line 529 
529                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>
530                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>
531                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>
532                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, dummy=nextDummy}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, ttl=nextIsDead, color=nextColor, rot=nextRot, pos2=nextPos2, dummy=nextDummy}, blk)
533                              )))),                              )))),
534                               (*else*)                               (*else*)
535                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>
536                               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 =>
537                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, dummy=nextDummy}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, ttl=nextIsDead, color=nextColor, rot=nextRot, pos2=nextPos2, dummy=nextDummy}, blk)
538                               ))                               ))
539                           )))))))))                           )))))))))
540                           end                           end
541                        ),                        ),
542                        (*else*)                        (*else*)
543                        goto(state, blk)))))                        goto(state, blk))))))))
544                    end                    end
545    
546                | P.GRAVITY(dir) =>                | P.ACCEL dir =>
547                      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 =>
548                      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 =>
549                        k(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, dummy=dummy})))                        k(PS{pos = pos, vel = newVel, size = size, ttl = ttl, color = color, rot=rot, pos2=pos2, dummy=dummy})))
550    
551                | P.MOVE =>                | P.MOVE =>
552                  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 =>
553                      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 =>
554                        k(PS{pos = newPos, vel = vel, size = size, isDead = isDead, color = color, dummy=dummy})))                        k(PS{pos = newPos, vel = vel, size = size, ttl = ttl, color = color, rot=rot, pos2=pos2, dummy=dummy})))
555                (*                (*
556                | P.SINK({d, kill_inside}) =>                | P.SINK({d, kill_inside}) =>
557                      mkWithinVar("isWithin", env, state, d, fn withinVal =>                      mkWithinVar("isWithin", env, state, d, fn withinVal =>
558                      mkXOR ("shouldNotKill", withinVal, psvToIRVar(env, kill_inside),                      mkXOR ("shouldNotKill", withinVal, psvToIRVar(env, kill_inside),
559                        fn shouldNotKill =>                        fn shouldNotKill =>
560                      letPRIM("shouldKill", IR.T_BOOL, IR.NOT, [shouldNotKill], fn shouldKill =>                      letPRIM("shouldKill", IR.T_BOOL, IR.NOT, [shouldNotKill], fn shouldKill =>
561                      letPRIM("isReallyDead", IR.T_BOOL, IR.OR, [shouldKill, isDead], fn isReallyDead =>                      letPRIM("isReallyDead", IR.T_BOOL, IR.OR, [shouldKill, ttl], fn isReallyDead =>
562                      k(PS{pos = pos, vel = vel, size = size, isDead = isReallyDead, color = color})                      k(PS{pos = pos, vel = vel, size = size, ttl = isReallyDead, color = color})
563                          ))))                          ))))
564                *)                *)
565    
# Line 512  Line 583 
583                    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 =>
584                    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 =>
585                    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 =>
586                    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 =>
587                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>
588                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>
589                    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 =>
590                    goto(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, dummy=dummy}, blk)                    goto(PS{pos = pos, vel = newVel, size = size, ttl = ttl, color = color, rot=rot, pos2=pos2, dummy=dummy}, blk)
591                    )))))))                    )))))))
592                  )))))))))))                  )))))))))))
593                  end                  end
594    
595                (* just kill it. *)                (* just kill it. *)
596                (* | 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}) *)
597                | P.DIE => IR.DISCARD                | P.DIE => IR.DISCARD
598                | _ => raise Fail("Action not implemented...")                | _ => raise Fail("Action not implemented...")
599              (* end case *)              (* end case *)
600            end            end
601    
602      fun compile (P.PG{      fun compile (P.PG{
603         emit as P.EMIT{maxNum, vars=emitVars, ...},         emit as P.EMIT{vars=emitVars, ...},
604         act as P.PSAE{action=root_act, vars=actionVars},         act as P.PSAE{action=root_act, vars=actionVars},
605         render         render
606      }) = let      }) = let
607            val blks = ref[]            val blks = ref[]
608            val env = let            val env = let
609                (* add special globals to free vars *)                (* add special globals to free vars *)
610                  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]))
611                  fun ins (x as PSV.V{name, ty, binding, id, ...}, map) = let                  fun ins (x as PSV.V{name, ty, binding, id, ...}, map) = let
612                        val x' = (case (ty, !binding)                        val x' = (case (ty, !binding)
613                               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 547  Line 618 
618                                | (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))
619                                | (PSV.T_VEC3F, PSV.UNDEF) => IR.newGlobal(x, IR.T_VEC)                                | (PSV.T_VEC3F, PSV.UNDEF) => IR.newGlobal(x, IR.T_VEC)
620                                | (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))
621                                | _ => 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.")
622                              (* end case *))                              (* end case *))
623                        in                        in
624                          PSV.Map.insert (map, x, x')                          PSV.Map.insert (map, x, x')
# Line 556  Line 627 
627                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)
628                  end                  end
629    
   
630            fun evalActs f [] state = f [] state            fun evalActs f [] state = f [] state
631              | evalActs f (psa :: psal) state = (case psa              | evalActs f (psa :: psal) state = (case psa
632                of P.SEQ(acts) => (case acts                of P.SEQ(acts) => (case acts
# Line 575  Line 645 
645    
646            (* 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 *)
647            fun trActs [] state = let            fun trActs [] state = let
648                  val PS{pos, vel, size, isDead, color, dummy} = state                  val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = state
649                  in                  in
650                    IR.mkRETURN[ pos, vel, size, isDead, color, dummy ]                    IR.mkRETURN (
651                        [ pos, vel, size, ttl, color, rot, pos2, dummy ],
652                        [IR.POS, IR.VEL, IR.SZ, IR.TTL, IR.COLOR, IR.ROT, IR.POS2, IR.DUMMY]
653                      )
654                  end (* trActs *)                  end (* trActs *)
655              | trActs _ _ = raise Fail "Should never reach here"              | trActs _ _ = raise Fail "Should never reach here"
656    
# Line 593  Line 666 
666            )            )
667    
668            (* 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. *)
669    
670          fun isGlobal(IR.V{scope, ...}) = (case scope
671            of IR.S_GLOBAL(v) => true
672             | _ => false
673            (* end case *))
674    
675          fun extractVarMap(TE(blks, map)) = map
676    
677            val outPgm = PSysIR.PGM {            val outPgm = PSysIR.PGM {
678                globals = PSV.Map.filter isGlobal (extractVarMap env),
679              emitter = entryBlock,              emitter = entryBlock,
680              physics = List.drop(!blks, 1),              physics = List.nth(!blks, 1),
681              render = render              render = render
682            }            }
683    
684            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
685    
686            in            in
687              IR.outputPgm(TextIO.stdErr, outPgm);              (* IR.outputPgm(TextIO.stdErr, outPgm); *)
688              if Checker.checkIR(optimized) then              if Checker.checkIR(optimized) then
689               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)
690              else              else
691               ();               ();
             IR.outputPgm(TextIO.stdErr, optimized);  
692              optimized              optimized
693            end (* compile *)            end (* compile *)
694    

Legend:
Removed from v.873  
changed lines
  Added in v.1050

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