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

📄 ivp_surbuild_ledge_soup.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 4 页
字号:

    IVP_IF(1){	/*printf("Compact surface size : %d\n", cs_size);*/    }
    
    this->compact_surface = (IVP_Compact_Surface *)ivp_malloc_aligned(cs_size*sizeof(char), 16);
    if ( this->compact_surface == 0 ) {
	return(0);
    }
    if ( number_of_ledges_compiled > 1 && !parameters->link_to_input_compact_ledges){
	if ( parameters->merge_points == IVP_SLMP_MERGE_AND_REALLOCATE ||
	    parameters->merge_points == IVP_SLMP_MERGE_NO_REALLOCATE){
	    int a = number_of_triangles_compiled; int b = 2;
	    while (a) { a = a>>1; b = b<<1; }
	    this->point_hash = new IVP_I_FPoint_VHash( b ); // very rough estimate
	    this->first_poly_point = (IVP_Compact_Poly_Point *) ( (char *)this->compact_surface + cs_header_size + 
	    number_of_triangles_compiled * sizeof(IVP_Compact_Triangle) + number_of_ledges_compiled * sizeof(IVP_Compact_Ledge));
	}
    }else{
	this->first_poly_point = NULL;
	this->point_hash = NULL;
    }

    n_poly_points_allocated  = 0;
    // now insert triangles (and maybe points
    {
        this->first_compact_ledge = (IVP_Compact_Ledge *)((char *)this->compact_surface + cs_header_size);
	this->insert_compact_ledges();
    }
    int cs_ledglelist_size;
    if ( this->point_hash ){
	P_DELETE ( this->point_hash );
	cs_ledglelist_size = number_of_triangles_compiled * sizeof(IVP_Compact_Triangle) + 
			     number_of_ledges_compiled * sizeof(IVP_Compact_Ledge) + 
			     n_poly_points_allocated * sizeof(IVP_Compact_Poly_Point);

    }else{
	cs_ledglelist_size = cs_estimated_ledglelist_size;
    }

     // set size values
    int cs_real_size = cs_header_size + cs_ledglelist_size + cs_ledgetree_size;
    this->compact_surface->byte_size = cs_real_size; // remember size of whole compact surface; useful for e.g. saving to disk
    this->compact_surface->offset_ledgetree_root = cs_header_size + cs_ledglelist_size;
    this->compact_surface->dummy[0] = 0; // otherwise RUI on SPARC
    this->compact_surface->dummy[1] = 0; // otherwise RUI on SPARC
    this->compact_surface->dummy[2] = 0; // otherwise RUI on SPARC

    // set pointer to first node in ledgetree array
    
   this->ledgetree_work =
	(IVP_Compact_Ledgetree_Node *)( (char *)this->compact_surface +   this->compact_surface->offset_ledgetree_root);
    IVP_IF(1) {
	this->clt_lowmem = (char *)this->ledgetree_work;
	this->clt_highmem = (char *)compact_surface + cs_real_size;
    }

    return(compact_surface);
}

int IVP_SurfaceBuilder_Ledge_Soup::recompile_point_indizes_of_compact_ledge(IVP_Compact_Ledge *ledge_source, char *dest){
    if ( !point_hash ){
	memcpy((void *)dest, ledge_source, ledge_source->get_size());
	return ledge_source->get_size();
    }
    IVP_Compact_Ledge *dl = (IVP_Compact_Ledge *)dest;
    int size = sizeof(IVP_Compact_Ledge) + sizeof(IVP_Compact_Triangle) * ledge_source->get_n_triangles();
    memcpy((void *)dest, ledge_source, size);

    IVP_Compact_Triangle *tri = dl->get_first_triangle();
    IVP_Compact_Poly_Point *source_ledge_points = ledge_source->get_point_array();

    for (int t = dl->get_n_triangles()-1; t>=0; t--){
	IVP_Compact_Edge *edge = tri->get_first_edge();
	for (int e = 0; e<3;e++){
	    int pi = edge->get_start_point_index();
	    IVP_Compact_Poly_Point *p_in = & source_ledge_points[pi];
	    IVP_Compact_Poly_Point *p_out = (IVP_Compact_Poly_Point *)point_hash->find_point( p_in);
	    if (p_out){
		edge->set_start_point_index( p_out - first_poly_point);
	    }else{
		edge->set_start_point_index( this->n_poly_points_allocated );
		p_out = &first_poly_point[n_poly_points_allocated++];
		*p_out = *p_in;
		point_hash->add_point( p_out );
	    }
	    edge++;
	}   

	tri = tri->get_next_tri();
    }
    dl->set_offset_ledge_points( (char *)first_poly_point - (char *)dl );
    return size;
}

/********************************************************************************
 *	Name:	     	insert_compact_ledges
 *	Description:	insert compact ledges into compact surface structure
 ********************************************************************************/
void IVP_SurfaceBuilder_Ledge_Soup::insert_compact_ledges(){
    char *dest = (char *)this->first_compact_ledge;

    if (parameters->link_to_input_compact_ledges == IVP_FALSE){
	for (int i=0; i<this->terminal_spheres.len(); i++) {
       	    IVV_Sphere *sphere = this->terminal_spheres.element_at(i);
	    IVP_Compact_Ledge *source = sphere->compact_ledge;

	    IVP_ASSERT((long(dest) & 0xf) == 0);

	    sphere->compact_ledge = (IVP_Compact_Ledge *)dest;	    
	    int ledge_size = recompile_point_indizes_of_compact_ledge(source,dest);
	    dest += ledge_size;

	    if (parameters->free_input_compact_ledges == IVP_TRUE){
		P_FREE_ALIGNED(source);
	    }
	}
    }
    for (int j=0; j<this->rec_spheres.len(); j++) {
       	IVV_Sphere *sphere = this->rec_spheres.element_at(j);
	IVP_Compact_Ledge *source = sphere->compact_ledge;

	IVP_ASSERT((long(dest) & 0xf) == 0);

	sphere->compact_ledge = (IVP_Compact_Ledge *)dest;
	
	int ledge_size = recompile_point_indizes_of_compact_ledge(source,dest);
	dest += ledge_size;

	P_FREE_ALIGNED(source);
    }    
    this->c_ledge_vec.clear();
    IVP_ASSERT( !first_poly_point || dest == (char *)this->first_poly_point );
    return;
}


/********************************************************************************
 *	Name:	     	build_ledgetree
 *	Description:	recursively builds the tree of ledges into allocated
 *			compact surface memory;
 *			initiating call by 'create_compact_ledgetree()'
 ********************************************************************************/
IVP_Compact_Ledgetree_Node *IVP_SurfaceBuilder_Ledge_Soup::build_ledgetree(IVV_Sphere *node) {

    IVP_Compact_Ledgetree_Node *current_node = this->ledgetree_work;

    IVP_ASSERT((int)current_node <  (int)this->clt_highmem); // ledgetree memory overwrite!
    IVP_ASSERT((int)current_node >= (int)this->clt_lowmem);  // ledgetree memory underwrite!
	
    this->ledgetree_work++;
    
    // fill in generic ledgetree_node data
    current_node->center.set(node->center.k);
    current_node->radius = (IVP_FLOAT)(node->radius);

    for (int x=0; x < IVP_CLT_N_DIRECTIONS; x++) {
	current_node->box_sizes[x] = node->box_sizes[x];
    }
    current_node->free_0 = 0;

    
    if ( node->child_1 ) {
	IVP_ASSERT(node->child_2);
	if ( node->compact_ledge){
	    current_node->offset_compact_ledge = (char *)(node->compact_ledge)-(char *)current_node;
	    node->compact_ledge->ledgetree_node_offset = (char *) current_node - (char *)node->compact_ledge;
	    node->compact_ledge->has_chilren_flag = IVP_TRUE;
	}else{
	    current_node->offset_compact_ledge = 0;
	}

	// process child nodes
	build_ledgetree(node->child_1);
	IVP_Compact_Ledgetree_Node *address_of_right_branch = build_ledgetree(node->child_2);
	
	// fill in specific internal ledgetree_node data
	current_node->offset_right_node = (char *)address_of_right_branch - (char *)current_node; // calulcate offset to right branch
    } else {
	IVP_ASSERT(!node->child_2);	
	node->compact_ledge->has_chilren_flag = IVP_FALSE;

	// fill in specific terminal ledgetree_node data
	current_node->offset_compact_ledge = (char *)node->compact_ledge - (char *)current_node; // calculate backward offset to compact ledge
	current_node->offset_right_node = 0;
    }    
    IVP_ASSERT(current_node->box_sizes[0]!=0);

    return(current_node);
}


/********************************************************************************
 *	Name:	     	ledgetree_debug_output
 *	Description:	DEBUGGING ONLY
 ********************************************************************************/
void IVP_SurfaceBuilder_Ledge_Soup::ledgetree_debug_output(const IVP_Compact_Ledgetree_Node *node) const
{
    // *** debugging START ******************************************************
    IVP_IF(1) {
	IVP_ASSERT((int)node < (int)this->clt_highmem); // ledgetree memory overread!
	IVP_ASSERT((int)node >= (int)this->clt_lowmem); // ledgetree memory underread!
    }
    
    //for (int x=0; x<ivp_debug_sf_indent; x++) {
    //    printf("  ");
    //}
    //node->center.print("center");
    //printf("Radius: %.6f\n", node->radius);
    if (node->offset_right_node==0) return;
    //ivp_debug_sf_indent++;
    //printf("%d\n", node->offset);
    if ( !node->is_terminal() ) {
	ledgetree_debug_output(node->left_son());
	ledgetree_debug_output(node->right_son());
    }
    //ivp_debug_sf_indent--;
    // *** debugging END ********************************************************
    return;
}


/********************************************************************************
 *	Name:	     	ledgetree_array_debug_output
 *	Description:	DEBUGGING ONLY
 ********************************************************************************/
void IVP_SurfaceBuilder_Ledge_Soup::ledgetree_array_debug_output() {

    // *** debugging START ******************************************************
    const IVP_Compact_Ledgetree_Node *node;
    const IVP_Compact_Ledgetree_Node *nodes = compact_surface->get_compact_ledge_tree_root();

    int i;
    for (i=0; i<this->number_of_nodes; i++) {
	node = &nodes[i];
	printf("Node %d (address: 0x%x / %d)\n", i, (int)node, (int)node);
	//node->center.print("     center ");
	printf("        radius %.6f)\n", node->radius);
	printf("         left branch offset: %d (address: 0x%x / %d)\n", sizeof(*node), (int)(node+1), (int)(node+1));
	printf("        right branch offset: %d (address: 0x%x / %d)\n", node->offset_right_node, (int)node+node->offset_right_node, (int)node+node->offset_right_node);
	printf("\n");
    }
    // *** debugging END ********************************************************
    return;
}


void IVP_SurfaceBuilder_Ledge_Soup::insert_radius_in_compact_surface() {

    IVP_U_Point mass_center;
    IVP_U_Point rotation_inertia;
    IVP_Rot_Inertia_Solver::calc_mass_center_and_rotation_inertia(this->compact_surface, &mass_center, &rotation_inertia);

    IVP_DOUBLE mass_radius, mass_radius_dev;
    IVP_CLS.calc_radius_to_given_center( this->compact_surface, &mass_center,
					 &mass_radius, &mass_radius_dev);

    this->compact_surface->rotation_inertia.set(rotation_inertia.k);
    this->compact_surface->mass_center.set(mass_center.k);
    this->compact_surface->upper_limit_radius = (IVP_FLOAT)mass_radius;
    IVP_ASSERT( mass_radius_dev >=0.0f);
    IVP_ASSERT( mass_radius_dev <= mass_radius + P_FLOAT_RES);
    this->compact_surface->max_factor_surface_deviation = int(1.0f + mass_radius_dev / (mass_radius * IVP_COMPACT_SURFACE_DEVIATION_STEP_SIZE));
}


/********************************************************************************
 *	Name:	     	create_compact_ledgetree
 *	Description:	creates tree of ledges
 ********************************************************************************/
IVP_RETURN_TYPE IVP_SurfaceBuilder_Ledge_Soup::create_compact_ledgetree() {

    IVV_Sphere *cluster_node = this->spheres_cluster[this->spheres_cluster[0].next].sphere;

    // *** debugging START ******************************************************
    IVP_IF(0) {
	ivp_debug_sf_indent=0;
	debug_sphere_output(this->spheres_cluster[this->spheres_cluster[0].next].sphere);
    }
    // *** debugging END ********************************************************
#ifdef DEBUG
    IVP_Compact_Ledgetree_Node *root =
#endif
	this->build_ledgetree(cluster_node);
    this->spheres_cluster[0].next = 0;
    IVP_ASSERT(this->compact_surface->get_compact_ledge_tree_root()==root);
    
    // *** debugging START ******************************************************
    IVP_IF(1) {
	//ivp_debug_sf_indent=0;
	ledgetree_debug_output(this->compact_surface->get_compact_ledge_tree_root());
	//ledgetree_array_debug_output();
    }
    // *** debugging END ********************************************************

    return(IVP_OK);
}

#if defined(LINUX) || defined(SUN) || (__MWERKS__ && POWERPC)
void IVP_SurfaceBuilder_Ledge_Soup::convert_ledges_to_templates(IVP_U_BigVector<IVP_Compact_Ledge> &ledges,
								IVP_U_Vector<IVP_Template_Polygon> *templates_out)
{

    int i;
    for (i=0; i<ledges.len(); i++) {
	IVP_Compact_Ledge *ledge = ledges.element_at(i);

	int n_points_for_ledge = ledge->get_n_points();

	// copy all points of ledge (i.e. all points of all triangles) into pointlist
	int j;
	IVP_U_Vector<IVP_U_Point> points;
	const IVP_Compact_Poly_Point *cpp_array = ledge->get_point_array();
	for (j=0; j<n_points_for_ledge; j++) {
	    IVP_U_Point *p = new IVP_U_Point();
	    p->k[0] = cpp_array[j].k[0];
	    p->k[1] = cpp_array[j].k[1];
	    p->k[2] = cpp_array[j].k[2];
	    points.add(p);
	    //p->print();
	}

	// process all triangles in ledge
	IVP_U_Vector<IVP_SurMan_PS_Plane> planes;
	int n_faces = ledge->get_n_triangles();
	const IVP_Compact_Triangle *tri = ledge->get_first_triangle();
	int k;
	for (k=0; k<n_faces; k++) {
	    
	    const IVP_Compact_Edge *edge = tri->get_first_edge();
	    IVP_SurMan_PS_Plane *plane = new IVP_SurMan_PS_Plane();
	    
	    IVP_CLS.calc_hesse_vec_object_not_normized(edge, ledge, plane);
	    plane->normize();
 	    planes.add(plane);

	    int m;
	    for (m=0; m<3; m++) {
		const IVP_Compact_Poly_Point *p = edge->get_start_point(ledge);
		int index;
		for (index=0; index<n_points_for_ledge; index++) {
		    if ( &cpp_array[index] == p ) break;
		}
		plane->points.add(points.element_at(index));
		edge = edge->get_prev();
	    }
	    
	    tri = tri->get_next_tri();
	}

	
	// --------------------------------------------------
	// convert convex points & planes to polygon template
	// --------------------------------------------------
	IVP_Template_Polygon *templ;
	templ = IVP_SurfaceBuilder_Pointsoup::planes_to_template(&points, &planes);
	templates_out->add(templ);

	// -----------------------
	// clean up temporary data
	// -----------------------
	for (j=0; j<points.len(); j++) {
	    IVP_U_Point *p = points.element_at(j);
	    P_DELETE(p);
	}
	for (j=0; j<planes.len(); j++) {
	    IVP_SurMan_PS_Plane *p = planes.element_at(j);
	    P_DELETE(p);
	}
    }

    // --------------------------------------------------
    // convert convex points & planes to polygon template
    // --------------------------------------------------
//    *template_out = IVP_SurfaceBuilder_Pointsoup::planes_to_template(&points, &planes);
    return;
}

#endif



⌨️ 快捷键说明

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