/* 0 - up left, 1 - up right, 2 - down right, 3 - down left */
int get_diagonal_index(mesh_t *mesh, int direction, int cur_y, int cur_x)
{
	switch (direction) {
		case 0:
			return MESH_INDEX((cur_y - 1), (cur_x - 1));
		case 1:
			return MESH_INDEX((cur_y - 1), (cur_x + 1));
		case 2:
			return MESH_INDEX((cur_y + 1), (cur_x + 1));
		case 3:
			return MESH_INDEX((cur_y + 1), (cur_x - 1));
	}
	return 0;
}
/* Corner update for the diffusion test problem */
void diff_update_corner_dirichlet(mesh_t *mesh, mesh_t *mesh_old, int cur_y,
	int cur_x, int boundary_side1, int boundary_side2)
{
	int k;
	cell_t *cur_cell, *cur_cell_old, *adj_cell;
	double A, sum_A, sum_A_R, num, denom, phi_h_dt, xi;

	cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
	cur_cell_old = &mesh_old->cell[MESH_INDEX(cur_y, cur_x)];

	sum_A = 0;
	sum_A_R = 0;

	xi = 2 * cur_cell->diffusion / mesh->dim.h;

	/* Updates saturation for the current cell on the new mesh */
	for (k = 0; k < 4; k++) {
		if ((k != boundary_side1) && (k != boundary_side2)) {
			adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
			sum_A += cur_cell_old->A_d[k];
			sum_A_R += cur_cell_old->A_d[k] * adj_cell->robin[(k + 2) % 4];
		}
	}

	phi_h_dt = (mesh->global.porosity * mesh->dim.h / mesh->dim.dt);

	num = cur_cell_old->source_d * mesh->dim.h + sum_A_R + phi_h_dt * cur_cell_old->saturation_prev;
	denom = phi_h_dt + sum_A + xi;

	cur_cell->saturation = num / denom;

	/* Updates flux for the current cell on the new mesh */
	for (k = 0; k < 4; k++) {
		if ((k != boundary_side1) && (k != boundary_side2)) {
			adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
	        A = cur_cell->A_d[k];
	        cur_cell->flux_d[k] = A * (cur_cell->saturation - adj_cell->robin[(k + 2) % 4]);
		}
	}

	/* Updates the saturation at the edges of the current cell in the new mesh */
    for (k = 0; k < 4; k ++) {
		if ((k != boundary_side1) && (k != boundary_side2)) {
	        adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
		    cur_cell->l_d[k] = cur_cell->beta[k] * cur_cell->flux_d[k] + adj_cell->robin[(k + 2) % 4];
		}
	}
}
Example #3
0
/* Finds the maxiumum time step for transport */
void mesh_max_time_step(mesh_t *mesh, mesh_t *mesh_old)
{
    double max = 0, mult = 0, vel_norm = 0, global_max = 0;
    cell_t *cur_cell;

    for (int i = 0; i < mesh->dim.ydim; i++) {
        for (int j = 0; j < mesh->dim.xdim; j++) {
            cur_cell = &mesh_old->cell[MESH_INDEX(i, j)];
            vel_norm = sqrt(pow(cur_cell->velocity_x, 2) + pow(cur_cell->velocity_y, 2));
            mult = cur_cell->pm_w_deriv / mesh->global.porosity * vel_norm;
            if (mult > max)
                max = mult;
        }
    }

    MPI_Allreduce(&max, &global_max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);

    double time = (0.95 * mesh->dim.h / 2) / global_max;

    if (time > (mesh->dim.dt / 5.0)) {
        mesh->dim.dt_transport = mesh->dim.dt / 5.0;
        mesh_old->dim.dt_transport = mesh->dim.dt / 5.0;
    } else {
        mesh->dim.dt_transport = time;
        mesh_old->dim.dt_transport = time;
    }
}
Example #4
0
void setup_transport_test(mesh_t *mesh)
{
    cell_t *cur_cell;

    cur_cell = &mesh->cell[MESH_INDEX((mesh->dim.ydim - 1), 0)];
    cur_cell->saturation = 0.84;
}
/* Computes robin conditions for the diffusion problem */
void diff_compute_robin(mesh_t *mesh, int cur_y, int cur_x)
{
	cell_t *cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];

	for (int k = 0; k < 4; k++) {
		cur_cell->robin[k] = cur_cell->beta[k] * cur_cell->flux_d[k] + cur_cell->l_d[k];
	}
}
void press_update_corner(mesh_t *mesh, mesh_t *mesh_old, int cur_y, int cur_x,
                    int boundary_side1, int boundary_side2)
{
    int k;
    cell_t *cur_cell, *cur_cell_old, *adj_cell;
    double sum_A, sum_A_R, A;

    cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
    cur_cell_old = &mesh_old->cell[MESH_INDEX(cur_y, cur_x)];

    sum_A = 0;
    sum_A_R = 0;

    for (k = 0; k < 4; k++) {
        if ((k != boundary_side1) && (k != boundary_side2)) {
            adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
            sum_A += cur_cell_old->A_p[k];
            sum_A_R += cur_cell_old->A_p[k] * adj_cell->robin[(k + 2) % 4];
        }
    }

    /* Updates the pressure at the current cell on the new mesh */
    cur_cell->pressure = (cur_cell_old->source * mesh->dim.h + sum_A_R) / sum_A;

    /* Updates the flux at the current cell on the new mesh */
    for (k = 0; k < 4; k++) {
        if ((k != boundary_side1) && (k != boundary_side2)) {
            adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
            A = cur_cell->A_p[k];
            cur_cell->flux_p[k] = A * (cur_cell->pressure - adj_cell->robin[(k + 2) % 4]);
        }
    }

    /* Updates the pressure at the edges of the current cell in the new mesh */
    for (k = 0; k < 4; k ++) {
        if ((k != boundary_side1) && (k != boundary_side2)) {
            adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
            cur_cell->l_p[k] = cur_cell->beta[k] * cur_cell->flux_p[k] +
                                adj_cell->robin[(k + 2) % 4];
        }
    }
}
/* Computes A_alpha = xi/(1+beta_alpha*xi), xi = 2k/h */
void press_compute_A(mesh_t *mesh, int cur_y, int cur_x)
{
    double xi;
    cell_t *cur_cell;

    cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
    xi = 2.0 * cur_cell->perm * total_mobility(cur_cell, &mesh->global)/ mesh->dim.h;
	// printf("lambda: %e\n", total_mobility(cur_cell, &mesh->global));
    for (int k = 0; k < 4; k++) {
        cur_cell->A_p[k] = xi / (1.0 + cur_cell->beta[k] * xi);
    }
}
/* Updates the saturation and flux for the diffusion problem on interior cells */
void diff_update_interior(mesh_t *mesh, mesh_t *mesh_old, int cur_y, int cur_x)
{
	int k;
	cell_t *cur_cell, *cur_cell_old, *adj_cell;
	double A, sum_A, sum_A_R, num, denom, phi_h_dt;

	cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
	cur_cell_old = &mesh_old->cell[MESH_INDEX(cur_y, cur_x)];

	sum_A = 0;
	sum_A_R = 0;

	/* Updates saturation for the current cell on the new mesh */
	for (k = 0; k < 4; k++) {
		adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
		sum_A += cur_cell_old->A_d[k];
		sum_A_R += cur_cell_old->A_d[k] * adj_cell->robin[(k + 2) % 4];
	}

	phi_h_dt = (mesh->global.porosity * mesh->dim.h / mesh->dim.dt);

	num = cur_cell_old->source_d * mesh->dim.h + sum_A_R + phi_h_dt * cur_cell_old->saturation_prev;
	denom = phi_h_dt + sum_A;

	cur_cell->saturation = num / denom;

	/* Updates flux for the current cell on the new mesh */
	for (k = 0; k < 4; k++) {
		adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
        A = cur_cell->A_d[k];
        cur_cell->flux_d[k] = A * (cur_cell->saturation - adj_cell->robin[(k + 2) % 4]);
	}

	/* Updates the pressure at the edges of the current cell in the new mesh */
    for (k = 0; k < 4; k ++) {
        adj_cell = &mesh_old->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
        cur_cell->l_d[k] = cur_cell->beta[k] * cur_cell->flux_d[k] + adj_cell->robin[(k + 2) % 4];
    }
}
Example #9
0
/* Computes the velocity information on the mesh */
void mesh_compute_velocity(mesh_t *mesh)
{
    cell_t *cur_cell;

    for (int i = 0; i < mesh->dim.ydim; i++) {
        for (int j = 0; j < mesh->dim.xdim; j++) {
            cur_cell = &mesh->cell[MESH_INDEX(i, j)];

            cur_cell->velocity_y = (cur_cell->flux_p[0] - cur_cell->flux_p[2]) / 2;
            cur_cell->velocity_x = (cur_cell->flux_p[1] - cur_cell->flux_p[3]) / 2;
        }
    }
}
Example #10
0
/* Records production well data */
void record_production_wells(production_wells_t *wells, mesh_t *mesh, int time_step)
{
    cell_t *cur_cell;
    prod_well_t *cur_well;
    int y, x;

    for (int i = 0; i < wells->num_wells; i++) {
        cur_well = &wells->wells[i];
        y = cur_well->y_pos;
        x = cur_well->x_pos;
        cur_cell = &mesh->cell[MESH_INDEX(y, x)];
        cur_well->oil_sat_recording[time_step] = 1.0 - cur_cell->saturation;
    }
}
/* Computes A_alpha = xi/(1+beta_alpha*xi), xi = - 2D/h */
void diff_compute_A(mesh_t *mesh, int cur_y, int cur_x)
{
    double xi;
    cell_t *cur_cell;

    cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
    xi = 2.0 * cur_cell->diffusion / mesh->dim.h;

    for (int k = 0; k < 4; k++) {
        cur_cell->A_d[k] = xi / (cur_cell->beta[k] * xi - 1.0);
		// if ((cur_y == mesh->dim.ydim - 1) && (cur_x == 0))
		// 	printf("A: %e\n", cur_cell->A_d[k]);
    }
}
Example #12
0
/* Initializes Production Wells */
production_wells_t init_production_wells(mesh_t *mesh)
{
	cell_t *cur_cell;
	production_wells_t prod_wells;

	/* First sweep to determine number of production wells */
	for (int i = 0; i < mesh->dim.ydim; i++) {
		for (int j = 0; j < mesh->dim.xdim; j++) {
			cur_cell = &mesh->cell[MESH_INDEX(i, j)];
			if (cur_cell->source < 0)
				prod_wells.num_wells++;
		}
	}

	/* Allocates memory for array of wells */
	prod_wells.wells = malloc(prod_wells.num_wells * sizeof(prod_well_t));

    /* Allocates memory for oil saturation recordings within wells */
    for (int i = 0; i < prod_wells.num_wells; i++) {
        prod_wells.wells[i].oil_sat_recording = malloc(mesh->dim.num_ts * sizeof(double));
    }

    /* Records the x and y position for each well */
    int well_count = 0;
    for (int i = 0; i < mesh->dim.ydim; i++) {
        for (int j = 0; j < mesh->dim.xdim; j++) {
            cur_cell = &mesh->cell[MESH_INDEX(i, j)];
            if (cur_cell->source < 0) {
                prod_wells.wells[well_count].y_pos = i;
                prod_wells.wells[well_count].x_pos = j;
                prod_wells.wells[well_count].oil_sat_recording[0] = 1 - cur_cell->saturation;
            }
        }
    }

	return prod_wells;
}
/* Direction = 0 for x, 1 for y */
double trans_get_old_position(mesh_t *mesh, int cur_y, int cur_x, int direction)
{
	cell_t *cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];

	double pos;
	pos = (-1.0) * cur_cell->pm_w_deriv * mesh->dim.dt_transport;
	pos /= mesh->global.porosity;

	if (direction == 0)
		return pos * cur_cell->velocity_x;
	else if (direction == 1)
		return pos * cur_cell->velocity_y;
	else
		return 0;
}
/* Combutes beta at the current cell for diffusion problem */
void diff_compute_beta(mesh_t *mesh, int cur_y, int cur_x, double beta_coef)
{
	cell_t *cur_cell, *adj_cell;
	double diff_eff;

	cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];

	for (int k = 0; k < 4; k++) {
		adj_cell = &mesh->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
		if (adj_cell->diffusion == 0) {
			cur_cell->beta[k] = 0;
		} else {
			diff_eff = 2.0 * adj_cell->diffusion * cur_cell->diffusion;
			diff_eff /= (adj_cell->diffusion + cur_cell->diffusion);
			cur_cell->beta[k] =(-1.0) * beta_coef * mesh->dim.h / diff_eff;
		}
	}
}
Example #15
0
void setup_diffusion_test(mesh_t *mesh)
{
    cell_t *cur_cell;
    double delta_x = mesh->dim.xlen / mesh->dim.xdim;
    double x;

    mesh->global.porosity = 1;

    for (int i = 0; i < mesh->dim.ydim; i++) {
        for (int j = 0; j < mesh->dim.xdim; j++) {
            x = delta_x * j;
            cur_cell = &mesh->cell[MESH_INDEX(i, j)];
            cur_cell->saturation = 0;
            cur_cell->saturation_prev = sin(M_PI * x) + 0.5 * sin(3.0 * M_PI * x);
            cur_cell->diffusion = 1;
        }
    }
}
/* Computes beta at the current cell for pressure problem */
void press_compute_beta(mesh_t *mesh, int cur_y, int cur_x, double beta_coef)
{
    double perm_eff;
    cell_t *cur_cell, *adj_cell;

	double total_mob, adj_total_mob;

    cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
	total_mob = total_mobility(cur_cell, &mesh->global);

    for (int k = 0; k < 4; k++) {
        adj_cell = &mesh->cell[get_adjacent_index(mesh, k, cur_y, cur_x)];
		adj_total_mob = total_mobility(adj_cell, &mesh->global);
		// printf("cur y %d, cur x %d, adj total mob %e\n", cur_y, cur_x, adj_total_mob);
        if (adj_cell->perm == 0) {
            cur_cell->beta[k] = 0;
        } else {
            perm_eff = 2 * adj_cell->perm * adj_total_mob * cur_cell->perm * total_mob;
            perm_eff /= (adj_cell->perm * adj_total_mob + cur_cell->perm * total_mob);
            cur_cell->beta[k] = beta_coef * mesh->dim.h / perm_eff;
        }

		// if (adj_cell->perm == 0) {
        //     cur_cell->beta[k] = 0;
        // } else {
        //     perm_eff = 2 * adj_cell->perm * cur_cell->perm;
        //     perm_eff /= (adj_cell->perm + cur_cell->perm);
        //     cur_cell->beta[k] = beta_coef * mesh->dim.h / perm_eff;
        // }

        /* temp fix for weird inf bug */
        if ((cur_cell->beta[k] == INFINITY) || (cur_cell->beta[k] == NAN)) {
            cur_cell->beta[k] = 0;
        }
    }
}
Example #17
0
static void
init_static_index_arrays (TestState *state)
{
  guint     n_indices;
  int       x, y;
  guint16  *i;
  guint     dir;

  /* - Each row takes (2 + 2 * MESH_WIDTH indices)
   *    - Thats 2 to start the triangle strip then 2 indices to add 2 triangles
   *      per mesh quad.
   * - We have MESH_HEIGHT rows
   * - It takes one extra index for linking between rows (MESH_HEIGHT - 1)
   * - A 2 x 3 mesh == 20 indices... */
  n_indices = (2 + 2 * MESH_WIDTH) * MESH_HEIGHT + (MESH_HEIGHT - 1);
  state->static_indices = g_malloc (sizeof (guint16) * n_indices);
  state->n_static_indices = n_indices;

#define MESH_INDEX(X, Y) (Y) * (MESH_WIDTH + 1) + (X)

  i = state->static_indices;

  /* NB: front facing == anti-clockwise winding */

  i[0] = MESH_INDEX (0, 0);
  i[1] = MESH_INDEX (0, 1);
  i += 2;

#define LEFT  0
#define RIGHT 1

  dir = RIGHT;

  for (y = 0; y < MESH_HEIGHT; y++)
    {
      for (x = 0; x < MESH_WIDTH; x++)
        {
          /* Add 2 triangles per mesh quad... */
          if (dir == RIGHT)
            {
              i[0] = MESH_INDEX (x + 1, y);
              i[1] = MESH_INDEX (x + 1, y + 1);
            }
          else
            {
              i[0] = MESH_INDEX (MESH_WIDTH - x - 1, y);
              i[1] = MESH_INDEX (MESH_WIDTH - x - 1, y + 1);
            }
          i += 2;
        }

      /* Link rows... */

      if (y == (MESH_HEIGHT - 1))
        break;

      if (dir == RIGHT)
        {
          i[0] = MESH_INDEX (MESH_WIDTH, y + 1);
          i[1] = MESH_INDEX (MESH_WIDTH, y + 1);
          i[2] = MESH_INDEX (MESH_WIDTH, y + 2);
        }
      else
        {
          i[0] = MESH_INDEX (0, y + 1);
          i[1] = MESH_INDEX (0, y + 1);
          i[2] = MESH_INDEX (0, y + 2);
        }
      i += 3;
      dir = !dir;
    }

#undef MESH_INDEX

  state->indices =
    cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
                                    state->static_indices,
                                    state->n_static_indices);
}
void trans_update_corner(mesh_t *mesh, mesh_t *mesh_old, int cur_y, int cur_x,
                    int boundary_side1, int boundary_side2)
{
	cell_t *cur_cell, *cur_cell_old, *adj_cell_vert, *adj_cell_hor, *adj_cell_diag;
	double y_comp, x_comp;

	/* Gets the x and y components of the backwards in time vector for method */
	/* of characteristics */
	y_comp = trans_get_old_position(mesh_old, cur_y, cur_x, 1);
	x_comp = trans_get_old_position(mesh_old, cur_y, cur_x, 0);

	cur_cell = &mesh->cell[MESH_INDEX(cur_y, cur_x)];
	cur_cell_old = &mesh->cell[MESH_INDEX(cur_y, cur_x)];

	/* Gets the quadrant the foot is in */
	int quad = get_quadrant(y_comp, x_comp);
	int corner_type = get_corner_config(boundary_side1, boundary_side2);

	/* Sets components to proportions of full cell */
	y_comp = fabs(y_comp / mesh->dim.h);
	x_comp = fabs(x_comp / mesh->dim.h);
	// printf("ycomp %e, xcomp %e\n", y_comp, x_comp);

	/* Selects the configuration of cells */
	switch (corner_type) {
		case 1:
			switch (quad) {
				case 1:
					dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
								&adj_cell_diag);
					break;
				case 2:
					dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							  	&adj_cell_diag, cur_y, cur_x, 3);
					break;
				case 3:
					assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert,
						 		&adj_cell_diag, cur_y, cur_x, quad);
					break;
				default:
					dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
					  			&adj_cell_diag, cur_y, cur_x, 2);
					break;
			}
			break;
		case 2:
			switch (quad) {
				case 1:
					dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
						  		&adj_cell_diag, cur_y, cur_x, 1);
					break;
				case 2:
					dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
								&adj_cell_diag);
					break;
				case 3:
					dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
				  				&adj_cell_diag, cur_y, cur_x, 2);
					break;
				default:
					assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert,
								&adj_cell_diag, cur_y, cur_x, quad);
					break;
			}
			break;
		case 3:
			switch (quad) {
				case 1:
					assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag, cur_y, cur_x, quad);
					break;
				case 2:
					dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag, cur_y, cur_x, 0);
					break;
				case 3:
					dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag);
					break;
				default:
					dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag, cur_y, cur_x, 1);
					break;
			}
			break;
		default:
			switch (quad) {
				case 1:
					dup_cell_hor(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag, cur_y, cur_x, 0);
					break;
				case 2:
					assign_cells(mesh_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag, cur_y, cur_x, quad);
					break;
				case 3:
					dup_cell_vert(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag, cur_y, cur_x, 3);
					break;
				default:
					dup_cell_corner(mesh, cur_cell_old, &adj_cell_hor, &adj_cell_vert,
							&adj_cell_diag);
					break;
			}
	}

	cur_cell->saturation = trans_get_average_sat(cur_cell_old, adj_cell_hor,
							adj_cell_vert, adj_cell_diag, y_comp, x_comp);
	// printf("sat: %e\n", cur_cell->saturation);
}
Example #19
0
static void
clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
{
  ClutterDeformEffectPrivate *priv = self->priv;
  GLushort *static_indices, *static_back_indices;
  GLushort *idx, *back_idx;
  gint x, y, direction;
  gint n_tiles;

  clutter_deform_effect_free_arrays (self);

  priv->n_indices = (2 + 2 * priv->x_tiles)
                  * priv->y_tiles
                  + (priv->y_tiles - 1);

  static_indices = g_new (GLushort, priv->n_indices);
  static_back_indices = g_new (GLushort, priv->n_indices);

#define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x))

  /* compute all the triangles from the various tiles */
  direction = 1;

  idx = static_indices;
  idx[0] = MESH_INDEX (0, 0);
  idx[1] = MESH_INDEX (0, 1);
  idx += 2;

  back_idx = static_back_indices;
  back_idx[0] = MESH_INDEX (priv->x_tiles, 0);
  back_idx[1] = MESH_INDEX (priv->x_tiles, 1);
  back_idx += 2;

  for (y = 0; y < priv->y_tiles; y++)
    {
      for (x = 0; x < priv->x_tiles; x++)
        {
          if (direction)
            {
              idx[0] = MESH_INDEX (x + 1, y);
              idx[1] = MESH_INDEX (x + 1, y + 1);

              back_idx[0] = MESH_INDEX (priv->x_tiles - (x + 1), y);
              back_idx[1] = MESH_INDEX (priv->x_tiles - (x + 1), y + 1);
            }
          else
            {
              idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y);
              idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1);

              back_idx[0] = MESH_INDEX (x + 1, y);
              back_idx[1] = MESH_INDEX (x + 1, y + 1);
            }

          idx += 2;
          back_idx += 2;
        }

      if (y == (priv->y_tiles - 1))
        break;

      if (direction)
        {
          idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
          idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
          idx[2] = MESH_INDEX (priv->x_tiles, y + 2);

          back_idx[0] = MESH_INDEX (0, y + 1);
          back_idx[1] = MESH_INDEX (0, y + 1);
          back_idx[2] = MESH_INDEX (0, y + 2);
        }
      else
        {
          idx[0] = MESH_INDEX (0, y + 1);
          idx[1] = MESH_INDEX (0, y + 1);
          idx[2] = MESH_INDEX (0, y + 2);

          back_idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
          back_idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
          back_idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
        }

      idx += 3;
      back_idx += 3;

      direction = !direction;
    }

#undef MESH_INDEX

  priv->indices =
    cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
                                    static_indices,
                                    priv->n_indices);
  priv->back_indices =
    cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
                                    static_back_indices,
                                    priv->n_indices);

  g_free (static_indices);
  g_free (static_back_indices);

  n_tiles = (priv->x_tiles + 1) * (priv->y_tiles + 1);
  priv->vertices = g_new (CoglTextureVertex, n_tiles);
  priv->vbo = cogl_vertex_buffer_new (n_tiles);

  priv->is_dirty = TRUE;
}
Example #20
0
static void
clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
{
  ClutterDeformEffectPrivate *priv = self->priv;
  gint x, y, direction, n_indices;
  CoglAttribute *attributes[3];
  guint16 *static_indices;
  CoglContext *ctx =
    clutter_backend_get_cogl_context (clutter_get_default_backend ());
  CoglIndices *indices;
  guint16 *idx;
  int i;

  clutter_deform_effect_free_arrays (self);

  n_indices = ((2 + 2 * priv->x_tiles)
               * priv->y_tiles
               + (priv->y_tiles - 1));

  static_indices = g_new (guint16, n_indices);

#define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x))

  /* compute all the triangles from the various tiles */
  direction = 1;

  idx = static_indices;
  idx[0] = MESH_INDEX (0, 0);
  idx[1] = MESH_INDEX (0, 1);
  idx += 2;

  for (y = 0; y < priv->y_tiles; y++)
    {
      for (x = 0; x < priv->x_tiles; x++)
        {
          if (direction)
            {
              idx[0] = MESH_INDEX (x + 1, y);
              idx[1] = MESH_INDEX (x + 1, y + 1);
            }
          else
            {
              idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y);
              idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1);
            }

          idx += 2;
        }

      if (y == (priv->y_tiles - 1))
        break;

      if (direction)
        {
          idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
          idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
          idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
        }
      else
        {
          idx[0] = MESH_INDEX (0, y + 1);
          idx[1] = MESH_INDEX (0, y + 1);
          idx[2] = MESH_INDEX (0, y + 2);
        }

      idx += 3;

      direction = !direction;
    }

#undef MESH_INDEX

  indices = cogl_indices_new (ctx,
                              COGL_INDICES_TYPE_UNSIGNED_SHORT,
                              static_indices,
                              n_indices);

  g_free (static_indices);

  priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1);

  priv->buffer =
    cogl_attribute_buffer_new (ctx,
                               sizeof (CoglVertexP3T2C4) *
                               priv->n_vertices,
                               NULL);

  /* The application is expected to continuously modify the vertices
     so we should give a hint to Cogl about that */
  cogl_buffer_set_update_hint (COGL_BUFFER (priv->buffer),
                               COGL_BUFFER_UPDATE_HINT_DYNAMIC);

  attributes[0] = cogl_attribute_new (priv->buffer,
                                      "cogl_position_in",
                                      sizeof (CoglVertexP3T2C4),
                                      G_STRUCT_OFFSET (CoglVertexP3T2C4, x),
                                      3, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (priv->buffer,
                                      "cogl_tex_coord0_in",
                                      sizeof (CoglVertexP3T2C4),
                                      G_STRUCT_OFFSET (CoglVertexP3T2C4, s),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[2] = cogl_attribute_new (priv->buffer,
                                      "cogl_color_in",
                                      sizeof (CoglVertexP3T2C4),
                                      G_STRUCT_OFFSET (CoglVertexP3T2C4, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);

  priv->primitive =
    cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
                                        priv->n_vertices,
                                        attributes,
                                        3 /* n_attributes */);
  cogl_primitive_set_indices (priv->primitive,
                              indices,
                              n_indices);

  if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES))
    {
      priv->lines_primitive =
        cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP,
                                            priv->n_vertices,
                                            attributes,
                                            2 /* n_attributes */);
      cogl_primitive_set_indices (priv->lines_primitive,
                                  indices,
                                  n_indices);
    }

  cogl_object_unref (indices);

  for (i = 0; i < 3; i++)
    cogl_object_unref (attributes[i]);

  priv->is_dirty = TRUE;
}