void DelaunayPulseOut::update( float elapsed )
{
	timer += elapsed;
	vector<pair< int, float > > pings;
	// update animation
	while ( !queued_pulses.empty() && queued_pulses.top().timer < timer )
	{
		// fetch id
		int curr = queued_pulses.top().id;
		float energy = queued_pulses.top().energy;
		// remove from queue
		queued_pulses.pop();
		// if we haven't already seen this one
		if ( seen.find( curr ) == seen.end() )
		{
			// pulse the led
			lights->pulse( curr, energy );
			
			// queue a ping
			pings.push_back( make_pair( curr, energy ) );
			
			// add to seen
			seen.insert( curr );
			
			// add neighbours to queue
			set<int> adj = lights->getDelaunay()->getNeighbours( curr );
			// check neighbours against seen. 
			ofxVec2f curr_pos( lights->getLight( curr ).getX(), 
							  lights->getLight( curr ).getY() );
			for ( set<int>::iterator jt = adj.begin();
				 jt != adj.end(); 
				 ++jt )
			{
				// add unseen neighbours 
				if ( seen.find( *jt ) == seen.end() )
				{
					ofxVec2f adj_pos( lights->getLight( *jt ).getX(), 
									 lights->getLight( *jt ).getY() );
					float distance = ( adj_pos - curr_pos ).length();
					queued_pulses.push( MovingPulse(*jt, energy*max(0.0f,1-falloff*distance), ofRandom(0.8f,1.2f)*(timer+(distance/speed)) ) );
				}
			}
		}
	}
	// send pings
	for ( int i=0; i<pings.size(); i++ )
	{
		ofxOscMessage m;
		m.setAddress( "/delaunay/ping" );
		m.addFloatArg( pings[i].second );
		const Light& light = lights->getLight( pings[i].first );
		m.addFloatArg( light.getX() );
		m.addFloatArg( light.getY() );
		Osc::getInstance()->sendMessage( m );
	}
}
예제 #2
0
    ActionType Simple::takeTurn(const Surroundings &s) const
    {
        // __posRandom takes in a vector of int (position) so make a vector of prioritized positions
        std::vector<int> potential_pos;
        // reset the position to the center of the grid.
        Position curr_pos(1, 1);
        Position new_pos;
        PositionRandomizer position;

        // look for food and loot first
        for (int i=0; i < 9; i++)
        {
            if (s.array[i] == FOOD || s.array[i] == ADVANTAGE)
            {
                potential_pos.push_back(i);
            }
        }

        if (potential_pos.size() > 0) {
            new_pos = Game::randomPosition(potential_pos);
            return Game::reachSurroundings(curr_pos, new_pos);
        }
        // look for somewhere safe to hide
        for (int i = 0; i < 9; i++) {
            if (s.array[i] == EMPTY)
            {
                potential_pos.push_back(i);
            }
        }
        if (potential_pos.size() > 0) {
            new_pos = Game::randomPosition(potential_pos);
            return Game::reachSurroundings(curr_pos, new_pos);
        }
        // if neither are available stay put
        return STAY;
    }
예제 #3
0
Point2D OpticalFlow::getAccumulatedDelta(const Point2D& position,
                                         const float32 radius,
                                         const clock_t timestamp) const {
  Point2D curr_pos(position);

  // Scale down to downsampled size.
  curr_pos.x /= downsample_factor_;
  curr_pos.y /= downsample_factor_;

  LOGV("Tracking accumulated delta from %.2f, %.2f", curr_pos.x, curr_pos.y);

  const float32 cutoff_dist = radius / downsample_factor_;

  // Anything that ended before the requested timestamp is of no concern to us.
  bool found_it = false;
  int32 num_frames_back = -1;
  for (int32 i = 0; i < num_frames_; ++i) {
    const FramePair& frame_pair =
        frame_pairs_[geNthIndexFromEnd(i)];

    if (frame_pair.end_time <= timestamp) {
      num_frames_back = i - 1;

      if (num_frames_back > 0) {
        LOGV("Went %d out of %d frames before finding frame. (index: %d)",
             num_frames_back, num_frames_, geNthIndexFromEnd(i));
      }

      found_it = true;
      break;
    }
  }

  if (!found_it) {
    const FramePair& frame_pair = frame_pairs_[geNthIndexFromStart(0)];
    const FramePair& latest_frame_pair = frame_pairs_[geNthIndexFromEnd(0)];

    clock_t latest_time = latest_frame_pair.end_time;

    LOGW("History did not go back far enough! %ld vs %ld",
         latest_time - frame_pair.end_time,
         latest_time - timestamp);
  }

  // Loop over all the frames in the queue, tracking the accumulated delta
  // of the point from frame to frame.  It's possible the point could
  // go out of frame, but keep tracking as best we can, using points near
  // the edge of the screen where it went out of bounds.
  for (int32 i = num_frames_back; i >= 0; --i) {
    const FramePair& frame_pair = frame_pairs_[geNthIndexFromEnd(i)];
    CHECK(frame_pair.end_time >= timestamp, "Frame timestamp was too early!");

    const Point2D delta = frame_pair.queryFlow(curr_pos, cutoff_dist);
    curr_pos.x += delta.x;
    curr_pos.y += delta.y;
  }

  // Scale back to original size.
  curr_pos.x *= downsample_factor_;
  curr_pos.y *= downsample_factor_;

  // Return the delta only.
  return curr_pos - position;
}
예제 #4
0
void DelaunayPulseIn::update( float elapsed )
{
	timer += elapsed;
	// update animation
	//printf("queue contains: ");
	vector<MovingPulse> dequeued;
	while ( !queued_pulses.empty() && queued_pulses.top().timer < timer )
	{
		// dequeue
		dequeued.push_back( queued_pulses.top() );
		
		// remove from queue
		queued_pulses.pop();
	}

	// pings
	vector<pair< int, float > > pings;

	// coalesce pulses for the same node
	map<int,int> coalesced;
	for ( int i=0; i<dequeued.size(); i++ )
	{
		int id = dequeued[i].id;
		// add ping here (because we might drop it later)
		pings.push_back( make_pair( id, dequeued[i].energy ) );
		// coalesce
		if ( coalesced.find( id ) == coalesced.end() )
		{
			coalesced[id] = i;
		}
		else
		{
			// merge
			dequeued[coalesced[id]].energy += dequeued[i].energy;
			// remove
			dequeued.erase( dequeued.begin()+i );
			i--;
		}
	}
	// no go through coalesced
	for ( int i=0; i<dequeued.size(); i++ )
	{
		// fetch id
		int curr = dequeued[i].id;
		float energy = dequeued[i].energy;
		//printf("%2i:%7.5f ", curr, energy );

		// pulse the led
		if ( dequeued[i].timer > 0 )
			lights->pulse( curr, energy );
		// finished?
		if ( curr == target_index || energy < 0.001f )
			continue;
		
		// add the closest neighbours to queue
		set<int> adj = delaunay->getNeighbours( curr );
		ofxVec2f curr_pos( lights->getLight( curr ).getX(), 
						  lights->getLight( curr ).getY() );
		ofxVec2f target_pos( lights->getLight( target_index ).getX(),
							lights->getLight( target_index ).getY() );
		// use for calculating dot product (-> angle )
		ofxVec2f target_delta = target_pos - curr_pos;
		float distance_to_target = target_delta.length();
		target_delta /= distance_to_target;
		//printf("delta to target is %7.5f %7.5f\n", target_delta.x, target_delta.y );
		for ( set<int>::iterator jt = adj.begin();
			 jt != adj.end(); 
			 ++jt )
		{
			// add neighbours, distributing energy
			ofxVec2f adj_pos( lights->getLight( *jt ).getX(), 
							 lights->getLight( *jt ).getY() );
			ofxVec2f adj_delta = adj_pos - curr_pos;
			float distance = adj_delta.length();
			adj_delta /= distance;
			
			// dot product
			float direction_accuracy = target_delta.dot( adj_delta );
			// would this path take us towards the target?
			//printf(" adj delta to next is %7.5f %f7.5 -> accuracy %7.5f\n", adj_delta.x, adj_delta.y, direction_accuracy );
			if ( direction_accuracy > 0.5f )
			{
				direction_accuracy*=direction_accuracy;
				// yes
				//float new_energy = direction_accuracy*0.5f*(max_brightness*(1.0f-(distance_to_target/initial_radius)));
				float falloff = 0.25f;
				float new_energy = energy*direction_accuracy*0.5f - energy*distance*falloff;
				queued_pulses.push( MovingPulse(*jt, new_energy, ofRandom(0.8f,1.2f)*(timer+(distance/speed)) ) );
			}
		}
	}
	//printf("\n");
	// send pings
	for ( int i=0; i<pings.size(); i++ )
	{
		ofxOscMessage m;
		m.setAddress( "/delaunay/ping" );
		m.addFloatArg( pings[i].second );
		const Light& light = lights->getLight( pings[i].first );
		m.addFloatArg( light.getX() );
		m.addFloatArg( light.getY() );
		m.addFloatArg( delaunay->getId() );
		Osc::getInstance()->sendMessage( m );
	}
	
}