new benchmark -- fluidanimate for Scheduling
[IRC.git] / Robust / src / Benchmarks / Scheduling / PSFluidAnimate / Grid.java
1 public class Grid {
2     flag tosum;
3     flag flushghost;
4     flag tosum2;
5     flag flushghost2;
6     flag tosum3;
7     flag flushghost3;
8     flag tosum4;
9     flag flushghost4;
10     flag rebuild;
11     flag computeDens;
12     flag computeDens2;
13     flag computeForce;
14     flag procCollision;
15     flag finish;
16     
17     public int m_id;
18     public int m_sx;
19     public int m_sy;
20     public int m_sz;
21     public int m_ex;
22     public int m_ey;
23     public int m_ez;
24
25     public Vec3 m_delta;                                // cell dimensions
26     
27     private Vec3 m_externalAcceleration;
28     public Vec3 m_domainMin;
29     public Vec3 m_domainMax;
30     
31     public float m_h;
32     public float m_hSq;
33     public float m_densityCoeff;
34     public float m_pressureCoeff;
35     public float m_viscosityCoeff;
36     public int m_nx;
37     public int m_ny;
38     public int m_nz;
39     
40     public int m_frameNum;
41     
42     public Cell[][][] m_cells;
43     public Cell[][][] m_cells2;
44     public HashMap m_neighCells;    // neighbour cells
45
46     public Grid() {}
47
48     public Grid(int _id, int _sx, int _sy, int _sz, int _ex, int _ey, int _ez, 
49             float _h, float _hSq, Vec3 _delta, 
50             float _densityCoeff, float _pressureCoeff, float _viscosityCoeff, 
51             int _nx, int _ny, int _nz, int _frameNum) {
52         this.m_id = _id;
53         this.m_sx = _sx;
54         this.m_sy = _sy;
55         this.m_sz = _sz;
56         this.m_ex = _ex;
57         this.m_ey = _ey;
58         this.m_ez = _ez;
59         this.m_delta = _delta;
60         this.m_externalAcceleration = new Vec3(0.f, -9.8f, 0.f);
61         this.m_domainMin = new Vec3(-0.065f, -0.08f, -0.065f);
62         this.m_domainMax = new Vec3(0.065f, 0.1f, 0.065f);
63         this.m_h = _h;
64         this.m_hSq = _hSq;
65         this.m_densityCoeff = _densityCoeff;
66         this.m_pressureCoeff = _pressureCoeff;
67         this.m_viscosityCoeff = _viscosityCoeff;
68         this.m_nx = _nx;
69         this.m_ny = _ny;
70         this.m_nz = _nz;
71         this.m_frameNum = _frameNum;
72         this.m_cells = new Cell[_ex-_sx][_ey-_sy][_ez-_sz];
73         this.m_cells2 = new Cell[_ex-_sx][_ey-_sy][_ez-_sz];
74         this.m_neighCells = new HashMap();
75     }
76     
77     public void initCells(Cell[][][] _cells) {
78         for(int ix = 0; ix < this.m_ex - this.m_sx; ix++) {
79             for(int iy = 0; iy < this.m_ey - this.m_sy; iy++) {
80                 for(int iz = 0; iz < this.m_ez - this.m_sz; iz++) {
81                     this.m_cells2[ix][iy][iz] = 
82                         _cells[ix+this.m_sx][iy+this.m_sy][iz+this.m_sz];
83                     this.m_cells[ix][iy][iz] = 
84                         new Cell(this.m_cells2[ix][iy][iz].m_id);
85                 }
86             }
87         }
88     }
89     
90     public void initNeighCells(Cell[][][] _cells, PSFADemo _psfaDemo) {
91         for(int iz = 0; iz < this.m_ez; iz = this.m_ez - 1) {
92             for(int iy = 0; iy < this.m_ey; iy++) {
93                 for(int ix = 0; ix < this.m_ex; ix++) {
94                     for(int dk = -1; dk <= 1; ++dk) {
95                         for(int dj = -1; dj <= 1; ++dj) {
96                             for(int di = -1; di <= 1; ++di) {
97                                 int ci = ix + this.m_sx + di;
98                                 int cj = iy + this.m_sy + dj;
99                                 int ck = iz + this.m_sz + dk;
100
101                                 if(ci < 0) {
102                                     ci = 0; 
103                                 } else if(ci > (this.m_nx-1)) {
104                                     ci = this.m_nx-1;
105                                 }
106                                 if(cj < 0) {
107                                     cj = 0; 
108                                 } else if(cj > (this.m_ny-1)) {
109                                     cj = this.m_ny-1;
110                                 }
111                                 if(ck < 0) {
112                                     ck = 0; 
113                                 } else if(ck > (this.m_nz-1)) {
114                                     ck = this.m_nz-1;
115                                 }
116
117                                 if( ci < this.m_sx || ci >= this.m_ex ||
118                                         cj < this.m_sy || cj >= this.m_ey ||
119                                         ck < this.m_sz || ck >= this.m_ez ) {
120                                     Integer index = new Integer((ck*this.m_ny 
121                                                   + cj)*this.m_nx + ci);
122                                     if(!this.m_neighCells.containsKey(index)) {
123                                         this.m_neighCells.put(index, 
124                                                 new Cell(index.intValue()));
125                                     }
126                                     _psfaDemo.addBorderCells(index.intValue());
127                                 }
128                             }
129                         }
130                     }
131                 }
132             }
133         }
134         
135         for(int iy = 0; iy < this.m_ey; iy = this.m_ey - 1) {
136             for(int iz = 0; iz < this.m_ez; iz++) {
137                 for(int ix = 0; ix < this.m_ex; ix++) {
138                     for(int dk = -1; dk <= 1; ++dk) {
139                         for(int dj = -1; dj <= 1; ++dj) {
140                             for(int di = -1; di <= 1; ++di) {
141                                 int ci = ix + this.m_sx + di;
142                                 int cj = iy + this.m_sy + dj;
143                                 int ck = iz + this.m_sz + dk;
144
145                                 if(ci < 0) {
146                                     ci = 0; 
147                                 } else if(ci > (this.m_nx-1)) {
148                                     ci = this.m_nx-1;
149                                 }
150                                 if(cj < 0) {
151                                     cj = 0; 
152                                 } else if(cj > (this.m_ny-1)) {
153                                     cj = this.m_ny-1;
154                                 }
155                                 if(ck < 0) {
156                                     ck = 0; 
157                                 } else if(ck > (this.m_nz-1)) {
158                                     ck = this.m_nz-1;
159                                 }
160
161                                 if( ci < this.m_sx || ci >= this.m_ex ||
162                                         cj < this.m_sy || cj >= this.m_ey ||
163                                         ck < this.m_sz || ck >= this.m_ez ) {
164                                     Integer index = new Integer((ck*this.m_ny 
165                                                   + cj)*this.m_nx + ci);
166                                     if(!this.m_neighCells.containsKey(index)) {
167                                         this.m_neighCells.put(index, 
168                                                 new Cell(index.intValue()));
169                                     }
170                                     _psfaDemo.addBorderCells(index.intValue());
171                                 }
172                             }
173                         }
174                     }
175                 }
176             }
177         }
178         
179         for(int ix = 0; ix < this.m_ex; ix = this.m_ex - 1) {
180             for(int iy = 0; iy < this.m_ey; iy++) {
181                 for(int iz = 0; iz < this.m_ez; iz++) {
182                     for(int dk = -1; dk <= 1; ++dk) {
183                         for(int dj = -1; dj <= 1; ++dj) {
184                             for(int di = -1; di <= 1; ++di) {
185                                 int ci = ix + this.m_sx + di;
186                                 int cj = iy + this.m_sy + dj;
187                                 int ck = iz + this.m_sz + dk;
188
189                                 if(ci < 0) {
190                                     ci = 0; 
191                                 } else if(ci > (this.m_nx-1)) {
192                                     ci = this.m_nx-1;
193                                 }
194                                 if(cj < 0) {
195                                     cj = 0; 
196                                 } else if(cj > (this.m_ny-1)) {
197                                     cj = this.m_ny-1;
198                                 }
199                                 if(ck < 0) {
200                                     ck = 0; 
201                                 } else if(ck > (this.m_nz-1)) {
202                                     ck = this.m_nz-1;
203                                 }
204
205                                 if( ci < this.m_sx || ci >= this.m_ex ||
206                                         cj < this.m_sy || cj >= this.m_ey ||
207                                         ck < this.m_sz || ck >= this.m_ez ) {
208                                     Integer index = new Integer((ck*this.m_ny 
209                                                   + cj)*this.m_nx + ci);
210                                     if(!this.m_neighCells.containsKey(index)) {
211                                         this.m_neighCells.put(index, 
212                                                 new Cell(index.intValue()));
213                                     }
214                                     _psfaDemo.addBorderCells(index.intValue());
215                                 }
216                             }
217                         }
218                     }
219                 }
220             }
221         }
222     }
223
224     public void ClearParticlesMT() {
225         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
226             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
227                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
228                     this.m_cells[ix][iy][iz].m_numPars = 0;
229                 }
230             }
231         }
232         
233         HashMapIterator it_values = this.m_neighCells.iterator(1);
234         while(it_values.hasNext()) {
235             Cell value = (Cell)it_values.next();
236             value.m_numPars = 0;
237         }
238     }
239
240     public void RebuildGridMT() {
241         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
242             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
243                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
244                     Cell cell2 = this.m_cells2[ix][iy][iz];
245                     int np2 = cell2.m_numPars;
246                     for(int j = 0; j < np2; ++j) {
247                         int ci = (int)((cell2.m_p[j].m_x - this.m_domainMin.m_x) 
248                                 / this.m_delta.m_x);
249                         int cj = (int)((cell2.m_p[j].m_y - this.m_domainMin.m_y) 
250                                 / this.m_delta.m_y);
251                         int ck = (int)((cell2.m_p[j].m_z - this.m_domainMin.m_z) 
252                                 / this.m_delta.m_z);
253
254                         if(ci < 0) {
255                             ci = 0; 
256                         } else if(ci > (this.m_nx-1)) {
257                             ci = this.m_nx-1;
258                         }
259                         if(cj < 0) {
260                             cj = 0; 
261                         } else if(cj > (this.m_ny-1)) {
262                             cj = this.m_ny-1;
263                         }
264                         if(ck < 0) {
265                             ck = 0; 
266                         } else if(ck > (this.m_nz-1)) {
267                             ck = this.m_nz-1;
268                         }
269                         
270                         int np = 0;
271                         Cell cell = null;
272                         if( ci < this.m_sx || ci >= this.m_ex ||
273                                 cj < this.m_sy || cj >= this.m_ey ||
274                                 ck < this.m_sz || ck >= this.m_ez ) {
275                             // move to a neighbour cell
276                             int index = (ck*this.m_ny + cj)*this.m_nx + ci;
277                             // this assumes that particles cannot travel more than 
278                             // one grid cell per time step
279                             cell = (Cell)this.m_neighCells.get(
280                                     new Integer(index));
281                         } else {
282                             // move to a inside cell
283                             cell = this.m_cells[ix][iy][iz];
284                         }
285                         np = cell.m_numPars;
286                         cell.m_p[np].m_x = cell2.m_p[j].m_x;
287                         cell.m_p[np].m_y = cell2.m_p[j].m_y;
288                         cell.m_p[np].m_z = cell2.m_p[j].m_z;
289                         cell.m_hv[np].m_x = cell2.m_hv[j].m_x;
290                         cell.m_hv[np].m_y = cell2.m_hv[j].m_y;
291                         cell.m_hv[np].m_z = cell2.m_hv[j].m_z;
292                         cell.m_v[np].m_x = cell2.m_v[j].m_x;
293                         cell.m_v[np].m_y = cell2.m_v[j].m_y;
294                         cell.m_v[np].m_z = cell2.m_v[j].m_z;
295                         cell.m_numPars++;
296                     }
297                 }
298             }
299         }
300     }
301
302     private int InitNeighCellList(int ci, int cj, int ck, Vec3[] neighCells) {
303         int numNeighCells = 0;
304
305         for(int di = -1; di <= 1; ++di) {
306             for(int dj = -1; dj <= 1; ++dj) {
307                 for(int dk = -1; dk <= 1; ++dk) {
308                     int ii = ci + di;
309                     int jj = cj + dj;
310                     int kk = ck + dk;
311                     if(ii >= 0 && ii < this.m_nx && jj >= 0 && jj < this.m_ny 
312                             && kk >= 0 && kk < this.m_nz) {
313                         if( ii < this.m_sx || ii >= this.m_ex ||
314                                 jj < this.m_sy || jj >= this.m_ey ||
315                                 kk < this.m_sz || kk >= this.m_ez ) {
316                             Integer index = new Integer((kk*this.m_ny + jj)
317                                           *this.m_nx + ii);
318                             if(((Cell)(this.m_neighCells.get(index))).m_numPars 
319                                     != 0) {
320                                 neighCells[numNeighCells] = new Vec3(ii,jj,kk);
321                                 ++numNeighCells;
322                             }
323                         } else {
324                             if(this.m_cells[ii - this.m_sx]
325                                             [jj - this.m_sy]
326                                              [kk - this.m_sz].m_numPars != 0) {
327                                 neighCells[numNeighCells] = new Vec3(ii,jj,kk);
328                                 ++numNeighCells;
329                             }
330                         }
331                     }
332                 }
333             }
334         }
335
336         return numNeighCells;
337     }
338
339     public void InitDensitiesAndForcesMT() {    
340         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
341             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
342                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
343                     Cell cell = this.m_cells[ix][iy][iz];
344                     int np = cell.m_numPars;
345                     for(int j = 0; j < np; ++j) {
346                         cell.m_density[j] = 0.f;
347                         cell.m_a[j].m_x = this.m_externalAcceleration.m_x;
348                         cell.m_a[j].m_y = this.m_externalAcceleration.m_y;
349                         cell.m_a[j].m_z = this.m_externalAcceleration.m_z;
350                     }
351                 }
352             }
353         }
354         
355         HashMapIterator it_values = this.m_neighCells.iterator(1);
356         while(it_values.hasNext()) {
357             Cell value = (Cell)it_values.next();
358             int np = value.m_numPars;
359             for(int j = 0; j < np; ++j) {
360                 value.m_density[j] = 0.f;
361                 value.m_a[j].m_x = this.m_externalAcceleration.m_x;
362                 value.m_a[j].m_y = this.m_externalAcceleration.m_y;
363                 value.m_a[j].m_z = this.m_externalAcceleration.m_z;
364             }
365         }
366     }
367
368     public void ComputeDensitiesMT() {
369         Vec3[] neighCells = new Vec3[27];
370
371         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
372             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
373                 for(int ix = 0; ix < this.m_ex- this.m_sx; ++ix) {
374                     Cell cell = this.m_cells[ix][iy][iz];
375                     int np = cell.m_numPars;
376                     if(np != 0) {
377                         int numNeighCells = InitNeighCellList(ix + this.m_sx, 
378                                 iy + this.m_sy, 
379                                 iz + this.m_sz, 
380                                 neighCells);
381
382                         for(int j = 0; j < np; ++j) {
383                             for(int inc = 0; inc < numNeighCells; ++inc) {
384                                 Vec3 indexNeigh = neighCells[inc];
385                                 Cell neigh = null;
386                                 if( indexNeigh.m_x < this.m_sx || 
387                                         indexNeigh.m_x >= this.m_ex ||
388                                         indexNeigh.m_y < this.m_sy || 
389                                         indexNeigh.m_y >= this.m_ey ||
390                                         indexNeigh.m_z < this.m_sz || 
391                                         indexNeigh.m_z >= this.m_ez ) {
392                                     int index = (int)((indexNeigh.m_z*this.m_ny 
393                                             + indexNeigh.m_y)*this.m_nx 
394                                             + indexNeigh.m_x);
395                                     neigh = (Cell)(this.m_neighCells.get(
396                                             new Integer(index)));
397                                 } else {
398                                     neigh = this.m_cells[(int)indexNeigh.m_x-this.m_sx]
399                                                          [(int)indexNeigh.m_y-this.m_sy]
400                                                           [(int)indexNeigh.m_z-this.m_sz];
401                                 }
402                                 int numNeighPars = neigh.m_numPars;
403                                 for(int iparNeigh = 0; iparNeigh < numNeighPars; 
404                                 ++iparNeigh) {
405                                     if(neigh.m_p[iparNeigh].isLess(cell.m_p[j])) {
406                                         float distSq = (cell.m_p[j].sub1
407                                                 (neigh.m_p[iparNeigh])).
408                                                 GetLengthSq();
409                                         if(distSq < this.m_hSq) {
410                                             float t = this.m_hSq - distSq;
411                                             float tc = t*t*t;
412                                             cell.m_density[j] += tc;
413                                             neigh.m_density[iparNeigh] += tc;
414                                         }
415                                     }
416                                 }
417                             }
418                         }
419                     }
420                 }
421             }
422         }
423     }
424
425     public void ComputeDensities2MT() {
426         float tc = this.m_hSq*this.m_hSq*this.m_hSq;
427         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
428             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
429                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
430                     Cell cell = this.m_cells[ix][iy][iz];
431                     int np = cell.m_numPars;
432                     for(int j = 0; j < np; ++j) {
433                         cell.m_density[j] += tc;
434                         cell.m_density[j] *= this.m_densityCoeff;
435                     }
436                 }
437             }
438         }
439     }
440
441     public void ComputeForcesMT() {
442         float doubleRestDensity = 2000.f;
443         
444         Vec3[] neighCells = new Vec3[27];
445
446         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
447             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
448                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
449                     Cell cell = this.m_cells[ix][iy][iz];
450                     int np = cell.m_numPars;
451                     if(np != 0) {
452                         int numNeighCells = InitNeighCellList(ix + this.m_sx, 
453                                 iy + this.m_sy, 
454                                 iz + this.m_sz, 
455                                 neighCells);
456
457                         for(int j = 0; j < np; ++j) {
458                             for(int inc = 0; inc < numNeighCells; ++inc) {
459                                 Vec3 indexNeigh = neighCells[inc];
460                                 Cell neigh = null;
461                                 if( indexNeigh.m_x < this.m_sx || 
462                                         indexNeigh.m_x >= this.m_ex ||
463                                         indexNeigh.m_y < this.m_sy || 
464                                         indexNeigh.m_y >= this.m_ey ||
465                                         indexNeigh.m_z < this.m_sz || 
466                                         indexNeigh.m_z >= this.m_ez ) {
467                                     int index = (int)((indexNeigh.m_z*this.m_ny 
468                                             + indexNeigh.m_y)*this.m_nx 
469                                             + indexNeigh.m_x);
470                                     neigh = (Cell)(this.m_neighCells.get(
471                                             new Integer(index)));
472                                 } else {
473                                     neigh = this.m_cells[(int)indexNeigh.m_x-this.m_sx]
474                                                          [(int)indexNeigh.m_y-this.m_sy]
475                                                           [(int)indexNeigh.m_z-this.m_sz];
476                                 }
477                                 int numNeighPars = neigh.m_numPars;
478                                 for(int iparNeigh = 0; iparNeigh < numNeighPars; 
479                                 ++iparNeigh) {
480                                     if(neigh.m_p[iparNeigh].isLess(cell.m_p[j])) {
481                                         Vec3 disp = cell.m_p[j].sub1
482                                         (neigh.m_p[iparNeigh]);
483                                         float distSq = disp.GetLengthSq();
484                                         if(distSq < this.m_hSq) {
485                                             float max = 1e-12f;
486                                             if(distSq > 1e-12f) {
487                                                 max = distSq;
488                                             }
489                                             float dist = Math.sqrtf(max);
490                                             float hmr = this.m_h - dist;
491
492                                             Vec3 acc = disp.mul1(
493                                                     this.m_pressureCoeff).mul1(
494                                                             hmr*hmr/dist).mul1(
495                                                                     cell.m_density[j]+
496                                                                     neigh.m_density[iparNeigh] - 
497                                                                     doubleRestDensity);
498                                             acc.add0(neigh.m_v[iparNeigh].sub1(
499                                                     cell.m_v[j]).mul1(
500                                                             this.m_viscosityCoeff * 
501                                                             hmr));
502                                             acc.div0(cell.m_density[j] * 
503                                                     neigh.m_density[iparNeigh]);
504                                             cell.m_a[j].add0(acc);
505                                             neigh.m_a[iparNeigh].sub0(acc);
506                                         }
507                                     }
508                                 }
509                             }
510                         }
511                     }
512                 }
513             }
514         }
515     }
516
517     public void ProcessCollisionsMT() {
518         float timeStep = 0.005f;
519         float parSize = 0.0002f;
520         float epsilon = 1e-10f;
521         float stiffness = 30000.f;
522         float damping = 128.f;
523
524         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
525             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
526                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
527                     Cell cell = this.m_cells[ix][iy][iz];
528                     int np = cell.m_numPars;
529                     for(int j = 0; j < np; ++j) {
530                         Vec3 pos = cell.m_p[j].add1(
531                                 cell.m_hv[j].mul1(timeStep));
532
533                         float diff = parSize - (pos.m_x - this.m_domainMin.m_x);
534                         if(diff > epsilon) {
535                             cell.m_a[j].m_x += stiffness*diff 
536                                              - damping*cell.m_v[j].m_x;
537                         }
538
539                         diff = parSize - (this.m_domainMax.m_x - pos.m_x);
540                         if(diff > epsilon) {
541                             cell.m_a[j].m_x -= stiffness*diff 
542                                              + damping*cell.m_v[j].m_x;
543                         }
544
545                         diff = parSize - (pos.m_y - this.m_domainMin.m_y);
546                         if(diff > epsilon) {
547                             cell.m_a[j].m_y += stiffness*diff 
548                                              - damping*cell.m_v[j].m_y;
549                         }
550
551                         diff = parSize - (this.m_domainMax.m_y - pos.m_y);
552                         if(diff > epsilon) {
553                             cell.m_a[j].m_y -= stiffness*diff 
554                                              + damping*cell.m_v[j].m_y;
555                         }
556
557                         diff = parSize - (pos.m_z - this.m_domainMin.m_z);
558                         if(diff > epsilon) {
559                             cell.m_a[j].m_z += stiffness*diff 
560                                              - damping*cell.m_v[j].m_z;
561                         }
562
563                         diff = parSize - (this.m_domainMax.m_z - pos.m_z);
564                         if(diff > epsilon) {
565                             cell.m_a[j].m_z -= stiffness*diff 
566                                              + damping*cell.m_v[j].m_z;
567                         }
568                     }
569                 }
570             }
571         }
572     }
573
574     public void AdvanceParticlesMT() {
575         float timeStep = 0.005f;
576         
577         for(int iz = 0; iz < this.m_ez - this.m_sz; ++iz) {
578             for(int iy = 0; iy < this.m_ey - this.m_sy; ++iy) {
579                 for(int ix = 0; ix < this.m_ex - this.m_sx; ++ix) {
580                     Cell cell = this.m_cells[ix][iy][iz];
581                     int np = cell.m_numPars;
582                     for(int j = 0; j < np; ++j) {
583                         Vec3 v_half = cell.m_hv[j].add1(cell.m_a[j].mul1(
584                                 timeStep));
585                         cell.m_p[j].add0(v_half.mul1(timeStep));
586                         cell.m_v[j] = cell.m_hv[j].add1(v_half);
587                         cell.m_v[j].mul0(0.5f);
588                         cell.m_hv[j] = v_half;
589                     }
590                 }
591             }
592         }
593     }
594     
595     public boolean isFinish() {
596         this.m_frameNum--;
597         return (this.m_frameNum == 0);
598     }
599 }