Beispiel #1
0
/**
 * @brief       Performs undo move.
 *
 * Takes back last move from move history and on the board.
 *
 * @return      Nothing
 * @sa          make_move()
 */
void undo_move(void)
{
    int k;
    int i            = get_last_move_i();
    int j            = get_last_move_j();
    int color        = get_last_move_color();
    int count_stones = get_last_move_count_stones();
    int stones[BOARD_SIZE_MAX * BOARD_SIZE_MAX][2];

    if ( get_last_move_pass() ) {
        pop_move();

        return;
    }

    get_last_move_stones(stones);

    set_vertex( EMPTY, i, j );
    if ( count_stones > 0 ) {
        for ( k = 0; k < count_stones; k++ ) {
            set_vertex( color * -1, stones[k][0], stones[k][1] );
        }

        if ( color == BLACK ) {
            set_black_captured( get_black_captured() - count_stones );
        }
        else {
            set_white_captured( get_white_captured() - count_stones );
        }
    }

    pop_move();

    return;
}
Beispiel #2
0
void
Surface_mesh::
flip(Edge e)
{
    // CAUTION : Flipping a halfedge may result in
    // a non-manifold mesh, hence check for yourself
    // whether this operation is allowed or not!

    //let's make it sure it is actually checked
    assert(is_flip_ok(e));

    Halfedge a0 = halfedge(e, 0);
    Halfedge b0 = halfedge(e, 1);

    Halfedge a1 = next_halfedge(a0);
    Halfedge a2 = next_halfedge(a1);

    Halfedge b1 = next_halfedge(b0);
    Halfedge b2 = next_halfedge(b1);

    Vertex   va0 = to_vertex(a0);
    Vertex   va1 = to_vertex(a1);

    Vertex   vb0 = to_vertex(b0);
    Vertex   vb1 = to_vertex(b1);

    Face     fa  = face(a0);
    Face     fb  = face(b0);

    set_vertex(a0, va1);
    set_vertex(b0, vb1);

    set_next_halfedge(a0, a2);
    set_next_halfedge(a2, b1);
    set_next_halfedge(b1, a0);

    set_next_halfedge(b0, b2);
    set_next_halfedge(b2, a1);
    set_next_halfedge(a1, b0);

    set_face(a1, fb);
    set_face(b1, fa);

    set_halfedge(fa, a0);
    set_halfedge(fb, b0);

    if (halfedge(va0) == b0)
        set_halfedge(va0, a1);
    if (halfedge(vb0) == a0)
        set_halfedge(vb0, b1);
}
Beispiel #3
0
/**
 * @brief       Performs move
 *
 * Performs a move on the board and adds it to the move history.
 *
 * @param[in]   color   Color of stone to move
 * @param[in]   i       Horizontal coordinate of move
 * @param[in]   j       Vertical coordinate of move
 * @return      Nothing
 * @sa          undo_move()
 */
void make_move( int color, int i, int j )
{
    int nr_of_removed_stones;
    int group_nr;
    int nr_of_liberties;
    int group_size;
    int captured_now[BOARD_SIZE_MAX * BOARD_SIZE_MAX][2];

    // Check for pass:
    if ( i == INVALID && j == INVALID ) {
        create_next_move();
        set_move_pass(color);
        push_move();

        return;
    }

    set_vertex( color, i, j );
    scan_board_1();
    nr_of_removed_stones = remove_stones( color * -1 );
    if ( nr_of_removed_stones > 0 ) {
        scan_board_1();
    }

    nr_of_removed_stones = get_captured_now(captured_now);

    create_next_move();
    set_move_vertex( color, i, j );
    set_move_captured_stones(captured_now);

    group_nr        = get_worm_nr( i, j );
    nr_of_liberties = get_nr_of_liberties(group_nr);
    group_size      = get_size_of_worm(group_nr);

    // Check if this move is a ko:
    if ( nr_of_removed_stones == 1 && group_size == 1 && nr_of_liberties == 1 ) {
        // If only one stone has been captured it must be the first in the
        // captured_now list:
        set_move_ko( captured_now[0][0], captured_now[0][1] );
    }

    push_move();

    return;
}
	virtual void repaint()
	{
		if ( retry_count && !restore_objects() ) return;

		lpdev->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x000000ff, 1.0f, 0L );

		HRESULT rv = lpdev->BeginScene();

		if( SUCCEEDED( rv ) )
		{
			set_vertex( 0, 0, input_width, input_height, surface_width, surface_height, 0, 0, rcWindow.right, rcWindow.bottom );
			lpdev->SetTexture( 0, lptex );
			lpdev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
			lpdev->EndScene();

			if ( lpdev->Present( NULL, NULL, NULL, NULL ) == D3DERR_DEVICELOST ) retry_count = 60;
		}
		else retry_count = 60;

		ValidateRect( hWnd, & rcWindow );
	}
Beispiel #5
0
/**
 * @brief       Returnes list of valid moves for given color.
 *
 * This function takes a list of pseudo valid moves (as created by
 * get_pseudo_valid_move_list()) and drops the zero liberty moves. The
 * number of valid moves is returned.
 *
 * @param[in]   color               Color of moving side (BLACK|WHITE)
 * @param[out]  valid_moves         List of valid moves (zero liberty moves excluded)
 * @return      Number of valid moves
 * @sa          get_pseudo_valid_move_list()
 * @warning     The function get_pseudo_valid_move_list() must be called
 *              before get_valid_move_list().
 */
int get_valid_move_list( int color, int valid_moves[][4] )
{
    int  count;
    int  i, j;
    int  k, l;
    int  nr_of_removed_stones;
    int  captured_now[BOARD_SIZE_MAX * BOARD_SIZE_MAX][2];
    int  group_nr;
    int  nr_of_liberties;
    bool is_valid;
    int  temp_moves[BOARD_SIZE_MAX * BOARD_SIZE_MAX][4];
    int  value;
    int  valid_moves_count;
    int  atari_groups_player_before;
    int  atari_groups_opponent_before;
    int  atari_groups_player_after;
    int  atari_groups_opponent_after;
    //int  count_liberties_player_before;
    //int  count_liberties_opponent_before;
    //int  count_liberties_player_after;
    //int  count_liberties_opponent_after;

    int value_list[COUNT_BRAINS];

    //init_brains();

    valid_moves_count = get_pseudo_valid_move_list( color, valid_moves );

    for ( k = 0; k < BOARD_SIZE_MAX * BOARD_SIZE_MAX; k++ ) {
        temp_moves[k][0] = INVALID;     // i coordinate
        temp_moves[k][1] = INVALID;     // j coordinate
        temp_moves[k][2] = 0;           // Value of move
        temp_moves[k][3] = 0;           // Number of captured stones and atari ...
    }

    count = 0;
    for ( k = 0; k < valid_moves_count; k++ ) {
        is_valid = false;
        i = valid_moves[k][0];
        j = valid_moves[k][1];

        // Check for groups in atari before move is made:
        scan_board_1();
        atari_groups_player_before      = get_worm_count_atari(color);
        atari_groups_opponent_before    = get_worm_count_atari( color * -1 );
        //count_liberties_player_before   = get_group_count_liberties(color);
        //count_liberties_opponent_before = get_group_count_liberties( color * -1 );

        // Make move
        set_vertex( color, i, j );
        scan_board_1();
        nr_of_removed_stones = remove_stones( color * -1 );

        // Check if this move is valid:
        if ( nr_of_removed_stones > 0 ) {
            is_valid = true;
        }
        else {
            group_nr        = get_worm_nr( i, j );
            nr_of_liberties = get_nr_of_liberties(group_nr);
            if ( nr_of_liberties > 0 ) {
                is_valid = true;
            }
        }

        atari_groups_player_after   = get_worm_count_atari(color);
        atari_groups_opponent_after = get_worm_count_atari( color * -1 );
        // Check if move gives atari:
        if ( atari_groups_opponent_after > atari_groups_opponent_before ) {
            temp_moves[k][3]++;
        }
        // Check if move avoids atari:
        if ( atari_groups_player_after < atari_groups_player_before ) {
            temp_moves[k][3]++;
        }

        //count_liberties_player_after   = get_group_count_liberties(color);
        /*
        count_liberties_opponent_after = get_group_count_liberties( color * -1 );
        if ( count_liberties_opponent_after < count_liberties_opponent_before) {
            temp_moves[k][3]++;
        }
        */

        value = evaluate_position( value_list, false );

        // Undo move:
        nr_of_removed_stones = get_captured_now(captured_now);
        set_vertex( EMPTY, i, j );
        for ( l = 0; l < nr_of_removed_stones; l++ ) {
            set_vertex( color * -1, captured_now[l][0], captured_now[l][1] );
        }
        if ( color == BLACK ) {
            set_black_captured( get_black_captured() - nr_of_removed_stones );
        }
        else {
            set_white_captured( get_white_captured() - nr_of_removed_stones );
        }

        // Save only valid moves in temporary list:
        if ( is_valid ) {
            temp_moves[count][0] = i;
            temp_moves[count][1] = j;
            temp_moves[count][2] = value;
            temp_moves[count][3] += nr_of_removed_stones;
            count++;
        }
    }

    // Copy only valid moves into valid_moves list:
    for ( k = 0; k < count; k++ ) {
        valid_moves[k][0] = temp_moves[k][0];
        valid_moves[k][1] = temp_moves[k][1];
        valid_moves[k][2] = temp_moves[k][2];
        valid_moves[k][3] = temp_moves[k][3];
    }
    valid_moves[count][0] = INVALID;
    valid_moves[count][1] = INVALID;

    // Sort valid moves list by value
    if ( color == BLACK ) {
        qsort( valid_moves, (size_t)count, sizeof(valid_moves[0]), compare_value_black );
    }
    else {
        qsort( valid_moves, (size_t)count, sizeof(valid_moves[0]), compare_value_white );
    }

    return count;
}
Beispiel #6
0
  void refresh() {
    if(lost && !recover()) return;

    RECT rd, rs;  //dest, source rectangles
    GetClientRect(settings.handle, &rd);
    SetRect(&rs, 0, 0, settings.width, settings.height);

    //if output size changed, driver must be re-initialized.
    //failure to do so causes scaling issues on some video drivers.
    if(state.width != rd.right || state.height != rd.bottom) {
      init();
      set_shader(shader_source_markup);
      return;
    }

    if(caps.shader && effect) {
      device->BeginScene();
      set_vertex(0, 0, settings.width, settings.height, iwidth, iheight, 0, 0, rd.right, rd.bottom);

      D3DXVECTOR4 rubyTextureSize;
      rubyTextureSize.x = iwidth;
      rubyTextureSize.y = iheight;
      rubyTextureSize.z = 1.0 / iheight;
      rubyTextureSize.w = 1.0 / iwidth;
      effect->SetVector("rubyTextureSize", &rubyTextureSize);

      D3DXVECTOR4 rubyInputSize;
      rubyInputSize.x = settings.width;
      rubyInputSize.y = settings.height;
      rubyInputSize.z = 1.0 / settings.height;
      rubyInputSize.w = 1.0 / settings.width;
      effect->SetVector("rubyInputSize", &rubyInputSize);

      D3DXVECTOR4 rubyOutputSize;
      rubyOutputSize.x = rd.right;
      rubyOutputSize.y = rd.bottom;
      rubyOutputSize.z = 1.0 / rd.bottom;
      rubyOutputSize.w = 1.0 / rd.right;
      effect->SetVector("rubyOutputSize", &rubyOutputSize);

      UINT passes;
      effect->Begin(&passes, 0);
      effect->SetTexture("rubyTexture", texture);
      device->SetTexture(0, texture);
      for(unsigned pass = 0; pass < passes; pass++) {
        effect->BeginPass(pass);
        device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
        effect->EndPass();
      }
      effect->End();
      device->EndScene();
    } else {
      device->BeginScene();
      set_vertex(0, 0, settings.width, settings.height, iwidth, iheight, 0, 0, rd.right, rd.bottom);
      device->SetTexture(0, texture);
      device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
      device->EndScene();
    }

    if(settings.synchronize) {
      D3DRASTER_STATUS status;
      //wait for a previous vblank to finish, if necessary
      while(true) {
        device->GetRasterStatus(0, &status);
        if(status.InVBlank == false) break;
      }
      //wait for next vblank to begin
      while(true) {
        device->GetRasterStatus(0, &status);
        if(status.InVBlank == true) break;
      }
    }

    if(device->Present(0, 0, 0, 0) == D3DERR_DEVICELOST) lost = true;
  }
Beispiel #7
0
void
Surface_mesh::
split(Edge e, Vertex v)
{
    Halfedge h0 = halfedge(e, 0);
    Halfedge o0 = halfedge(e, 1);

    Vertex   v2 = to_vertex(o0);

    Halfedge e1 = new_edge(v, v2);
    Halfedge t1 = opposite_halfedge(e1);

    Face     f0 = face(h0);
    Face     f3 = face(o0);

    set_halfedge(v, h0);
    set_vertex(o0, v);

    if (!is_boundary(h0))
    {
        Halfedge h1 = next_halfedge(h0);
        Halfedge h2 = next_halfedge(h1);

        Vertex   v1 = to_vertex(h1);

        Halfedge e0 = new_edge(v, v1);
        Halfedge t0 = opposite_halfedge(e0);

        Face f1 = new_face();
        set_halfedge(f0, h0);
        set_halfedge(f1, h2);

        set_face(h1, f0);
        set_face(t0, f0);
        set_face(h0, f0);

        set_face(h2, f1);
        set_face(t1, f1);
        set_face(e0, f1);

        set_next_halfedge(h0, h1);
        set_next_halfedge(h1, t0);
        set_next_halfedge(t0, h0);

        set_next_halfedge(e0, h2);
        set_next_halfedge(h2, t1);
        set_next_halfedge(t1, e0);
    }
    else
    {
        set_next_halfedge(prev_halfedge(h0), t1);
        set_next_halfedge(t1, h0);
        // halfedge handle of _vh already is h0
    }


    if (!is_boundary(o0))
    {
        Halfedge o1 = next_halfedge(o0);
        Halfedge o2 = next_halfedge(o1);

        Vertex v3 = to_vertex(o1);

        Halfedge e2 = new_edge(v, v3);
        Halfedge t2 = opposite_halfedge(e2);

        Face f2 = new_face();
        set_halfedge(f2, o1);
        set_halfedge(f3, o0);

        set_face(o1, f2);
        set_face(t2, f2);
        set_face(e1, f2);

        set_face(o2, f3);
        set_face(o0, f3);
        set_face(e2, f3);

        set_next_halfedge(e1, o1);
        set_next_halfedge(o1, t2);
        set_next_halfedge(t2, e1);

        set_next_halfedge(o0, e2);
        set_next_halfedge(e2, o2);
        set_next_halfedge(o2, o0);
    }
    else
    {
        set_next_halfedge(e1, next_halfedge(o0));
        set_next_halfedge(o0, e1);
        set_halfedge(v, e1);
    }

    if (halfedge(v2) == h0)
        set_halfedge(v2, t1);
}
Beispiel #8
0
void
Surface_mesh::
garbage_collection()
{
    if (!garbage_) return;

    int  i, i0, i1,
    nV(vertices_size()),
    nE(edges_size()),
    nH(halfedges_size()),
    nF(faces_size());

    Vertex    v;
    Halfedge  h;
    Face      f;

    if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false);
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false);


    // setup handle mapping
    Vertex_property<Vertex>      vmap = add_vertex_property<Vertex>("v:garbage-collection");
    Halfedge_property<Halfedge>  hmap = add_halfedge_property<Halfedge>("h:garbage-collection");
    Face_property<Face>          fmap = add_face_property<Face>("f:garbage-collection");
    for (i=0; i<nV; ++i)
        vmap[Vertex(i)] = Vertex(i);
    for (i=0; i<nH; ++i)
        hmap[Halfedge(i)] = Halfedge(i);
    for (i=0; i<nF; ++i)
        fmap[Face(i)] = Face(i);



    // remove deleted vertices
    if (nV > 0)
    {
        i0=0;  i1=nV-1;

        while (1)
        {
            // find first deleted and last un-deleted
            while (!vdeleted_[Vertex(i0)] && i0 < i1)  ++i0;
            while ( vdeleted_[Vertex(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            vprops_.swap(i0, i1);

            //add
            for(unsigned int j = 0;j<map_2skel.size();j++)
            {
                if(map_2skel[j] == i0)
                    map_2skel[j] = i1;
                else if(map_2skel[j] == i1)
                    map_2skel[j] = i0;
            }
            //end
        };

        // remember new size
        nV = vdeleted_[Vertex(i0)] ? i0 : i0+1;
    }


    // remove deleted edges
    if (nE > 0)
    {
        i0=0;  i1=nE-1;

        while (1)
        {
            // find first deleted and last un-deleted
            while (!edeleted_[Edge(i0)] && i0 < i1)  ++i0;
            while ( edeleted_[Edge(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            eprops_.swap(i0, i1);
            hprops_.swap(2*i0,   2*i1);
            hprops_.swap(2*i0+1, 2*i1+1);
        };

        // remember new size
        nE = edeleted_[Edge(i0)] ? i0 : i0+1;
        nH = 2*nE;
    }


    // remove deleted faces
    if (nF > 0)
    {
        i0=0;  i1=nF-1;

        while (1)
        {
            // find 1st deleted and last un-deleted
            while (!fdeleted_[Face(i0)] && i0 < i1)  ++i0;
            while ( fdeleted_[Face(i1)] && i0 < i1)  --i1;
            if (i0 >= i1) break;

            // swap
            fprops_.swap(i0, i1);
        };

        // remember new size
        nF = fdeleted_[Face(i0)] ? i0 : i0+1;
    }


    // update vertex connectivity
    for (i=0; i<nV; ++i)
    {
        v = Vertex(i);
        if (!is_isolated(v))
            set_halfedge(v, hmap[halfedge(v)]);
    }


    // update halfedge connectivity
    for (i=0; i<nH; ++i)
    {
        h = Halfedge(i);
        set_vertex(h, vmap[to_vertex(h)]);
        set_next_halfedge(h, hmap[next_halfedge(h)]);
        if (!is_boundary(h))
            set_face(h, fmap[face(h)]);
    }


    // update handles of faces
    for (i=0; i<nF; ++i)
    {
        f = Face(i);
        set_halfedge(f, hmap[halfedge(f)]);
    }


    // remove handle maps
    remove_vertex_property(vmap);
    remove_halfedge_property(hmap);
    remove_face_property(fmap);


    // finally resize arrays
    vprops_.resize(nV); vprops_.free_memory();
    hprops_.resize(nH); hprops_.free_memory();
    eprops_.resize(nE); eprops_.free_memory();
    fprops_.resize(nF); fprops_.free_memory();

    deleted_vertices_ = deleted_edges_ = deleted_faces_ = 0;
    garbage_ = false;
}
Beispiel #9
0
void
Surface_mesh::
remove_edge(Halfedge h)
{
    Halfedge  hn = next_halfedge(h);
    Halfedge  hp = prev_halfedge(h);

    Halfedge  o  = opposite_halfedge(h);
    Halfedge  on = next_halfedge(o);
    Halfedge  op = prev_halfedge(o);

    Face      fh = face(h);
    Face      fo = face(o);

    Vertex    vh = to_vertex(h);
    Vertex    vo = to_vertex(o);



    // halfedge -> vertex
    Halfedge_around_vertex_circulator vh_it, vh_end;
    vh_it = vh_end = halfedges(vo);
    do
    {
        set_vertex(opposite_halfedge(vh_it), vh);
    }
    while (++vh_it != vh_end);


    // halfedge -> halfedge
    set_next_halfedge(hp, hn);
    set_next_halfedge(op, on);


    // face -> halfedge
    if (fh.is_valid())  set_halfedge(fh, hn);
    if (fo.is_valid())  set_halfedge(fo, on);


    // vertex -> halfedge
    if (halfedge(vh) == o)  set_halfedge(vh, hn);
    adjust_outgoing_halfedge(vh);
    set_halfedge(vo, Halfedge());


    // delete stuff
    if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false);
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    vdeleted_[vo]      = true; ++deleted_vertices_;
    edeleted_[edge(h)] = true; ++deleted_edges_;
    garbage_ = true;

    //add
    for(unsigned int j = 0;j < map_2skel.size();j++)
    {
        if(map_2skel[j] == vo.idx())
        {
            //unsigned int tem = map_2skel[j];
            map_2skel[j] = vh.idx();
            //qDebug("vertex:[%d],change %d to %d",j,tem,vh.idx());
        }
    }
    //end
}
Beispiel #10
0
void create_clouds() {
    weather = (Weather*)malloc(sizeof(Weather));

    //set a prevailaing wind direction.
    weather->x_prevailing_winds = 0.025f;
    weather->z_prevailing_winds = 0.035f;
    
    weather->initial_generation = MAXIMUM_CLOUDS;

    weather->cloud_count = 0;
    weather->clouds = (Cloud**)malloc(MAXIMUM_CLOUDS * sizeof(Cloud*));

    GLfloat *data = malloc(sizeof(GLfloat) * 6 * 9 * 6);

    float n = 1.0f;
    int index = 0;

    // -z
    set_vertex(data,-n,n,-n,0,0,-1,1.0,1.0,1.0, &index);
    set_vertex(data, n,n,-n,0,0,-1,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,-n,0,0,-1,1.0,1.0,1.0, &index);

    set_vertex(data, n,n,-n,0,0,-1,1.0,1.0,1.0, &index);
    set_vertex(data,n,-n,-n,0,0,-1,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,-n,0,0,-1,1.0,1.0,1.0, &index);

    // +z
    set_vertex(data,-n,n,n,0,0,1,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,n,0,0,1,1.0,1.0,1.0, &index);
    set_vertex(data, n,n,n,0,0,1,1.0,1.0,1.0, &index);

    set_vertex(data, n,n,n,0,0,1,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,n,0,0,1,1.0,1.0,1.0, &index);
    set_vertex(data,n,-n,n,0,0,1,1.0,1.0,1.0, &index);

    // +x
    set_vertex(data,n,n, n,1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,-n,-n,1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,n,-n,1,0,0,1.0,1.0,1.0, &index);

    set_vertex(data,n,-n,-n,1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,n, n,1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,-n,n,1,0,0,1.0,1.0,1.0, &index);

    // -x
    set_vertex(data,-n,n, n,-1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,n,-n,-1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,-n,-1,0,0,1.0,1.0,1.0, &index);

    set_vertex(data,-n,n, n,-1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,-n,-1,0,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,n,-1,0,0,1.0,1.0,1.0, &index);

    // +y
    set_vertex(data,-n,n,n,0,1,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,n, n,0,1,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,n,-n,0,1,0,1.0,1.0,1.0, &index);

    set_vertex(data,n,n, n,0,1,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,n,-n,0,1,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,n,-n,0,1,0,1.0,1.0,1.0, &index);

    // -y
    set_vertex(data,-n,-n,-n,0,-1,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,-n, -n,0,-1,0,1.0,1.0,1.0, &index);
    set_vertex(data,n,-n,n,0,-1,0,1.0,1.0,1.0, &index);

    set_vertex(data,n,-n, n,0,-1,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,n,0,-1,0,1.0,1.0,1.0, &index);
    set_vertex(data,-n,-n,-n,0,-1,0,1.0,1.0,1.0, &index);

    weather->cloud_vertex_buffer = gen_faces(9, 6, data);

}
Beispiel #11
0
void Mesh::set_vertex(int index, Vector3 vector){
    set_vertex(index, vector.x(), vector.y(), vector.z());
}
	void operator ()(VcacheMesh &vcache_mesh, submesh_id_t const &submesh_id, ProgressCallback & progress_callback, bool const reorder_vertices = true)
	{
		//////// prerequisites
		//////////////////////

		has_best_triangle = false;
		best_triangle = 0;

		optimized_tris.clear();
		lru_cache.clear();

		vtx_data.resize(get_num_vertices(vcache_mesh, submesh_id));
		tri_data.resize(get_num_triangles(vcache_mesh, submesh_id));

		// fetch the triangle data and put it in the internal vector
		// also fill the tri_indices_using vectors in the process
		{
			for (triangle_index_t tri_index = 0; tri_index < get_num_triangles(vcache_mesh, submesh_id); ++tri_index)
			{
				triangle_t triangle = get_triangle(vcache_mesh, submesh_id, tri_index);

				for (int i = 0; i < 3; ++i)
				{
					tri_data[tri_index].indices[i] = triangle[i];
					vtx_data[triangle[i]].tri_indices_using.insert(tri_index);
				}
			}
		}


		//////// optimize triangles
		///////////////////////////

		// calculate vertex and triangle scores
		{
			for (vertex_index_t vtx_index = 0; vtx_index < get_num_vertices(vcache_mesh, submesh_id); ++vtx_index)
			{
				vertex_data &vtx = vtx_data[vtx_index];
				vtx.score = find_vertex_score(vtx); // calculate the vertex score

				for (typename tri_indices_using_t::const_iterator tri_idx_iter = vtx.tri_indices_using.begin(); tri_idx_iter != vtx.tri_indices_using.end(); ++tri_idx_iter)
					tri_data[*tri_idx_iter].score += vtx.score; // add the vertex score to the triangles using this vertex
			}
		}

		// tell the progress callback the maximum progress value
		set_maximum_optimizing_triangles_progress(progress_callback, tri_data.size());

		/*
		the actual optimization step; reorder triangles by repeatedly finding a "best" triangle
		(= look at all the vertices in the LRU cache, and from all the triangles using these vertices,
		find the one with the highest score, remove this one from the vertices and put it in
		optimized_tris, and then find the next best triangle etc.)
		*/
		{
			size_t progress_counter = 0;
			while (optimized_tris.size() < tri_data.size())
			{
				push_best_triangle();
				++progress_counter;
				set_current_optimizing_triangles_progress(progress_callback, progress_counter);
			}
		}


		//////// reoder vertices
		////////////////////////

		if (reorder_vertices)
		{
			// even though *vertices* are reordered, reordering happens across *triangles*
			set_maximum_reordering_vertices_progress(progress_callback, tri_data.size());

			// get the vertices from the mesh
			std::vector < vertex_t > src_vertices;
			src_vertices.resize(vtx_data.size());
			for (vertex_index_t vtx_index = 0; vtx_index < vtx_data.size(); ++vtx_index)
				src_vertices[vtx_index] = get_vertex(vcache_mesh, submesh_id, vtx_index);

			// create and initialize the permutation sequence;
			// this sequence will be used for updating the triangle vertex indices later
			std::vector < std::pair < bool, vertex_index_t > > permutation;
			permutation.resize(vtx_data.size());
			std::fill(permutation.begin(), permutation.end(), std::pair < bool, vertex_index_t > (false, 0));

			/*
			reordering is done according to the order of access
			"access" refers to the triangles; for example, it makes no sense when the first
			triangle's vertices are at the end of the list of vertices, the second triangle's
			are in the middle etc.
			Instead, the first triangle's vertices should be at the beginning, the second triangle's
			should be right after these etc.
			*/
			size_t progress_counter = 0;
			vertex_index_t mesh_vertex_index = 0;
			for (triangle_index_t tri_index = 0; tri_index < optimized_tris.size(); ++tri_index)
			{
				triangle_data const &tri = tri_data[tri_index];

				// go through all 3 indices of each triangle,
				// and if it wasn't reordered, do so
				for (int i = 0; i < 3; ++i)
				{
					vertex_index_t vtx_index = tri.indices[i];
					if (!permutation[vtx_index].first) // first false -> was not reordered yet
					{
						// check for overflow; it should never happen, since
						// each vertex is reordered only once
						assert(mesh_vertex_index < src_vertices.size());

						// mark the vertex as reordered and store its new index
						permutation[vtx_index].first = true;
						permutation[vtx_index].second = mesh_vertex_index;

						// write the vertex at its new position in the mesh
						set_vertex(vcache_mesh, submesh_id, mesh_vertex_index, src_vertices[vtx_index]);
						++mesh_vertex_index;
					}
				}

				++progress_counter;
				set_current_reordering_vertices_progress(progress_callback, progress_counter);
			}

			// After the vertices have been reodered, the triangle vertex indices need to be updated
			for (triangle_index_t tri_index = 0; tri_index < optimized_tris.size(); ++tri_index)
			{
				triangle_data &tri = optimized_tris[tri_index];
				for (int i = 0; i < 3; ++i)
					tri.indices[i] = permutation[tri.indices[i]].second;
			}
		}

		// finally, store the contents of optimized_tris in the mesh
		{
			for (triangle_index_t tri_index = 0; tri_index < optimized_tris.size(); ++tri_index)
			{
				triangle_data const &tri = optimized_tris[tri_index];
				triangle_t new_triangle = create_new_triangle(
					vcache_mesh,
					tri.indices[0],
					tri.indices[1],
					tri.indices[2]
				);

				set_triangle(vcache_mesh, submesh_id, tri_index, new_triangle);
			}
		}
	}