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 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.block list      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
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 49  Line 50 
50              k state              k state
51            )            )
52    
53    
54        fun retState s = let
55          val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = s
56         in
57          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
62    
63    (* translation environment *)    (* translation environment *)
64      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)
65    
# Line 64  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 state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color}            val rot = IR.newParam("ps_rot", IR.T_FLOAT)
81            val blk = IR.newBlock ([pos, vel, size, isDead, color], k state)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
82              val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
83              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 77  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 state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color}            val rot = IR.newParam("ps_rot", IR.T_FLOAT)
97            val blk = IR.newBlock ([pos, vel, size, isDead, color] @ args, k state)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
98              val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
99              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}, blk) =      fun goto (PS{pos, vel, size, ttl, color, rot, pos2, dummy}, blk) =
107            IR.mkGOTO(blk, [pos, vel, size, isDead, color])            IR.mkGOTO(blk, [pos, vel, size, ttl, color, rot, pos2, dummy])
108    
109          fun gotoWithArgs(PS{pos, vel, size, isDead, color}, args, blk) =          fun gotoWithArgs(PS{pos, vel, size, ttl, color, rot, pos2, dummy}, args, blk) =
110            IR.mkGOTO(blk, [pos, vel, size, isDead, color] @ 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 100  Line 117 
117    
118    (* prim bound to state variable (S_LOCAL for now) *)    (* prim bound to state variable (S_LOCAL for now) *)
119      fun letSPRIM(x, ty, p, args, body) = let      fun letSPRIM(x, ty, p, args, body) = let
120            val x' = IR.new(x, IR.S_LOCAL(p, args), ty)            val x' = IR.new(x, IR.S_LOCAL(ref (p, args)), ty)
121            in            in
122              IR.mkPRIM(x', p, args, body x')              IR.mkPRIM(x', p, args, body x')
123            end            end
# Line 115  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 129  Line 191 
191                  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 =>
192                  letPRIM (vecVar, IR.T_VEC, IR.ADD_VEC, [pt1ScaleVec, pt2ScaleVec], stmt)))))                  letPRIM (vecVar, IR.T_VEC, IR.ADD_VEC, [pt1ScaleVec, pt2ScaleVec], stmt)))))
193    
194            (* This is a bit more complicated if we're trying to avoid accessing              | P.D_BOX{max, min} =>
195             * the vector variables themselves. Basically the way we can do it is to                  (* Extract the componentwise vector variables *)
196             * decompose the vector connecting min and max into the basis vectors,                  letPRIM("minX", IR.T_FLOAT, IR.EXTRACT_X, [psvToIRVar(env, min)], fn minX =>
197             * scale them independently, and then add them back together.                  letPRIM("maxX", IR.T_FLOAT, IR.EXTRACT_X, [psvToIRVar(env, max)], fn maxX =>
198             *                  letPRIM("minY", IR.T_FLOAT, IR.EXTRACT_Y, [psvToIRVar(env, min)], fn minY =>
199             * !FIXME! Actually do that. Don't have time right now...                  letPRIM("maxY", IR.T_FLOAT, IR.EXTRACT_Y, [psvToIRVar(env, max)], fn maxY =>
200             *)                  letPRIM("minZ", IR.T_FLOAT, IR.EXTRACT_Z, [psvToIRVar(env, min)], fn minZ =>
201              | 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 =>
202    
203                    (* Find the distance in each component *)
204                    letPRIM("distX", IR.T_FLOAT, IR.SUB, [maxX, minX], fn distX =>
205                    letPRIM("distY", IR.T_FLOAT, IR.SUB, [maxY, minY], fn distY =>
206                    letPRIM("distZ", IR.T_FLOAT, IR.SUB, [maxZ, minZ], fn distZ =>
207    
208                    (* Get three random numbers for each of the components *)
209                    letPRIM("randX", IR.T_FLOAT, IR.RAND, [], fn randX =>
210                    letPRIM("randY", IR.T_FLOAT, IR.RAND, [], fn randY =>
211                    letPRIM("randZ", IR.T_FLOAT, IR.RAND, [], fn randZ =>
212    
213                    (* Scale the distances by these random numbers *)
214                    letPRIM("scaledX", IR.T_FLOAT, IR.MULT, [randX, distX], fn scaledX =>
215                    letPRIM("scaledY", IR.T_FLOAT, IR.MULT, [randY, distY], fn scaledY =>
216                    letPRIM("scaledZ", IR.T_FLOAT, IR.MULT, [randZ, distZ], fn scaledZ =>
217    
218                    (* Add them to the minimum vec in order to create a new vec inside
219                     * of the box.
220                     *)
221                    letPRIM("newX", IR.T_FLOAT, IR.ADD, [minX, scaledX], fn newX =>
222                    letPRIM("newY", IR.T_FLOAT, IR.ADD, [minY, scaledY], fn newY =>
223                    letPRIM("newZ", IR.T_FLOAT, IR.ADD, [minZ, scaledZ], fn newZ =>
224    
225                    (* Gen the vector *)
226                    letPRIM(vecVar, IR.T_VEC, IR.GEN_VEC, [newX, newY, newZ], stmt
227    
228                    )))))))))))))))))))
229    
230    
231              | P.D_TRIANGLE{pt1, pt2, pt3} =>              | P.D_TRIANGLE{pt1, pt2, pt3} =>
232                  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 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 264  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 304  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                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 =>
411                letSPRIM ("ps_ttl", IR.T_FLOAT, IR.COPY, [IR.newConst("fbool", IR.C_FLOAT 10000.0)], fn newIsDead =>
412                  k(PS{pos = newPos,
413                       vel = newVel,
414                       size = newSize,
415                       ttl = newIsDead,
416                       color = newCol,
417                       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 336  Line 447 
447                   )                   )
448    
449             | P.D_SPHERE{center, irad, orad} => let             | P.D_SPHERE{center, irad, orad} => let
450                val PS{pos, vel, size, isDead, color} = state                val PS{pos, ...} = state
451                in                in
452                      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 =>
453                  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 459 
459          end          end
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            val PS{pos, vel, size, isDead, color} = state  
463            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit            val PS{ttl, ...} = state
464              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 =>
475         IR.mkIF(t3,         IR.mkIF(t3,
476          (* then *)          (* then *)
477          newParticle (posDomain, velDomain, colDomain, env,          newParticle (posDomain, velDomain, colDomain, env,
478           fn state' => goto (state', blk)),           fn state' => retState state'),
479          (* else *)          (* else *)
480          IR.DISCARD)))))),          IR.DISCARD)))))),
481         (* else *)         (* else *)
482         goto (state, blk))         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
486            val PS{pos, vel, size, isDead, color} = state            val PS{pos, vel, ...} = state
487            val P.PR{ifstmt, ...} = pred            val P.PR{ifstmt, ...} = pred
           val thenBlk = newBlock(env, thenk)  
           val elseBlk = newBlock(env, elsek)  
488           in           in
489            case ifstmt            case ifstmt
490             of P.WITHIN(d) => mkWithinVar("wv", env, pos, d, fn withinVar =>             of P.WITHIN(d) => mkWithinVar("wv", env, pos, d, fn withinVar =>
491              IR.mkIF(withinVar, goto(state, thenBlk), goto(state, elseBlk)))              IR.mkIF(withinVar, thenk(state), elsek(state)))
492              | P.WITHINVEL(d) => mkWithinVar("wv", env, vel, d, fn withinVar =>              | P.WITHINVEL(d) => mkWithinVar("wv", env, vel, d, fn withinVar =>
493              IR.mkIF(withinVar, goto(state, thenBlk), goto(state, elseBlk)))              IR.mkIF(withinVar, thenk(state), elsek(state)))
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} = 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} = 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 415  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}, 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}, 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})))                        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})))                        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 469  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}, 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})                (* | 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
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{emit as P.EMIT{maxNum, vars=emitVars, ...}, act as P.PSAE{action=root_act, vars=actionVars}, ...}) = let      fun compile (P.PG{
603           emit as P.EMIT{vars=emitVars, ...},
604           act as P.PSAE{action=root_act, vars=actionVars},
605           render
606        }) = 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 499  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
                     (* printErr (String.concat["Inserting ", name, " with ID ", Int.toString id, " to IR Var list: ", IR.varToString x']); *)  
624                          PSV.Map.insert (map, x, x')                          PSV.Map.insert (map, x, x')
625                        end                        end
626                  in                  in
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            fun trActs [] state = let  
630                  val PS{pos, vel, size, isDead, color} = state        fun evalActs f [] state = f [] state
631                  in              | evalActs f (psa :: psal) state = (case psa
                   IR.mkRETURN[ pos, vel, size, isDead, color ]  
                 end (* trActs *)  
             | trActs (psa :: psal) state = (case psa  
632                of P.SEQ(acts) => (case acts                of P.SEQ(acts) => (case acts
633                   of [] => raise Fail "Should never reach here."                   of [] => raise Fail "Should never reach here."
634                    | [act] => trAct(act, env, state, trActs psal)                    | [act] => trAct(act, env, state, evalActs f psal)
635                    | act :: rest => trAct(act, env, state, trActs (P.SEQ(rest) :: psal))                    | act :: rest => trAct(act, env, state, evalActs f (P.SEQ(rest) :: psal))
636                    (* end case *))
637                   | P.PRED(pred as P.PR{thenstmt=t, elsestmt=e, ...}) => let
638                       val cblk = newBlock(env, evalActs f psal)
639                       fun trPredActs [] state' = goto(state', cblk)
640                         | trPredActs _ _ = raise Fail "Should never reach here."
641                      in
642                       trPred(pred, env, state, evalActs trPredActs t, evalActs trPredActs e)
643                      end
644                  (* end case *))                  (* end case *))
645                 | P.PRED(pred as P.PR{thenstmt=t, elsestmt=e, ...}) =>  
646                    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 *)
647              fun trActs [] state = let
648                    val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = state
649                    in
650                      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 *)
655                | trActs _ _ = raise Fail "Should never reach here"
656    
657              (* The entry block is the first block of the program, or in other words, the emitter. *)
658              val entryBlock = newBlock (
659                env,
660                fn pstate => trEmitter(
661                  emit,
662                  env,
663                  pstate,
664                  fn state => evalActs trActs root_act state
665                )
666              )
667    
668          (* 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 *))                (* end case *))
674    
675            val entryBlock = newBlock (env, fn pstate => trEmitter(emit, env, pstate, fn state => trActs root_act state))        fun extractVarMap(TE(blks, map)) = map
676    
677              val outPgm = PSysIR.PGM {
678                globals = PSV.Map.filter isGlobal (extractVarMap env),
679            emitter = entryBlock,
680                physics = List.nth(!blks, 1),
681                render = render
682              }
683    
684              val optimized = if (Checker.checkIR(outPgm)) then (printErr "Pre-optimization complete."; Optimize.optimizeIR(outPgm)) else outPgm
685    
686            in            in
687              IR.output(TextIO.stdErr, !blks);              (* IR.outputPgm(TextIO.stdErr, outPgm); *)
688              if Checker.checkIR(!blks) then              if Checker.checkIR(optimized) then
689                (* 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)  
690              else              else
691                []               ();
692                optimized
693            end (* compile *)            end (* compile *)
694    
695      end (* Translate *)      end (* Translate *)

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

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