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 1017, Tue Jan 18 22:19:53 2011 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 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 *)
30            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 49  Line 49 
49              k state              k state
50            )            )
51    
52    
53        fun retState s = let
54          val PS{pos, vel, size, ttl, color, pos2, dummy} = s
55         in
56          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
61    
62    (* translation environment *)    (* translation environment *)
63      datatype env = TE of (IR.block list ref * IR.var PSV.Map.map)      datatype env = TE of (IR.block list ref * IR.var PSV.Map.map)
64    
# Line 64  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 state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color}            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
80            val blk = IR.newBlock ([pos, vel, size, isDead, color], k state)            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
81              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, ttl, color, pos2, dummy], k state)
83            in            in
84              blks := blk :: !blks;              blks := blk :: !blks;
85              blk              blk
# Line 77  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 state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color}            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
95            val blk = IR.newBlock ([pos, vel, size, isDead, color] @ args, k state)            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
96              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, 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}, blk) =      fun goto (PS{pos, vel, size, ttl, color, pos2, dummy}, blk) =
104            IR.mkGOTO(blk, [pos, vel, size, isDead, color])            IR.mkGOTO(blk, [pos, vel, size, ttl, color, pos2, dummy])
105    
106          fun gotoWithArgs(PS{pos, vel, size, isDead, color}, args, blk) =          fun gotoWithArgs(PS{pos, vel, size, ttl, color, pos2, dummy}, args, blk) =
107            IR.mkGOTO(blk, [pos, vel, size, isDead, color] @ 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 100  Line 114 
114    
115    (* prim bound to state variable (S_LOCAL for now) *)    (* prim bound to state variable (S_LOCAL for now) *)
116      fun letSPRIM(x, ty, p, args, body) = let      fun letSPRIM(x, ty, p, args, body) = let
117            val x' = IR.new(x, IR.S_LOCAL(p, args), ty)            val x' = IR.new(x, IR.S_LOCAL(ref (p, args)), ty)
118            in            in
119              IR.mkPRIM(x', p, args, body x')              IR.mkPRIM(x', p, args, body x')
120            end            end
# Line 115  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 129  Line 188 
188                  letPRIM ("pt2s", IR.T_VEC, IR.SCALE, [randInv, psvToIRVar(env, pt2)], fn pt2ScaleVec =>                  letPRIM ("pt2s", IR.T_VEC, IR.SCALE, [randInv, psvToIRVar(env, pt2)], fn pt2ScaleVec =>
189                  letPRIM (vecVar, IR.T_VEC, IR.ADD_VEC, [pt1ScaleVec, pt2ScaleVec], stmt)))))                  letPRIM (vecVar, IR.T_VEC, IR.ADD_VEC, [pt1ScaleVec, pt2ScaleVec], stmt)))))
190    
191            (* This is a bit more complicated if we're trying to avoid accessing              | P.D_BOX{max, min} =>
192             * the vector variables themselves. Basically the way we can do it is to                  (* Extract the componentwise vector variables *)
193             * decompose the vector connecting min and max into the basis vectors,                  letPRIM("minX", IR.T_FLOAT, IR.EXTRACT_X, [psvToIRVar(env, min)], fn minX =>
194             * scale them independently, and then add them back together.                  letPRIM("maxX", IR.T_FLOAT, IR.EXTRACT_X, [psvToIRVar(env, max)], fn maxX =>
195             *                  letPRIM("minY", IR.T_FLOAT, IR.EXTRACT_Y, [psvToIRVar(env, min)], fn minY =>
196             * !FIXME! Actually do that. Don't have time right now...                  letPRIM("maxY", IR.T_FLOAT, IR.EXTRACT_Y, [psvToIRVar(env, max)], fn maxY =>
197             *)                  letPRIM("minZ", IR.T_FLOAT, IR.EXTRACT_Z, [psvToIRVar(env, min)], fn minZ =>
198              | P.D_BOX{max, min} => raise Fail "Cannot generate point in D_BOX."                  letPRIM("maxZ", IR.T_FLOAT, IR.EXTRACT_Z, [psvToIRVar(env, max)], fn maxZ =>
199    
200                    (* Find the distance in each component *)
201                    letPRIM("distX", IR.T_FLOAT, IR.SUB, [maxX, minX], fn distX =>
202                    letPRIM("distY", IR.T_FLOAT, IR.SUB, [maxY, minY], fn distY =>
203                    letPRIM("distZ", IR.T_FLOAT, IR.SUB, [maxZ, minZ], fn distZ =>
204    
205                    (* Get three random numbers for each of the components *)
206                    letPRIM("randX", IR.T_FLOAT, IR.RAND, [], fn randX =>
207                    letPRIM("randY", IR.T_FLOAT, IR.RAND, [], fn randY =>
208                    letPRIM("randZ", IR.T_FLOAT, IR.RAND, [], fn randZ =>
209    
210                    (* Scale the distances by these random numbers *)
211                    letPRIM("scaledX", IR.T_FLOAT, IR.MULT, [randX, distX], fn scaledX =>
212                    letPRIM("scaledY", IR.T_FLOAT, IR.MULT, [randY, distY], fn scaledY =>
213                    letPRIM("scaledZ", IR.T_FLOAT, IR.MULT, [randZ, distZ], fn scaledZ =>
214    
215                    (* Add them to the minimum vec in order to create a new vec inside
216                     * of the box.
217                     *)
218                    letPRIM("newX", IR.T_FLOAT, IR.ADD, [minX, scaledX], fn newX =>
219                    letPRIM("newY", IR.T_FLOAT, IR.ADD, [minY, scaledY], fn newY =>
220                    letPRIM("newZ", IR.T_FLOAT, IR.ADD, [minZ, scaledZ], fn newZ =>
221    
222                    (* Gen the vector *)
223                    letPRIM(vecVar, IR.T_VEC, IR.GEN_VEC, [newX, newY, newZ], stmt
224    
225                    )))))))))))))))))))
226    
227    
228              | P.D_TRIANGLE{pt1, pt2, pt3} =>              | P.D_TRIANGLE{pt1, pt2, pt3} =>
229                  letPRIM ("pt1ToPt2", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt2), psvToIRVar(env, pt1)], fn pt1ToPt2 =>                  letPRIM ("pt1ToPt2", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt2), psvToIRVar(env, pt1)], fn pt1ToPt2 =>
# Line 253  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 264  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 304  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                k(PS{pos = newPos, vel = newVel, size = newSize, isDead = newIsDead, color = newCol}))))))              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,
410                       vel = newVel,
411                       size = newSize,
412                       ttl = newIsDead,
413                       color = newCol,
414                       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)})
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 336  Line 443 
443                   )                   )
444    
445             | P.D_SPHERE{center, irad, orad} => let             | P.D_SPHERE{center, irad, orad} => let
446                val PS{pos, vel, size, isDead, color} = state                val PS{pos, ...} = state
447                in                in
448                      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 =>
449                  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 455 
455          end          end
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            val PS{pos, vel, size, isDead, color} = state  
459            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit            val PS{ttl, ...} = state
460              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 =>
471         IR.mkIF(t3,         IR.mkIF(t3,
472          (* then *)          (* then *)
473          newParticle (posDomain, velDomain, colDomain, env,          newParticle (posDomain, velDomain, colDomain, env,
474           fn state' => goto (state', blk)),           fn state' => retState state'),
475          (* else *)          (* else *)
476          IR.DISCARD)))))),          IR.DISCARD)))))),
477         (* else *)         (* else *)
478         goto (state, blk))         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
482            val PS{pos, vel, size, isDead, color} = state            val PS{pos, vel, ...} = state
483            val P.PR{ifstmt, ...} = pred            val P.PR{ifstmt, ...} = pred
           val thenBlk = newBlock(env, thenk)  
           val elseBlk = newBlock(env, elsek)  
484           in           in
485            case ifstmt            case ifstmt
486             of P.WITHIN(d) => mkWithinVar("wv", env, pos, d, fn withinVar =>             of P.WITHIN(d) => mkWithinVar("wv", env, pos, d, fn withinVar =>
487              IR.mkIF(withinVar, goto(state, thenBlk), goto(state, elseBlk)))              IR.mkIF(withinVar, thenk(state), elsek(state)))
488              | P.WITHINVEL(d) => mkWithinVar("wv", env, vel, d, fn withinVar =>              | P.WITHINVEL(d) => mkWithinVar("wv", env, vel, d, fn withinVar =>
489              IR.mkIF(withinVar, goto(state, thenBlk), goto(state, elseBlk)))              IR.mkIF(withinVar, thenk(state), elsek(state)))
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} = 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} = 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 415  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}, 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}, 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})))                        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})))                        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 469  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}, 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})                (* | 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
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{emit as P.EMIT{maxNum, vars=emitVars, ...}, act as P.PSAE{action=root_act, vars=actionVars}, ...}) = let      fun compile (P.PG{
599           emit as P.EMIT{vars=emitVars, ...},
600           act as P.PSAE{action=root_act, vars=actionVars},
601           render
602        }) = 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 499  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
                     (* printErr (String.concat["Inserting ", name, " with ID ", Int.toString id, " to IR Var list: ", IR.varToString x']); *)  
620                          PSV.Map.insert (map, x, x')                          PSV.Map.insert (map, x, x')
621                        end                        end
622                  in                  in
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            fun trActs [] state = let  
626                  val PS{pos, vel, size, isDead, color} = state        fun evalActs f [] state = f [] state
627                  in              | evalActs f (psa :: psal) state = (case psa
                   IR.mkRETURN[ pos, vel, size, isDead, color ]  
                 end (* trActs *)  
             | trActs (psa :: psal) state = (case psa  
628                of P.SEQ(acts) => (case acts                of P.SEQ(acts) => (case acts
629                   of [] => raise Fail "Should never reach here."                   of [] => raise Fail "Should never reach here."
630                    | [act] => trAct(act, env, state, trActs psal)                    | [act] => trAct(act, env, state, evalActs f psal)
631                    | act :: rest => trAct(act, env, state, trActs (P.SEQ(rest) :: psal))                    | act :: rest => trAct(act, env, state, evalActs f (P.SEQ(rest) :: psal))
632                    (* end case *))
633                   | P.PRED(pred as P.PR{thenstmt=t, elsestmt=e, ...}) => let
634                       val cblk = newBlock(env, evalActs f psal)
635                       fun trPredActs [] state' = goto(state', cblk)
636                         | trPredActs _ _ = raise Fail "Should never reach here."
637                      in
638                       trPred(pred, env, state, evalActs trPredActs t, evalActs trPredActs e)
639                      end
640                  (* end case *))                  (* end case *))
641                 | P.PRED(pred as P.PR{thenstmt=t, elsestmt=e, ...}) =>  
642                    trPred(pred, env, state, trActs (t @ psal), trActs (e @ psal))            (* At the highest level, we want to return when we reach the end of the action list *)
643              fun trActs [] state = let
644                    val PS{pos, vel, size, ttl, color, pos2, dummy} = state
645                    in
646                      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 *)
651                | trActs _ _ = raise Fail "Should never reach here"
652    
653              (* The entry block is the first block of the program, or in other words, the emitter. *)
654              val entryBlock = newBlock (
655                env,
656                fn pstate => trEmitter(
657                  emit,
658                  env,
659                  pstate,
660                  fn state => evalActs trActs root_act state
661                )
662              )
663    
664          (* 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 *))                (* end case *))
670    
671            val entryBlock = newBlock (env, fn pstate => trEmitter(emit, env, pstate, fn state => trActs root_act state))        fun extractVarMap(TE(blks, map)) = map
672    
673              val outPgm = PSysIR.PGM {
674                globals = PSV.Map.filter isGlobal (extractVarMap env),
675            emitter = entryBlock,
676                physics = List.nth(!blks, 1),
677                render = render
678              }
679    
680              val optimized = if (Checker.checkIR(outPgm)) then (printErr "Pre-optimization complete."; Optimize.optimizeIR(outPgm)) else outPgm
681    
682            in            in
683              IR.output(TextIO.stdErr, !blks);              (* IR.outputPgm(TextIO.stdErr, outPgm); *)
684              if Checker.checkIR(!blks) then              if Checker.checkIR(optimized) then
685                (* 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)  
686              else              else
687                []               ();
688                optimized
689            end (* compile *)            end (* compile *)
690    
691      end (* Translate *)      end (* Translate *)

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

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