//Any live cell with fewer than two live neighbours dies, as if caused by under-population.
    //Any live cell with two or three live neighbours lives on to the next generation.
    //Any live cell with more than three live neighbours dies, as if by overcrowding.
    //Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
    bool alive(uint8_t x, uint8_t y) {
        uint8_t neighbours = numNeighbours(x, y);
        bool retVal = false;
        if ((*currState)[x][y] > 0) {
            retVal = neighbours == 2 || neighbours == 3;
        } else {
            retVal = neighbours == 3;
        }
//        Serial.print("alive("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(") = "); Serial.println(retVal);      
        return retVal;
    };
Beispiel #2
0
void MeshGroup::smoothVectorOccludersData()
{
  info( "Averaging vector occluder data shape %s", shape->name.c_str() ) ;
  // must do smoothing in copy structures
  // otherwise you change teh data as you are averaging it
  vector<VectorOccludersData> newFrd( getTotalVertices() ) ;
  vector<int> numNeighbours( getTotalVertices(), 0 ) ;

  int vID = 0 ;
  for( int meshNo = 0 ; meshNo < meshes.size() ; meshNo++ )
  {
    for( int vNo = 0 ; vNo < meshes[meshNo]->verts.size() ; vNo++ )
    {
      AllVertex* vertex = &meshes[meshNo]->verts[vNo];
      VectorOccludersData* voData = vertex->voData;
      
      // write the initial values from voData (current voData we are smoothing).
      newFrd[vID].reflectors = voData->reflectors ; ///copy the whole map

      numNeighbours[vID]++; //myself.

      for( int m = 0 ; m < meshes.size() ; m++ )
      {
        for( int j = 0 ; j < meshes[m]->verts.size() ; j++ )
        {
          AllVertex* other = &meshes[m]->verts[j] ;
          if( vertex != other &&
              vertex->pos.Near( other->pos ) )
          {
            // Found a near vertex.
            numNeighbours[vID]++;

            // take a look at the neighbour's reflectors
            for( map< Mesh*,VOVectors >::iterator neigh = other->voData->reflectors.begin() ;
                 neigh != other->voData->reflectors.end() ; ++neigh )
            {
              // Do I have this emitter shape?
              map< Mesh*,VOVectors >::iterator inAvg = newFrd[vID].reflectors.find( neigh->first ) ;
              
              // it's possible another vertex found a shape we didn't see in our ray cast
              // (for lwo res ray casts).  average it in.
              if( inAvg == newFrd[vID].reflectors.end() )  // shape in neighbour NOT FOUND in avg.
              {
                // Happens a lot for small # verts
                ///info( "%s not in avg vertex %d", neigh->first->name.c_str(), vID ) ;
                newFrd[vID].reflectors.insert( make_pair( neigh->first, neigh->second ) ) ; // copy the first one in there
              }
              else
              {
                // sum it in.
                inAvg->second.Add( neigh->second ) ;
                inAvg->second.normSpecular.w++ ;  // counts # pos/normals added in.
              }
            }
          }
        }
      }

      // Divide out the final values.
      for( map< Mesh*,VOVectors >::iterator iter = newFrd[vID].reflectors.begin() ;
           iter != newFrd[vID].reflectors.end() ; ++iter )
      {
        // the divider is in normSpecular.
        iter->second.Divide( iter->second.normSpecular.w ) ;
        iter->second.normSpecular.w = 1 ;
      }
      vID++ ;
    }
  }

  // WRITE
  vID=0;
  for( int meshNo = 0 ; meshNo < meshes.size() ; meshNo++ )
  {
    for( int vNo = 0 ; vNo < meshes[meshNo]->verts.size() ; vNo++ )
    {
      *meshes[meshNo]->verts[vNo].voData = newFrd[vID++] ;
    }
  }
}