 transitionFunc = parseTransitionFunction "B 3 S 2 3", tessellation.group.n, tessellation.group.m
 dragHandler = null
 
-tfm = M.eye()
 cells = new NodeHashMap
 cells.put null, 1
 

  mouseDown: ->
    

jumpLimit = 1.5
  
modifyView = (m) ->
  tfm = M.mul m, tfm
  checkViewMatrix()
  originDistance = viewDistanceToOrigin()
  if originDistance > jumpLimit
    rebaseView()

  observer.renderGrid tfm

viewDistanceToOrigin = ->
  #viewCenter = M.mulv tfm, [0.0,0.0,1.0]
  #Math.acosh(viewCenter[2])
  Math.acosh tfm[8]

#build new view around the cell which is currently at the center
rebaseView = ->
  centerCoord = M.mulv (M.inv tfm), [0.0, 0.0, 1.0]
  pathToCenterCell = xytFromCell centerCoord
  #console.log "Jump by #{showNode pathToCenterCell}"
  m = nodeMatrixRepr pathToCenterCell, tessellation.group

  #modifyView won't work, since it multiplies in different order.
  tfm = M.mul tfm, m
  checkViewMatrix()

  #move observation point
  observer.translateBy node2array pathToCenterCell

updatePopulation = ->
  E('population').innerHTML = ""+cells.count

  observer = new FieldObserverWithRemoreRenderer tessellation, appendRewrite, minVisibleSize
  observer.onFinish = -> redraw()

moveView = (dx, dy) -> observer.modifyView M.translationMatrix(dx, dy)        
rotateView = (angle) -> observer.modifyView M.rotationMatrix angle
  
class MouseTool
  mouseMoved: ->
