  'GENERIC PARTICLES
  '=================

  type position {float x,y,z}
  type ang      {float x,y,z}
  type avelocity {float x,y,z}
  type pvelocity {float x,y,z}
  type scale    {float x,y,z}

  typedef void* shape, shader

  type particle
    position  p
    ang       a
    pvelocity pv
    avelocity av
    scale     s
    shape     f
    shader    sh
  end type
  '#recordof particle

  class particles
    particle*q
    int count
    '
    int setup(){}
    int clear(){}
    int constructor(){}
    int destructor(){}
    int act(){}
  end class
  '#recordof particles


  'CONSTRUCTIVE PARTICLES
  '======================

  int pseed=0x12345678

  'BARNSLEY FERN
  '
  ===========
  class plant
  ===========
  '
  string s    'texture buffer
  dword  sz   'x and y tex size
  '
  method particle() as int
  ========================
  static single fxx, fxy, fyx, fyy, dxx, dyy, x, y, v
  static int i, px, py
  '
  'RND 0..100
  pseed=pseed*0x8088405+1 'chaos
  mov eax,101             'range 0..100
  mul pseed               'edx product bits 32..63
  '
  select edx
  case  0 to 10 'omit for dense fronds
    fxx = 0
    fxy = 0
    fyx = 0
    fyy = 0.16
    dxx = 0
    dyy = 0
  case 10 to 86 
    fxx = .85     'bushy
    fxy = 0.04    'curve up
    fyx = -.04    'dip density
    fyy = 0.85    'dispersal and internode
    dxx = 0.0     '
    dyy = 1.60    'height / density
  case 87 to 93 'omit for right side only 
    fxx = 0.2
    fxy = -.26
    fyx = 0.23
    fyy = 0.22
    dxx = 0
    dyy = 0.16
  case 94 to 100 'omit for left side only
    fxx = -.15  'x factor for x
    fxy = 0.28  'y factor for x
    fyx = 0.26  'x factor for y
    fyy = 0.24  'y factor for y
    dxx = 0     '  displacement for x
    dyy = 0.44  '  displacement for y
  end select

  v=x 'preserve original x
  x = fxx*v + fxy*y + dxx
  y = fyx*v + fyy*y + dyy
  px=limit(0,int(x*24+sz*.5),sz-1)
  py=limit(0,int(y*24+00),sz-1)
  int i 
  #noprec i=py*sz+px+1
  return i
  end method

  method new(sys m,n) as sys
  ==========================
  sz=m
  s=nuls m*m*4
  dword*p
  @p=strptr s
  int i,j
  for i=1 to n 'typically 64000
    j=Particle
    p(j)=0xffffffff
  next
  return @p
  end method

  method free()
  =============
  del s
  end method
  '
  end class



  'MOVING PARTICLES
  '================


  type tParticle
  ===============
  float x,y,z
  float xsize,ysize,speed,angle
  float r,g,b
  sys   tex
  end type

  class plasma
  ===========
  tparticle p[250]
  sys   i,e
  float r,g,b
  ===========
  '
  method Draw()
  tparticle q at (@p[i])
  glPushMatrix   
  glTranslatef q.x, q.y, q.z
  glColor4f    r,g,b,.7 '-q.y*.7 ' The particle will fade out
  q.angle+=Rnd()
  glscalef 1, q.angle*.0004+1, 1 'itr
  glRotatef q.angle, 0, 0, 1
  QuadTex q.xsize,q.ysize,0
  glPopMatrix   
  end method

  method Renew()
  tparticle q at (@p[i])
  q.x     = Rnd()*.15
  q.y     = 0
  q.z     =  -4.0 'z layers
  q.xsize = .25+aRnd()*0.5
  q.ysize = .25+aRnd()*0.5
  q.Speed = 1.*(1.+aRnd)
  q.Angle = aRnd()*360
  end method

  method Render(sys en)
  if r+g+b=0
    r=.5 : g=.5 : b=.6
  end if
  e=en
  tparticle *q : @q=@p
  for i = 1 to e
  if q.z > 3.0 or q.speed=0
    Renew
  else    
    'q.xsize +=0.1*.0167
    'q.ysize +=0.1*.0167
    q.x     += 0.1*.00167       '
    q.y     += 0.1*q.Speed *.00167 'assume framerate 60
    q.z     += 6.0*.00167 '
    Draw
  end if
  @q+=sizeof tparticle
  next  
  end method
  '
  end class 'plasma


  class smoke
  ===========
  tparticle p[50]
  sys   i,e
  float r,g,b
  ===========
  '
  method Draw()
  tparticle q at (@p[i])
  glPushMatrix   
  glTranslatef q.x, q.y, q.z
  glColor4f    r,g,b,.7-q.y*.7 ' The particle will fade out
  q.angle+=Rnd()
  glscalef 1, q.angle*.0004+1, 1 'itr
  glRotatef q.angle, 0, 0, 1
  QuadTex q.xsize,q.ysize,0
  glPopMatrix   
  end method

  method Renew()
  tparticle q at (@p[i])
  q.x     = Rnd()*.15
  q.y     = 0
  q.z     = -e*.01 / i 'z layers
  q.xsize = .025+aRnd()*0.05
  q.ysize = .025+aRnd()*0.05
  q.Speed = .5+aRnd()
  q.Angle = aRnd()*360
  end method

  method Render(sys en)
  if r+g+b=0
    r=.5 : g=.5 : b=.6
  end if
  e=en
  tparticle *q : @q=@p
  for i = 1 to e
  if q.y > 1 or q.speed=0
    Renew
  else    
    q.xsize += 0.1*.0167
    q.ysize += 0.1*.0167
    q.x     += 0.1*.0167
    q.y     += q.Speed *.00167 'assume framerate 60
    glColor4f r,g,b,.7-q.y*.7
    Draw
  end if
  @q+=sizeof tparticle
  Next  
  end method
  '
  end class

  class cloud
  ===============
  tparticle p[50]
  int basetex
  ===============
  '
  method Render(sys en)
  sys       i,e
  tparticle q at (@p)
  static float fr=2*0.0167 '1/60
  e=en
  for i = 1 to e
  if q.x > 1 or q.speed=0
    'renew
    static int n
    n=1-n 'toggle 0 and 1
    q.x     = Rnd()*.5
    q.y     = 0
    q.z     = -e*.1 / i 'z layers
    q.xsize = .01+aRnd()*0.02
    q.ysize = .01+aRnd()*0.01
    q.Speed = .05+aRnd()*.02
    q.Angle = aRnd()*360
    q.tex   = texn(n+basetex)
  else    
    q.xsize += .12*fr
    q.ysize += .10*fr
    q.x     += .9*q.Speed*fr
    q.y     += .3*q.Speed*fr
    glBindTexture GL_TEXTURE_2D,q.tex
    if q.x>.5
      glColor4f .99,.99,.99,.7-q.x *.7 'fades with xdistance
    else
      glColor4f .99,.99,.99,q.x*.7 'increases with xdistance
    end if
    'Draw
    glPushMatrix   
    glTranslatef q.x, q.y, q.z
    q.angle+=.03
    glScalef q.xsize,q.ysize,1.0
    glRotatef q.angle, 0, 0, 1
    QuadTex 1,1,0
    glPopMatrix   
  end if
  @q+=sizeof tparticle
  next  
  end method
  '
  end class


