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 770, Mon Feb 22 00:17:15 2010 UTC revision 868, Thu Apr 29 22:39:32 2010 UTC
# Line 8  Line 8 
8    
9  structure Translate : sig  structure Translate : sig
10    
11      val compile : Particles.particle_group -> PSysIR.block list      val compile : Particles.particle_group -> PSysIR.program
12    
13    end = struct    end = struct
14    
# Line 25  Line 25 
25          vel : IR.var,           (* vec3 *)          vel : IR.var,           (* vec3 *)
26          size : IR.var,          (* float *)          size : IR.var,          (* float *)
27          isDead : IR.var,        (* bool *)          isDead : IR.var,        (* bool *)
28          color : IR.var          (* vec3 (NOTE: should be vector4) *)          color : IR.var,         (* vec3 (NOTE: should be vector4) *)
29            dummy : IR.var
30        }        }
31    
32    (* special PSV global variables *)    (* special PSV global variables *)
# Line 66  Line 67 
67            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
68            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)
69            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
70            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color}            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
71            val blk = IR.newBlock ([pos, vel, size, isDead, color], k state)            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, dummy=dummy}
72              val blk = IR.newBlock ([pos, vel, size, isDead, color, dummy], k state)
73            in            in
74              blks := blk :: !blks;              blks := blk :: !blks;
75              blk              blk
# Line 79  Line 81 
81            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
82            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)
83            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
84            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color}            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
85            val blk = IR.newBlock ([pos, vel, size, isDead, color] @ args, k state)            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, dummy = dummy}
86              val blk = IR.newBlock ([pos, vel, size, isDead, color, dummy] @ args, k state)
87            in            in
88              blks := blk :: !blks;              blks := blk :: !blks;
89              blk              blk
90            end            end
91    
92      fun goto (PS{pos, vel, size, isDead, color}, blk) =      fun goto (PS{pos, vel, size, isDead, color, dummy}, blk) =
93            IR.mkGOTO(blk, [pos, vel, size, isDead, color])            IR.mkGOTO(blk, [pos, vel, size, isDead, color, dummy])
94    
95          fun gotoWithArgs(PS{pos, vel, size, isDead, color}, args, blk) =          fun gotoWithArgs(PS{pos, vel, size, isDead, color, dummy}, args, blk) =
96            IR.mkGOTO(blk, [pos, vel, size, isDead, color] @ args)            IR.mkGOTO(blk, [pos, vel, size, isDead, color, dummy] @ args)
97    
98      fun letPRIM (x, ty, p, args, body) = let      fun letPRIM (x, ty, p, args, body) = let
99            val x' = IR.newLocal(x, ty, (p, args))            val x' = IR.newLocal(x, ty, (p, args))
# Line 100  Line 103 
103    
104    (* prim bound to state variable (S_LOCAL for now) *)    (* prim bound to state variable (S_LOCAL for now) *)
105      fun letSPRIM(x, ty, p, args, body) = let      fun letSPRIM(x, ty, p, args, body) = let
106            val x' = IR.new(x, IR.S_LOCAL(p, args), ty)            val x' = IR.new(x, IR.S_LOCAL(ref (p, args)), ty)
107            in            in
108              IR.mkPRIM(x', p, args, body x')              IR.mkPRIM(x', p, args, body x')
109            end            end
# Line 306  Line 309 
309              genVecVar("ps_col", env, colDomain, fn newCol =>              genVecVar("ps_col", env, colDomain, fn newCol =>
310              letSPRIM ("ps_size", IR.T_FLOAT, IR.RAND, [], fn newSize =>              letSPRIM ("ps_size", IR.T_FLOAT, IR.RAND, [], fn newSize =>
311              letSPRIM ("ps_isDead", IR.T_BOOL, IR.COPY, [IR.newConst("fbool", IR.C_BOOL false)], fn newIsDead =>              letSPRIM ("ps_isDead", IR.T_BOOL, IR.COPY, [IR.newConst("fbool", IR.C_BOOL false)], fn newIsDead =>
312                k(PS{pos = newPos, vel = newVel, size = newSize, isDead = newIsDead, color = newCol}))))))                k(PS{pos = newPos, vel = newVel, size = newSize, isDead = newIsDead, color = newCol, dummy = IR.newConst("dmy", IR.C_FLOAT 0.01)}))))))
313    
314      (* 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
315       * 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 336  Line 339 
339                   )                   )
340    
341             | P.D_SPHERE{center, irad, orad} => let             | P.D_SPHERE{center, irad, orad} => let
342                val PS{pos, vel, size, isDead, color} = state                val PS{pos, vel, size, isDead, color, ...} = state
343                in                in
344                      letPRIM("sv", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, center)], fn subVec =>                      letPRIM("sv", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, center)], fn subVec =>
345                  letPRIM(retNorm, IR.T_VEC, IR.NORM, [subVec], fn newNormVar => k newNormVar state                  letPRIM(retNorm, IR.T_VEC, IR.NORM, [subVec], fn newNormVar => k newNormVar state
# Line 348  Line 351 
351          end          end
352    
353          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let
354            val PS{pos, vel, size, isDead, color} = state            fun retState s = let
355                val PS{pos, vel, size, isDead, color, dummy} = s
356               in
357                IR.mkRETURN [pos, vel, size, isDead, color, dummy]
358               end
359    
360              val PS{pos, vel, size, isDead, color, dummy} = state
361            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit
362            val blk = newBlock (env, k)            val blk = newBlock (env, k)
363           in           in
# Line 362  Line 371 
371         IR.mkIF(t3,         IR.mkIF(t3,
372          (* then *)          (* then *)
373          newParticle (posDomain, velDomain, colDomain, env,          newParticle (posDomain, velDomain, colDomain, env,
374           fn state' => goto (state', blk)),           fn state' => retState state'),
375          (* else *)          (* else *)
376          IR.DISCARD)))))),          IR.DISCARD)))))),
377         (* else *)         (* else *)
378         goto (state, blk))         IR.DISCARD)
379       end       end
380    
381          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
382            val PS{pos, vel, size, isDead, color} = state            val PS{pos, vel, size, isDead, color, ...} = state
383            val P.PR{ifstmt, ...} = pred            val P.PR{ifstmt, ...} = pred
           val thenBlk = newBlock(env, thenk)  
           val elseBlk = newBlock(env, elsek)  
384           in           in
385            case ifstmt            case ifstmt
386             of P.WITHIN(d) => mkWithinVar("wv", env, pos, d, fn withinVar =>             of P.WITHIN(d) => mkWithinVar("wv", env, pos, d, fn withinVar =>
387              IR.mkIF(withinVar, goto(state, thenBlk), goto(state, elseBlk)))              IR.mkIF(withinVar, thenk(state), elsek(state)))
388              | P.WITHINVEL(d) => mkWithinVar("wv", env, vel, d, fn withinVar =>              | P.WITHINVEL(d) => mkWithinVar("wv", env, vel, d, fn withinVar =>
389              IR.mkIF(withinVar, goto(state, thenBlk), goto(state, elseBlk)))              IR.mkIF(withinVar, thenk(state), elsek(state)))
390           end           end
391    
392      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let
393            val PS{pos, vel, size, isDead, color} = state            val PS{pos, vel, size, isDead, color, dummy} = state
394            in            in
395              case action              case action
396               of P.BOUNCE{friction, resilience, cutoff, d} => let               of P.BOUNCE{friction, resilience, cutoff, d} => let
# Line 396  Line 403 
403                      IR.mkIF(withinNextPos,                      IR.mkIF(withinNextPos,
404                        (*then*)                        (*then*)
405                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let
406                 val PS{pos=nextPos, vel=nextVel, size=nextSize, isDead=nextIsDead, color=nextColor} = state'                 val PS{pos=nextPos, vel=nextVel, size=nextSize, isDead=nextIsDead, color=nextColor, dummy=nextDummy} = state'
407                            in                            in
408                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>
409                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>
# Line 415  Line 422 
422                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>
423                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>
424                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>
425                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, dummy=nextDummy}, blk)
426                              )))),                              )))),
427                               (*else*)                               (*else*)
428                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>
429                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>
430                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, dummy=nextDummy}, blk)
431                               ))                               ))
432                           )))))))))                           )))))))))
433                           end                           end
# Line 432  Line 439 
439                | P.GRAVITY(dir) =>                | P.GRAVITY(dir) =>
440                      letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, timeStep), psvToIRVar(env, dir)], fn theScale =>                      letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, timeStep), psvToIRVar(env, dir)], fn theScale =>
441                      letPRIM("nextVel", IR.T_VEC, IR.ADD_VEC, [theScale, vel], fn newVel =>                      letPRIM("nextVel", IR.T_VEC, IR.ADD_VEC, [theScale, vel], fn newVel =>
442                        k(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color})))                        k(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, dummy=dummy})))
443    
444                | P.MOVE =>                | P.MOVE =>
445                  letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, timeStep), vel], fn theScale =>                  letPRIM("scaledVec", IR.T_VEC, IR.SCALE, [psvToIRVar(env, timeStep), vel], fn theScale =>
446                      letPRIM("nextPos", IR.T_VEC, IR.ADD_VEC, [theScale, pos], fn newPos =>                      letPRIM("nextPos", IR.T_VEC, IR.ADD_VEC, [theScale, pos], fn newPos =>
447                        k(PS{pos = newPos, vel = vel, size = size, isDead = isDead, color = color})))                        k(PS{pos = newPos, vel = vel, size = size, isDead = isDead, color = color, dummy=dummy})))
448                (*                (*
449                | P.SINK({d, kill_inside}) =>                | P.SINK({d, kill_inside}) =>
450                      mkWithinVar("isWithin", env, state, d, fn withinVal =>                      mkWithinVar("isWithin", env, state, d, fn withinVal =>
# Line 473  Line 480 
480                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>
481                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>
482                    letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [vel, acc], fn newVel =>                    letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [vel, acc], fn newVel =>
483                    goto(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color}, blk)                    goto(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, dummy=dummy}, blk)
484                    )))))))                    )))))))
485                  )))))))))))                  )))))))))))
486                  end                  end
487    
488                (* just kill it. *)                (* just kill it. *)
489                | P.DIE => k(PS{pos = pos, vel = vel, size = size, isDead = IR.newConst("falseVar", IR.C_BOOL true), color = color})                | P.DIE => k(PS{pos = pos, vel = vel, size = size, isDead = IR.newConst("falseVar", IR.C_BOOL true), color = color, dummy=dummy})
490                | _ => raise Fail("Action not implemented...")                | _ => raise Fail("Action not implemented...")
491              (* end case *)              (* end case *)
492            end            end
493    
494      fun compile (P.PG{emit as P.EMIT{maxNum, vars=emitVars, ...}, act as P.PSAE{action=root_act, vars=actionVars}, ...}) = let      fun compile (P.PG{
495           emit as P.EMIT{maxNum, vars=emitVars, ...},
496           act as P.PSAE{action=root_act, vars=actionVars},
497           render
498        }) = let
499            val blks = ref[]            val blks = ref[]
500            val env = let            val env = let
501                (* add special globals to free vars *)                (* add special globals to free vars *)
# Line 502  Line 513 
513                                | _ => raise Fail("Error in setup, type mismatch between IR and PSV vars.")                                | _ => raise Fail("Error in setup, type mismatch between IR and PSV vars.")
514                              (* end case *))                              (* end case *))
515                        in                        in
                     (* printErr (String.concat["Inserting ", name, " with ID ", Int.toString id, " to IR Var list: ", IR.varToString x']); *)  
516                          PSV.Map.insert (map, x, x')                          PSV.Map.insert (map, x, x')
517                        end                        end
518                  in                  in
519                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)
520                  end                  end
521            fun trActs [] state = let  
522                  val PS{pos, vel, size, isDead, color} = state  
523                  in            fun evalActs f [] state = f [] state
524                    IR.mkRETURN[ pos, vel, size, isDead, color ]              | evalActs f (psa :: psal) state = (case psa
                 end (* trActs *)  
             | trActs (psa :: psal) state = (case psa  
525                of P.SEQ(acts) => (case acts                of P.SEQ(acts) => (case acts
526                   of [] => raise Fail "Should never reach here."                   of [] => raise Fail "Should never reach here."
527                    | [act] => trAct(act, env, state, trActs psal)                    | [act] => trAct(act, env, state, evalActs f psal)
528                    | act :: rest => trAct(act, env, state, trActs (P.SEQ(rest) :: psal))                    | act :: rest => trAct(act, env, state, evalActs f (P.SEQ(rest) :: psal))
529                  (* end case *))                  (* end case *))
530                 | P.PRED(pred as P.PR{thenstmt=t, elsestmt=e, ...}) =>                 | P.PRED(pred as P.PR{thenstmt=t, elsestmt=e, ...}) => let
531                    trPred(pred, env, state, trActs (t @ psal), trActs (e @ psal))                     val cblk = newBlock(env, evalActs f psal)
532                       fun trPredActs [] state' = goto(state', cblk)
533                         | trPredActs _ _ = raise Fail "Should never reach here."
534                      in
535                       trPred(pred, env, state, evalActs trPredActs t, evalActs trPredActs e)
536                      end
537                (* end case *))                (* end case *))
538    
539            val entryBlock = newBlock (env, fn pstate => trEmitter(emit, env, pstate, fn state => trActs root_act state))            (* At the highest level, we want to return when we reach the end of the action list *)
540              fun trActs [] state = let
541                    val PS{pos, vel, size, isDead, color, dummy} = state
542                    in
543                      IR.mkRETURN[ pos, vel, size, isDead, color, dummy ]
544                    end (* trActs *)
545                | trActs _ _ = raise Fail "Should never reach here"
546    
547              (* The entry block is the first block of the program, or in other words, the emitter. *)
548              val entryBlock = newBlock (
549                env,
550                fn pstate => trEmitter(
551                  emit,
552                  env,
553                  pstate,
554                  fn state => evalActs trActs root_act state
555                )
556              )
557    
558              (* The entry block is the emitter, and the rest of the blocks define the physics processing. *)
559              val outPgm = PSysIR.PGM {
560                emitter = entryBlock,
561                physics = List.drop(!blks, 1),
562                render = render
563              }
564    
565              val optimized = if (Checker.checkIR(outPgm)) then Optimize.optimizeIR(outPgm) else outPgm
566    
567            in            in
568              IR.output(TextIO.stdErr, !blks);              IR.outputPgm(TextIO.stdErr, outPgm);
569              if Checker.checkIR(!blks) then              if Checker.checkIR(optimized) then
570                (* note that the entryBlock will be the first block *)               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)
               (IR.output(TextIO.stdErr, Optimize.optimizeIR(!blks));  
               !blks)  
571              else              else
572                []               ();
573                IR.outputPgm(TextIO.stdErr, optimized);
574                optimized
575            end (* compile *)            end (* compile *)
576    
577      end (* Translate *)      end (* Translate *)

Legend:
Removed from v.770  
changed lines
  Added in v.868

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