⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ivp_gridbuild_array.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 3 页
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.

#include <ivp_physics.hxx>
#if defined(LINUX)
#	include <memory.h>
#endif

#include <ivu_memory.hxx>

#ifndef WIN32
#	pragma implementation "ivp_gridbuild_array.hxx"
#endif

#include <ivp_compact_grid.hxx>
#include <ivp_gridbuild_array.hxx>

#include <ivp_cache_object.hxx>
#include <ivp_compact_ledge.hxx>
#include <ivp_compact_ledge_solver.hxx>


IVP_Template_Compact_Grid::IVP_Template_Compact_Grid(){
	P_MEM_CLEAR(this);
}

IVP_GridBuilder_Array::IVP_GridBuilder_Array(IVP_U_Memory *mm_, const IVP_Template_Compact_Grid *gp, IVP_FLOAT *height_field_)
{
    P_MEM_CLEAR(this);
    mm = mm_;
    this->height_field = height_field_;
    n_rows = gp->row_info.n_points;
    n_cols = gp->column_info.n_points;

    n_compact_poly_points_used = 0;
    height_points = (IVP_Compact_Poly_Point *)mm->get_mem(sizeof(IVP_Compact_Poly_Point) * n_rows * n_cols);
	unsigned int buffer_size=sizeof(IVP_Compact_Poly_Point) * n_rows * n_cols * 3;
    compact_poly_point_buffer = (IVP_Compact_Poly_Point *)mm->get_mem(buffer_size); // two extra points per square worst case
    ledge_reference_field = (IVP_Compact_Grid_Element *)mm->get_memc(sizeof(IVP_Compact_Grid_Element) * n_rows * n_cols); // last row and col not used

    grid_point_to_ledge_point_array = (int *) mm->get_mem(sizeof(int) * n_rows * n_cols);

    for (int j= n_rows * n_cols -1; j>=0;j--){
	grid_point_to_ledge_point_array[j] = -1;
    }
    
    IVP_U_Float_Point *dest = &this->height_points[0];
    IVP_FLOAT *source = &this->height_field[0];
    IVP_DOUBLE x = gp->position_origin_os.k[ gp->row_info.maps_to ];

    IVP_DOUBLE dx = (gp->row_info.invert_axis) ? -gp->grid_field_size:gp->grid_field_size;
    IVP_DOUBLE dy = (gp->column_info.invert_axis) ? -gp->grid_field_size:gp->grid_field_size;
    IVP_DOUBLE dz = (gp->height_invert_axis) ? -1.0f : 1.0f;
    for (int r=0; r<n_rows; r++) {
	IVP_DOUBLE y = gp->position_origin_os.k[ gp->column_info.maps_to ];
	for (int c=0; c<n_cols; c++) {
	    dest->k[ gp->row_info.maps_to ]    = (IVP_FLOAT)x;
	    dest->k[ gp->column_info.maps_to ] = (IVP_FLOAT)y;
	    dest->k[ gp->height_maps_to ]      = float(source[0] * dz);
	    source++;
	    dest++;
		IVP_ASSERT( ((int)dest & 15) == 0 );
	    y += dy;
	}
	x += dx;
    }
    templ = gp;	
}

int IVP_GridBuilder_Array::install_grid_point(int grid_point_index){
    int index = grid_point_to_ledge_point_array[grid_point_index];
    if (index >=0) return index;
    index = n_compact_poly_points_used++;	
    grid_point_to_ledge_point_array[grid_point_index] = index;
    compact_poly_point_buffer[ index ] = height_points[grid_point_index];
	IVP_IF(1) {
		IVP_Compact_Poly_Point *cpp=&compact_poly_point_buffer[ index ];
		int adress=(int)cpp;
		IVP_ASSERT( (adress & 15)==0 );
	}
    return index;
}

int IVP_GridBuilder_Array::install_point(const IVP_U_Float_Point *point){
    int index = n_compact_poly_points_used++;
	IVP_IF(1) {
		IVP_Compact_Poly_Point *cpp=&compact_poly_point_buffer[ index ];
		int adress=(int)cpp;
		IVP_ASSERT( (adress & 15)==0 );
	}
    compact_poly_point_buffer[ index ].set(point);
    compact_poly_point_buffer[index].hesse_val = 0.0f;
    return index;
}




IVP_GridBuilder_Array::~IVP_GridBuilder_Array(){
    //P_FREE(height_points);  // memory management system used
    //P_FREE(ledge_reference_field);

}


void IVP_GridBuilder_Array::add_triangle(int s_p0_off, int s_p1_off, int s_p2_off,
										 int opp0, int opp1, int opp2)
{
    int p0_off = c_point_to_point_index[s_p0_off];
    int p1_off = c_point_to_point_index[s_p1_off];
    int p2_off = c_point_to_point_index[s_p2_off];
    
    IVP_Compact_Triangle *tri = &((IVP_Compact_Triangle *)this->c_ledge)[this->triangle_count + 1];

    tri->set_tri_index(this->triangle_count++);

    tri->c_three_edges[0].set_start_point_index(p0_off);
    tri->c_three_edges[1].set_start_point_index(p1_off);
    tri->c_three_edges[2].set_start_point_index(p2_off);

    tri->c_three_edges[0].set_opposite_index(opp0);
    tri->c_three_edges[1].set_opposite_index(opp1);
    tri->c_three_edges[2].set_opposite_index(opp2);

    IVP_IF(1){
	// check for opposite and convexity consistency
	int opp[3];
	opp[0] = opp0;
	opp[1] = opp1;
	opp[2] = opp2;

	for(int e=0; e<3; e++){
	    const IVP_Compact_Edge *edge, *oppo;
	    edge = &tri->c_three_edges[e];
	    oppo = edge->get_opposite();

	    if((opp[e] < 0)&&(opp[e] > -1000) && (oppo->get_opposite_index() > -1000)){
		IVP_ASSERT(edge==oppo->get_opposite());

		// check for convexity
		IVP_U_Hesse hesse;
		IVP_U_Point p0, p1, p2;
		p0.set(edge->get_start_point(c_ledge));
		p1.set(edge->get_next()->get_start_point(c_ledge));
		p2.set(edge->get_prev()->get_start_point(c_ledge));

		hesse.calc_hesse(&p0, &p1, &p2);
		IVP_U_Point pp;
		pp.set(oppo->get_prev()->get_start_point(c_ledge));
		IVP_ASSERT(hesse.get_dist(&pp) >= -0.001f);//- P_RES_EPS);
	    }
	}
    }
}

void IVP_GridBuilder_Array::insert_opposite_index( const IVP_Compact_Edge *edge, int index){
    ((IVP_Compact_Edge *)edge)->set_opposite_index(index);
    
    IVP_IF(1){
	const IVP_Compact_Edge *oppo;
	oppo = edge->get_opposite();
	if (oppo->get_triangle() - c_ledge->get_first_triangle() >= triangle_count) return;	// not in list yet
//	if((index < 0)&&(index > -1000) && (oppo->get_opposite_index() > -1000)){
	    IVP_ASSERT(edge==oppo->get_opposite());

	    // check for convexity
	    IVP_U_Hesse hesse;
	    IVP_U_Point p0, p1, p2;
	    p0.set(edge->get_start_point(c_ledge));
	    p1.set(edge->get_next()->get_start_point(c_ledge));
	    p2.set(edge->get_prev()->get_start_point(c_ledge));

	    hesse.calc_hesse(&p0, &p1, &p2);
	    IVP_U_Point pp;
	    pp.set(oppo->get_prev()->get_start_point(c_ledge));
	    IVP_ASSERT(hesse.get_dist(&pp) >= -1e-12f);
//	}
    }
}


IVP_Compact_Ledge *IVP_GridBuilder_Array::convert_convex_triangle_to_compact_ledge( int strip_points[] ){

    int num_triangles = 2;
    //const int n_points = 3;
    triangle_count= 0;

    // get memory for Ledge Header, Triangles and Points
    int mem_size = 	sizeof(IVP_Compact_Ledge) +	num_triangles * sizeof(IVP_Compact_Triangle);

    this->c_ledge = (IVP_Compact_Ledge *)mm->get_memc( mem_size);
    IVP_ASSERT( (int(this->c_ledge) & 15) == 0);	// make sure it is aligned

    { // set point arrays
	// search the minimum point index and install points
	int min = IVP_GRID_MAX_ROWS * IVP_GRID_MAX_ROWS * 3;	// super high number
	int max = 0;
	for (int i=2;i>=0;i--){
	    int index = install_grid_point(strip_points[i]);
	    if (index < min) min = index;
	    if (index > max) max = index;
	    c_point_to_point_index[i] = index;
	}
	// shift start so min gets zero
	c_point_to_point_index[0] -= min;
	c_point_to_point_index[1] -= min;
	c_point_to_point_index[2] -= min;

	IVP_ASSERT(max - min + 1 < n_cols * 4 + 2 * n_cols);
	this->c_points = &compact_poly_point_buffer[min];

	c_ledge->set_offset_ledge_points( (int)((uchar *)c_points - (uchar *)c_ledge) ); // byte offset from 'this' to (ledge) point array
    }

    c_ledge->set_is_compact( IVP_FALSE);
    c_ledge->set_size(mem_size);	// <0 indicates a non compact compact ledge 
    c_ledge->n_triangles = num_triangles;
    c_ledge->has_chilren_flag = IVP_FALSE;

    // triangles
    this->add_triangle(0, 1, 2,   6, 4, 2);
    this->add_triangle(0, 2, 1,   -2, -4, -6);

    // pierce info
    IVP_Compact_Triangle *tri = c_ledge->get_first_triangle();
    tri->set_pierce_index(1);
    tri->get_next_tri()->set_pierce_index(0);

#ifdef DEBUG
	IVP_Compact_Ledge_Solver::check_ledge(c_ledge);
#endif

    return this->c_ledge;
}

IVP_Compact_Ledge *IVP_GridBuilder_Array::convert_convex_square_to_compact_ledge( int strip_points[], IVP_BOOL is_right_starter){

    int num_triangles = 4;
    const int n_points = 4;
    triangle_count= 0;

    // get memory for Ledge Header, Triangles and Points
    int mem_size = 	sizeof(IVP_Compact_Ledge) +	num_triangles * sizeof(IVP_Compact_Triangle);

    this->c_ledge = (IVP_Compact_Ledge *)mm->get_memc( mem_size);
    IVP_ASSERT( (int(this->c_ledge) & 15) == 0);	// make sure it is aligned

    { // set point arrays
	// search the minimum point index and install points
	int min = IVP_GRID_MAX_ROWS * IVP_GRID_MAX_ROWS * 3;	// super high number
	int max = 0;
	for (int i= n_points-1 ;i>=0;i--){
		int index = install_grid_point(strip_points[i]);
		if (index < min) min = index;
		if (index > max) max = index;
		c_point_to_point_index[i] = index;
	}
	// shift start so min gets zero
	c_point_to_point_index[0] -= min;
	c_point_to_point_index[1] -= min;
	c_point_to_point_index[2] -= min;
	c_point_to_point_index[3] -= min;

	IVP_ASSERT(max - min + 1 < n_cols * 4 + 2 * n_cols);
	this->c_points = &compact_poly_point_buffer[min];

	c_ledge->set_offset_ledge_points( (int)((uchar *)c_points - (uchar *)c_ledge) ); // byte offset from 'this' to (ledge) point array
    }
    c_ledge->set_is_compact( IVP_FALSE);
    c_ledge->set_size(mem_size);	
    c_ledge->n_triangles = num_triangles;
    c_ledge->has_chilren_flag = IVP_FALSE;


    // triangles
    int p1 = 1;
    int p2 = 2;
    if ( is_right_starter ){	// swap points 1 and 2
	p1 = 2;
	p2 = 1;
    }

    this->add_triangle(p2, p1, 0,   4, 8, 12);
    this->add_triangle(p1, p2, 3,   -4, 8, 4);
    this->add_triangle( 3, 0, p1,   4, -8, -4);
    this->add_triangle( 0, 3, p2,   -4, -8, -12);

    // pierce info
    IVP_Compact_Triangle *tri;
    tri = c_ledge->get_first_triangle();		tri->set_pierce_index(2);
    tri = tri->get_next_tri();					tri->set_pierce_index(2);
    tri = tri->get_next_tri();					tri->set_pierce_index(0);
    tri = tri->get_next_tri();					tri->set_pierce_index(0);

#ifdef DEBUG
	IVP_Compact_Ledge_Solver::check_ledge(c_ledge);
#endif

    return this->c_ledge;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -