Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] Diff of /trunk/sml3d/src/particles/compiler/translate.sml
ViewVC logotype

Diff of /trunk/sml3d/src/particles/compiler/translate.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 901, Fri May 28 19:15:30 2010 UTC revision 1060, Fri Jan 21 23:24:43 2011 UTC
# Line 8  Line 8 
8    
9  structure Translate : sig  structure Translate : sig
10    
11      val compile : Particles.particle_group -> PSysIR.program      val compile : Particles.program -> PSysIR.program
12    
13    end = struct    end = struct
14    
# Line 24  Line 24 
24          pos : IR.var,           (* vec3 *)          pos : IR.var,           (* vec3 *)
25          vel : IR.var,           (* vec3 *)          vel : IR.var,           (* vec3 *)
26          size : IR.var,          (* float *)          size : IR.var,          (* float *)
27          isDead : IR.var,        (* bool *)          ttl : IR.var,           (* float *)
28          color : IR.var,         (* vec3 (NOTE: should be vector4) *)          color : IR.var,         (* vec3 (NOTE: should be vector4) *)
29            rot : IR.var,           (* float *)
30          pos2 : IR.var,          (* vec3 *)          pos2 : IR.var,          (* vec3 *)
31          dummy : IR.var          dummy : IR.var
32        }        }
33    
34    (* special PSV global variables *)    (* special PSV global variables *)
     val timeStep = PSV.new("g_timeStep", PSV.T_FLOAT)   (* physics timestep *)  
     val numDead = PSV.new("g_numDead", PSV.T_INT)       (* # of dead particles *)  
35      val epsilon = PSV.constf(0.00001)      val epsilon = PSV.constf(0.00001)
36    
37    (* constants *)    (* constants *)
# Line 53  Line 52 
52    
53    
54      fun retState s = let      fun retState s = let
55        val PS{pos, vel, size, isDead, color, pos2, dummy} = s        val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = s
56       in       in
57        IR.mkRETURN [pos, vel, size, isDead, color, pos2, dummy]        IR.mkRETURN (
58            [pos, vel, size, ttl, color, rot, pos2, dummy],
59            [IR.POS, IR.VEL, IR.SZ, IR.TTL, IR.COLOR, IR.ROT, IR.POS2, IR.DUMMY]
60          )
61       end       end
62    
63    (* translation environment *)    (* translation environment *)
# Line 73  Line 75 
75            val pos = IR.newParam ("ps_pos", IR.T_VEC)            val pos = IR.newParam ("ps_pos", IR.T_VEC)
76            val vel = IR.newParam ("ps_vel", IR.T_VEC)            val vel = IR.newParam ("ps_vel", IR.T_VEC)
77            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
78            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val ttl = IR.newParam ("ps_ttl", IR.T_FLOAT)
79            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
80              val rot = IR.newParam("ps_rot", IR.T_FLOAT)
81            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
82            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
83            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, pos2=pos2, dummy=dummy}            val state = PS{pos=pos, vel=vel, size=size, ttl=ttl, color=color, rot=rot, pos2=pos2, dummy=dummy}
84            val blk = IR.newBlock ([pos, vel, size, isDead, color, pos2, dummy], k state)            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 88  Line 91 
91            val pos = IR.newParam ("ps_pos", IR.T_VEC)            val pos = IR.newParam ("ps_pos", IR.T_VEC)
92            val vel = IR.newParam ("ps_vel", IR.T_VEC)            val vel = IR.newParam ("ps_vel", IR.T_VEC)
93            val size = IR.newParam ("ps_size", IR.T_FLOAT)            val size = IR.newParam ("ps_size", IR.T_FLOAT)
94            val isDead = IR.newParam ("ps_isDead", IR.T_BOOL)            val ttl = IR.newParam ("ps_ttl", IR.T_FLOAT)
95            val color = IR.newParam ("ps_color", IR.T_VEC)            val color = IR.newParam ("ps_color", IR.T_VEC)
96              val rot = IR.newParam("ps_rot", IR.T_FLOAT)
97            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)            val dummy = IR.newParam ("ps_dummy", IR.T_FLOAT)
98            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)            val pos2 = IR.newParam ("ps_pos2", IR.T_VEC)
99            val state = PS{pos=pos, vel=vel, size=size, isDead=isDead, color=color, pos2=pos2, dummy = dummy}            val state = PS{pos=pos, vel=vel, size=size, ttl=ttl, color=color, rot=rot, pos2=pos2, dummy=dummy}
100            val blk = IR.newBlock ([pos, vel, size, isDead, color, pos2, dummy] @ args, k state)            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, pos2, dummy}, blk) =      fun goto (PS{pos, vel, size, ttl, color, rot, pos2, dummy}, blk) =
107            IR.mkGOTO(blk, [pos, vel, size, isDead, color, pos2, dummy])            IR.mkGOTO(blk, [pos, vel, size, ttl, color, rot, pos2, dummy])
108    
109          fun gotoWithArgs(PS{pos, vel, size, isDead, color, pos2, dummy}, args, blk) =          fun gotoWithArgs(PS{pos, vel, size, ttl, color, rot, pos2, dummy}, args, blk) =
110            IR.mkGOTO(blk, [pos, vel, size, isDead, color, pos2, dummy] @ args)            IR.mkGOTO(blk, [pos, vel, size, ttl, color, rot, pos2, dummy] @ args)
111    
112      fun letPRIM (x, ty, p, args, body) = let      fun letPRIM (x, ty, p, args, body) = let
113            val x' = IR.newLocal(x, ty, (p, args))            val x' = IR.newLocal(x, ty, (p, args))
# Line 128  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 294  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 305  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 323  Line 383 
383                    letPRIM("inOrad", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), posToCLen], fn inOrad =>                    letPRIM("inOrad", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), posToCLen], fn inOrad =>
384                    letPRIM("inIrad", IR.T_BOOL, IR.GT, [posToCLen, psvToIRVar(env, irad)], fn inIrad =>                    letPRIM("inIrad", IR.T_BOOL, IR.GT, [posToCLen, psvToIRVar(env, irad)], fn inIrad =>
385                    letPRIM(boolVar, IR.T_BOOL, IR.AND, [inIrad, inOrad], stmt)))))                    letPRIM(boolVar, IR.T_BOOL, IR.AND, [inIrad, inOrad], stmt)))))
386    
387                      | P.D_CYLINDER {pt1, pt2, irad, orad} =>
388    
389                      (* !FIXME! Right now, we see whether or not the point is within the two planes defined
390                       * by the endpoints of the cylinder, and then testing to see whether or not the smallest
391                       * distance to the line segment falls within the radii. It might be faster to find the
392                       * closest point to the line defined by the endpoints and then see whether or not the point
393                       * is within the segment.
394                       *)
395    
396                      (* Is it in one plane *)
397                      letPRIM("plane1Norm", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt2), psvToIRVar(env, pt1)], fn plane1Norm =>
398                      letPRIM("posToPt1", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, pt1)], fn posToPt1 =>
399                      letPRIM("dot1", IR.T_FLOAT, IR.DOT, [posToPt1, plane1Norm], fn dot1Prod =>
400                      letPRIM("inPlane1", IR.T_BOOL, IR.GT, [dot1Prod, IR.newConst("zero", IR.C_FLOAT 0.0)], fn inPlane1=>
401    
402                      (* Is it in another plane *)
403                      letPRIM("plane2Norm", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt1), psvToIRVar(env, pt2)], fn plane2Norm =>
404                      letPRIM("posToPt2", IR.T_VEC, IR.SUB_VEC, [pos, psvToIRVar(env, pt2)], fn posToPt2 =>
405                      letPRIM("dot2", IR.T_FLOAT, IR.DOT, [posToPt2, plane2Norm], fn dot2Prod =>
406                      letPRIM("inPlane2", IR.T_BOOL, IR.GT, [dot2Prod, IR.newConst("zero", IR.C_FLOAT 0.0)], fn inPlane2=>
407    
408                      (* Is it in both planes? *)
409                      letPRIM("inPlanes", IR.T_BOOL, IR.AND, [inPlane1, inPlane2], fn inPlanes =>
410    
411                      (* Find distance from segment *)
412                      letPRIM("a", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt2), psvToIRVar(env, pt1)], fn a =>
413                      letPRIM("b", IR.T_VEC, IR.SUB_VEC, [psvToIRVar(env, pt1), pos], fn b =>
414                      letPRIM("alen", IR.T_FLOAT, IR.LEN, [a], fn alen =>
415                      letPRIM("axb", IR.T_VEC, IR.CROSS, [a, b], fn axb =>
416                      letPRIM("axblen", IR.T_FLOAT, IR.LEN, [axb], fn axblen =>
417                      letPRIM("dist", IR.T_FLOAT, IR.DIV, [axblen, alen], fn dist =>
418    
419                      (* Is distance in both radii? *)
420                      letPRIM("inOradGt", IR.T_BOOL, IR.GT, [psvToIRVar(env, orad), dist], fn inOradGt =>
421                      letPRIM("inOradEq", IR.T_BOOL, IR.EQUALS, [psvToIRVar(env, orad), dist], fn inOradEq =>
422                      letPRIM("inOrad", IR.T_BOOL, IR.OR, [inOradGt, inOradEq], fn inOrad =>
423    
424                      letPRIM("inIradGt", IR.T_BOOL, IR.GT, [dist, psvToIRVar(env, irad)], fn inIradGt =>
425                      letPRIM("inIradEq", IR.T_BOOL, IR.EQUALS, [dist, psvToIRVar(env, irad)], fn inIradEq =>
426                      letPRIM("inIrad", IR.T_BOOL, IR.OR, [inIradGt, inIradEq], fn inIrad =>
427    
428                      letPRIM("inBothRad", IR.T_BOOL, IR.AND, [inIrad, inOrad], fn inBothRad =>
429    
430                      (* It's in the cylinder (tube) if it's within both radii and in both planes... *)
431                      letPRIM(boolVar, IR.T_BOOL, IR.AND, [inPlanes, inBothRad], stmt)
432                      ))))))))))))))))))))))
433  (*  (*
434                | P.D_TRIANGLE {pt1: vec3f var, pt2: vec3f var, pt3: vec3f var}                | P.D_TRIANGLE {pt1: vec3f var, pt2: vec3f var, pt3: vec3f var}
435                | P.D_PLANE {pt: vec3f var, normal: vec3f var}                | P.D_PLANE {pt: vec3f var, normal: vec3f var}
436                | P.D_RECT {pt: vec3f var, htvec: vec3f var, wdvec: vec3f var}                | P.D_RECT {pt: vec3f var, htvec: vec3f var, wdvec: vec3f var}
437                | P.D_BOX {min: vec3f var, max: vec3f var}                | P.D_BOX {min: vec3f var, max: vec3f var}
438                | P.D_SPHERE {center: vec3f var, irad: vec3f var, orad: vec3f var}                | P.D_SPHERE {center: vec3f var, irad: vec3f var, orad: vec3f var}
               | P.D_CYLINDER {pt1: vec3f var, pt2: vec3f var, irad: float var, orad: float var}  
439                | P.D_CONE {pt1: vec3f var, pt2: vec3f var, irad: float var, orad: float var}                | P.D_CONE {pt1: vec3f var, pt2: vec3f var, irad: float var, orad: float var}
440                | P.D_BLOB {center: vec3f var, stddev: float var}                | P.D_BLOB {center: vec3f var, stddev: float var}
441                | P.D_DISC {pt: vec3f var, normal: vec3f var, irad: float var, orad: float var}                | P.D_DISC {pt: vec3f var, normal: vec3f var, irad: float var, orad: float var}
# Line 345  Line 451 
451              genVecVar("ps_pos", env, posDomain, fn newPos =>              genVecVar("ps_pos", env, posDomain, fn newPos =>
452              genVecVar("ps_vel", env, velDomain, fn newVel =>              genVecVar("ps_vel", env, velDomain, fn newVel =>
453              genVecVar("ps_col", env, colDomain, fn newCol =>              genVecVar("ps_col", env, colDomain, fn newCol =>
454              letSPRIM ("ps_size", IR.T_FLOAT, IR.RAND, [], fn newSize =>              letPRIM ("randSize", IR.T_FLOAT, IR.RAND, [], fn randSize =>
455              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 =>
456                letSPRIM("ps_size", IR.T_FLOAT, IR.ADD, [halfSize, IR.newConst("scalar", IR.C_FLOAT 0.5)], fn newSize =>
457                letSPRIM ("ps_ttl", IR.T_FLOAT, IR.COPY, [IR.newConst("fbool", IR.C_FLOAT 10000.0)], fn newIsDead =>
458                k(PS{pos = newPos,                k(PS{pos = newPos,
459                     vel = newVel,                     vel = newVel,
460                     size = newSize,                     size = newSize,
461                     isDead = newIsDead,                     ttl = newIsDead,
462                     color = newCol,                     color = newCol,
463                     pos2 = IR.newConst("p2", IR.C_VEC {x=0.0, y=0.0, z=0.0}),                     rot = IR.newConst("ps_rot", IR.C_FLOAT 0.0),
464                     dummy = IR.newConst("dmy", IR.C_FLOAT 0.01)})                     pos2 = IR.newConst("ps_pos2", IR.C_VEC {x=0.0, y=0.0, z=0.0}),
465              )))))                     dummy = IR.newConst("ps_dummy", IR.C_FLOAT 0.01)})
466                )))))))
467    
468      (* 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
469       * domain. Note, that the particle doesn't necessarily need to be on the       * domain. Note, that the particle doesn't necessarily need to be on the
# Line 397  Line 506 
506    
507          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let          fun trEmitter(emit, env, state, k : particle_state -> IR.stmt) = let
508    
509            val PS{isDead, ...} = state            val PS{ttl, ...} = state
510            val P.EMIT{maxNum, posDomain, velDomain, colDomain, ...} = emit            val P.EMIT{range, dist, posDomain, velDomain, colDomain, ...} = emit
511            val blk = newBlock (env, k)            val blk = newBlock (env, k)
512           in           in
513              letPRIM("isDead", IR.T_BOOL, IR.GT, [IR.newConst("small", IR.C_FLOAT 0.1), ttl], fn isDead =>
514        IR.mkIF(isDead,        IR.mkIF(isDead,
515         (* then *)         (* then *)
516         letPRIM("t1", IR.T_FLOAT, IR.ITOF, [psvToIRVar (env, maxNum)], fn t1 =>         genFloatVar("t1", env, range, dist, fn t1 =>
517         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 =>
518         letPRIM("prob", IR.T_FLOAT, IR.DIV, [t1, t2], fn prob =>         letPRIM("prob", IR.T_FLOAT, IR.DIV, [t1, t2], fn prob =>
519         letPRIM("r", IR.T_FLOAT, IR.RAND, [], fn r =>         letPRIM("r", IR.T_FLOAT, IR.RAND, [], fn r =>
520         letPRIM("t3", IR.T_BOOL, IR.GT, [prob, r], fn t3 =>         letPRIM("t3", IR.T_BOOL, IR.GT, [prob, r], fn t3 =>
# Line 415  Line 525 
525          (* else *)          (* else *)
526          IR.DISCARD)))))),          IR.DISCARD)))))),
527         (* else *)         (* else *)
528         retState state)         retState state))
529       end       end
530    
531          fun trPred(pred, env, state, thenk : particle_state -> IR.stmt, elsek : particle_state -> IR.stmt) = let          fun trPred(pred, env, state, thenk : particle_state -> IR.stmt, elsek : particle_state -> IR.stmt) = let
# Line 430  Line 540 
540           end           end
541    
542      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let      fun trAct (action, env, state, k : particle_state -> IR.stmt) = let
543            val PS{pos, vel, size, isDead, color, pos2, dummy} = state            val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = state
544            in            in
545              case action              case action
546               of P.BOUNCE{friction, resilience, cutoff, d} => let               of P.BOUNCE{friction, resilience, cutoff, d} => let
547                    val blk = newBlock (env, k)                    val blk = newBlock (env, k)
548                    val negOne = IR.newConst("negOne", IR.C_FLOAT ~1.0)                    val negOne = IR.newConst("negOne", IR.C_FLOAT ~1.0)
549                    in                    in
550                      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 =>
551                      letPRIM("np", IR.T_VEC, IR.ADD_VEC, [pos, velScale], fn nextPos =>                      letPRIM("np", IR.T_VEC, IR.ADD_VEC, [pos, velScale], fn nextPos =>
552                      mkWithinVar("wnp", env, pos, d, fn withinNextPos =>                      mkWithinVar("wcp", env, pos, d, fn withinCurPos =>
553                      IR.mkIF(withinNextPos,                      mkWithinVar("wnp", env, nextPos, d, fn withinNextPos =>
554                        letPRIM("nwcp", IR.T_BOOL, IR.NOT, [withinCurPos], fn notWithinCurPos =>
555                        letPRIM("sb", IR.T_BOOL, IR.AND, [notWithinCurPos, withinNextPos], fn shouldBounce =>
556                        IR.mkIF(shouldBounce,
557                        (*then*)                        (*then*)
558                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let                          normAtPoint("n", d, env, state, fn normAtD => fn state' => let
559                 val PS{pos=nextPos, vel=nextVel, size=nextSize, isDead=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy} = state'                 val PS{pos=nextPos, vel=nextVel, size=nextSize, ttl=nextIsDead, color=nextColor, rot=nextRot, pos2=nextPos2, dummy=nextDummy} = state'
560                            in                            in
561                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>                             letPRIM("negVel", IR.T_VEC, IR.SCALE, [negOne, nextVel], fn negVel =>
562                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>                             letPRIM("dnv", IR.T_FLOAT, IR.DOT, [negVel, normAtD], fn dotNegVel =>
# Line 462  Line 575 
575                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>                               letPRIM("f", IR.T_FLOAT, IR.MULT, [negOne, frictInv], fn modFrict =>
576                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [modFrict, tang], fn frictTang =>
577                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>                               letPRIM("newVel", IR.T_VEC, IR.ADD_VEC, [frictTang, resNorm], fn newVel =>
578                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, ttl=nextIsDead, color=nextColor, rot=nextRot, pos2=nextPos2, dummy=nextDummy}, blk)
579                              )))),                              )))),
580                               (*else*)                               (*else*)
581                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>                               letPRIM("fTang", IR.T_VEC, IR.SCALE, [negOne, tang], fn frictTang =>
582                               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 =>
583                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, isDead=nextIsDead, color=nextColor, pos2=nextPos2, dummy=nextDummy}, blk)                                goto(PS{pos=nextPos, vel=newVel, size=nextSize, ttl=nextIsDead, color=nextColor, rot=nextRot, pos2=nextPos2, dummy=nextDummy}, blk)
584                               ))                               ))
585                           )))))))))                           )))))))))
586                           end                           end
587                        ),                        ),
588                        (*else*)                        (*else*)
589                        goto(state, blk)))))                        goto(state, blk))))))))
590                    end                    end
591    
592                | P.GRAVITY(dir) =>                | P.ACCEL dir =>
593                      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 =>
594                      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 =>
595                        k(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, pos2=pos2, dummy=dummy})))                        k(PS{pos = pos, vel = newVel, size = size, ttl = ttl, color = color, rot=rot, pos2=pos2, dummy=dummy})))
596    
597                | P.MOVE =>                | P.MOVE =>
598                  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 =>
599                      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 =>
600                        k(PS{pos = newPos, vel = vel, size = size, isDead = isDead, color = color, pos2=pos2, dummy=dummy})))                        k(PS{pos = newPos, vel = vel, size = size, ttl = ttl, color = color, rot=rot, pos2=pos2, dummy=dummy})))
601                (*                (*
602                | P.SINK({d, kill_inside}) =>                | P.SINK({d, kill_inside}) =>
603                      mkWithinVar("isWithin", env, state, d, fn withinVal =>                      mkWithinVar("isWithin", env, state, d, fn withinVal =>
604                      mkXOR ("shouldNotKill", withinVal, psvToIRVar(env, kill_inside),                      mkXOR ("shouldNotKill", withinVal, psvToIRVar(env, kill_inside),
605                        fn shouldNotKill =>                        fn shouldNotKill =>
606                      letPRIM("shouldKill", IR.T_BOOL, IR.NOT, [shouldNotKill], fn shouldKill =>                      letPRIM("shouldKill", IR.T_BOOL, IR.NOT, [shouldNotKill], fn shouldKill =>
607                      letPRIM("isReallyDead", IR.T_BOOL, IR.OR, [shouldKill, isDead], fn isReallyDead =>                      letPRIM("isReallyDead", IR.T_BOOL, IR.OR, [shouldKill, ttl], fn isReallyDead =>
608                      k(PS{pos = pos, vel = vel, size = size, isDead = isReallyDead, color = color})                      k(PS{pos = pos, vel = vel, size = size, ttl = isReallyDead, color = color})
609                          ))))                          ))))
610                *)                *)
611    
# Line 516  Line 629 
629                    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 =>
630                    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 =>
631                    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 =>
632                    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 =>
633                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>                    letPRIM("accVec", IR.T_VEC, IR.SUB_VEC, [closestP, pos], fn accVec =>
634                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>                    letPRIM("acc", IR.T_VEC, IR.SCALE, [totMag, accVec], fn acc =>
635                    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 =>
636                    goto(PS{pos = pos, vel = newVel, size = size, isDead = isDead, color = color, pos2=pos2, dummy=dummy}, blk)                    goto(PS{pos = pos, vel = newVel, size = size, ttl = ttl, color = color, rot=rot, pos2=pos2, dummy=dummy}, blk)
637                    )))))))                    )))))))
638                  )))))))))))                  )))))))))))
639                  end                  end
640    
641                (* just kill it. *)                (* just kill it. *)
642                (* | P.DIE => k(PS{pos = pos, vel = vel, size = size, isDead = IR.newConst("falseVar", IR.C_BOOL true), color = color, dummy=dummy}) *)                (* | P.DIE => k(PS{pos = pos, vel = vel, size = size, ttl = IR.newConst("falseVar", IR.C_BOOL true), color = color, dummy=dummy}) *)
643                | P.DIE => IR.DISCARD                | P.DIE => IR.DISCARD
644                | _ => raise Fail("Action not implemented...")                | _ => raise Fail("Action not implemented...")
645              (* end case *)              (* end case *)
646            end            end
647    
648      fun compile (P.PG{      fun compile (P.PG{
649         emit as P.EMIT{maxNum, vars=emitVars, ...},         emit as P.EMIT{vars=emitVars, ...},
650         act as P.PSAE{action=root_act, vars=actionVars},         act as P.PSAE{action=root_act, vars=actionVars},
651         render         render
652      }) = let      }) = let
653            val blks = ref[]            val blks = ref[]
654            val env = let            val env = let
655                (* add special globals to free vars *)                (* add special globals to free vars *)
656                  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]))
657                  fun ins (x as PSV.V{name, ty, binding, id, ...}, map) = let                  fun ins (x as PSV.V{name, ty, binding, id, ...}, map) = let
658                        val x' = (case (ty, !binding)                        val x' = (case (ty, !binding)
659                               of (PSV.T_BOOL,  PSV.UNDEF) => IR.newGlobal(x, IR.T_BOOL)                               of (PSV.T_BOOL,  PSV.UNDEF) => IR.newGlobal(x, IR.T_BOOL)
# Line 551  Line 664 
664                                | (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))
665                                | (PSV.T_VEC3F, PSV.UNDEF) => IR.newGlobal(x, IR.T_VEC)                                | (PSV.T_VEC3F, PSV.UNDEF) => IR.newGlobal(x, IR.T_VEC)
666                                | (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))
667                                | _ => 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.")
668                              (* end case *))                              (* end case *))
669                        in                        in
670                          PSV.Map.insert (map, x, x')                          PSV.Map.insert (map, x, x')
# Line 560  Line 673 
673                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)                    TE(blks, PSV.Set.foldl ins PSV.Map.empty vars)
674                  end                  end
675    
   
676            fun evalActs f [] state = f [] state            fun evalActs f [] state = f [] state
677              | evalActs f (psa :: psal) state = (case psa              | evalActs f (psa :: psal) state = (case psa
678                of P.SEQ(acts) => (case acts                of P.SEQ(acts) => (case acts
# Line 579  Line 691 
691    
692            (* At the highest level, we want to return when we reach the end of the action list *)            (* At the highest level, we want to return when we reach the end of the action list *)
693            fun trActs [] state = let            fun trActs [] state = let
694                  val PS{pos, vel, size, isDead, color, pos2, dummy} = state                  val PS{pos, vel, size, ttl, color, rot, pos2, dummy} = state
695                  in                  in
696                    IR.mkRETURN[ pos, vel, size, isDead, color, pos2, dummy ]                    IR.mkRETURN (
697                        [ pos, vel, size, ttl, color, rot, pos2, dummy ],
698                        [IR.POS, IR.VEL, IR.SZ, IR.TTL, IR.COLOR, IR.ROT, IR.POS2, IR.DUMMY]
699                      )
700                  end (* trActs *)                  end (* trActs *)
701              | trActs _ _ = raise Fail "Should never reach here"              | trActs _ _ = raise Fail "Should never reach here"
702    
# Line 597  Line 712 
712            )            )
713    
714            (* The entry block is the emitter, and the rest of the blocks define the physics processing. *)            (* The entry block is the emitter, and the rest of the blocks define the physics processing. *)
715    
716          fun isGlobal(IR.V{scope, ...}) = (case scope
717            of IR.S_GLOBAL(v) => true
718             | _ => false
719            (* end case *))
720    
721          fun extractVarMap(TE(blks, map)) = map
722    
723            val outPgm = PSysIR.PGM {            val outPgm = PSysIR.PGM {
724                globals = PSV.Map.filter isGlobal (extractVarMap env),
725              emitter = entryBlock,              emitter = entryBlock,
726              physics = List.drop(!blks, 1),              physics = List.nth(!blks, 1),
727              render = render              render = render
728            }            }
729    
730            val optimized = if (Checker.checkIR(outPgm)) then Optimize.optimizeIR(outPgm) else outPgm            val optimized = if (Checker.checkIR(outPgm)) then (printErr "Pre-optimization complete."; Optimize.optimizeIR(outPgm)) else outPgm
731    
732            in            in
733              IR.outputPgm(TextIO.stdErr, outPgm);              (* IR.outputPgm(TextIO.stdErr, outPgm); *)
734              if Checker.checkIR(optimized) then              if Checker.checkIR(optimized) then
735               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)               printErr "Compilation succeeded." (* Note: it only succeeds if we can optimize, too *)
736              else              else
737               ();               ();
             IR.outputPgm(TextIO.stdErr, optimized);  
738              optimized              optimized
739            end (* compile *)            end (* compile *)
740    

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

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