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

📄 ivp_surbuild_q12.cxx

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

    // swap everything
    this->swap_bsp_data();

    IVP_IF(1) {
	printf("Number of models in bsp file: %d\n", n_models);
    }

    this->bsptree_loaded_from_disk = IVP_TRUE;

    return(n_models);

// ****
#else  // GEKKO
// ****

    return 0;
    
// ****
#endif // GEKKO
// ****

}

    
void IVP_SurfaceBuilder_Q12::init_q12bsp_from_memory(int version,
						     int n_models_in   , dmodel_t    *dmodels_in,
						     int n_planes_in   , dplane_t    *dplanes_in,
						     int n_nodes_in    , dnode_t     *dnodes_in,
						     int n_clipnodes_in, dclipnode_t *dclipnodes_in)
{
    IVP_IF(1) {
	if ( version > BSPVERSION ) {
	    printf("****** ERROR ******\nSupplied bsptree is version %i, not %i\n", version, BSPVERSION);
	}
    }

    this->n_models    = n_models_in;
    this->n_planes    = n_planes_in;
    this->n_nodes     = n_nodes_in;
    this->n_clipnodes = n_clipnodes_in;

    this->dmodels    = dmodels_in;
    this->dplanes    = dplanes_in;
    this->dnodes     = dnodes_in;
    this->dclipnodes = dclipnodes_in;

    this->bsptree_loaded_from_disk = IVP_FALSE;

    return;
}

    
void IVP_SurfaceBuilder_Q12::convert_model(int model)
{
    this->min_x = (IVP_FLOAT)(dmodels[model].mins[0]-(1.0f/this->scale)); // blow-up (1m) necessary to avoid 2-dimensional objects on the level's boundaries
    this->min_y = (IVP_FLOAT)(dmodels[model].mins[1]-(1.0f/this->scale));
    this->min_z = (IVP_FLOAT)(dmodels[model].mins[2]-(1.0f/this->scale));
    this->max_x = (IVP_FLOAT)(dmodels[model].maxs[0]+(1.0f/this->scale));
    this->max_y = (IVP_FLOAT)(dmodels[model].maxs[1]+(1.0f/this->scale));
    this->max_z = (IVP_FLOAT)(dmodels[model].maxs[2]+(1.0f/this->scale));

    this->n_solid_nodes = 0;
    this->n_converted_nodes = 0;

    this->convert_node(dmodels[model].headnode[0]);

    IVP_IF(1) {
	printf("\nBSP tree conversion statistics:\n");
	printf("  # of original solid nodes : %d\n", this->n_solid_nodes);
	printf("  # of converted nodes      : %d\n", this->n_converted_nodes);
	printf("  # of dropped nodes        : %d\n", this->n_solid_nodes-this->n_converted_nodes);
	printf("\n\n");
    }

    this->nodes.clear();
    return;
}


void IVP_SurfaceBuilder_Q12::convert_node(int node)
{
    this->nodes.add((int *)node);

    if ( dnodes[node].children[0] > 0 ) {
	this->convert_node(dnodes[node].children[0]);
    }else if ( dnodes[node].children[0] == -1 ) {
	this->convert_solid_node();
    }
    
    if ( dnodes[node].children[1] > 0 ) {
	this->convert_node(dnodes[node].children[1]);
    }else if ( dnodes[node].children[1] == -1 ) {
	this->convert_solid_node();
    }

    this->nodes.remove_at(this->nodes.len()-1);
    return;
}


#if 0 /* not used right now, but don't delete!*/
void IVP_SurfaceBuilder_Q12::convert_clipnode(int clipnode)
{
    this->nodes.add((int *)clipnode);

    if ( dclipnodes[clipnode].children[0] > 0 ) {
	this->convert_clipnode(dclipnodes[clipnode].children[0]);
    }
    else if ( dclipnodes[clipnode].children[0] == -2 ) {
	this->convert_solid_clipnode();
    }
    if ( dclipnodes[clipnode].children[1] > 0 ) {
	this->convert_clipnode(dclipnodes[clipnode].children[1]);
    }
    else if ( dclipnodes[clipnode].children[1] == -2 ) {
	this->convert_solid_clipnode();
    }

    this->nodes.delete_at(this->nodes.len()-1);
    return;
}
#endif


// -------------------------------------------------------------------------
// convert_solid_node
// ==================
//
// extract a solid node from bsp tree and convert it into a polygon template
// -------------------------------------------------------------------------
void IVP_SurfaceBuilder_Q12::convert_solid_node()
{
    this->n_solid_nodes++;

    // --------------------------------
    // extract all planes from bsp tree
    // --------------------------------
    this->nodes_to_planes();


    // ------------------------------------------------
    // insert boundary planes to avoid infinite volumes
    // ------------------------------------------------
    this->create_and_insert_plane( 1.0f,  0.0f,  0.0f,  this->min_x);
    this->create_and_insert_plane( 0.0f,  1.0f,  0.0f,  this->min_y);
    this->create_and_insert_plane( 0.0f,  0.0f,  1.0f,  this->min_z);
    this->create_and_insert_plane(-1.0f,  0.0f,  0.0f, -this->max_x);
    this->create_and_insert_plane( 0.0f, -1.0f,  0.0f, -this->max_y);
    this->create_and_insert_plane( 0.0f,  0.0f, -1.0f, -this->max_z);


    // ------------------------------------------
    // build convex hull from intersecting planes
    // ------------------------------------------
    IVP_Compact_Ledge *new_ledge;
    new_ledge = IVP_SurfaceBuilder_Halfspacesoup::convert_halfspacesoup_to_compact_ledge(this->halfspaces, this->pointmerge_threshold);
    if ( new_ledge ) {
	this->ledges->add(new_ledge);
	this->n_converted_nodes++;
    }
    this->cleanup();    
    this->halfspaces = new IVP_Halfspacesoup();

    return;
}


#if 0 /* not used right now, but don't delete!*/
// ----------------------------------------------------------------------------
// convert_solid_clipnode
// ======================
//
// extract a solid clipnode from bsp tree and convert it into a physical object
// ----------------------------------------------------------------------------
void IVP_SurfaceBuilder_Q12::convert_solid_clipnode()
{

    // [...]

    // --------------------------------
    // extract all planes from bsp tree
    // --------------------------------
    this->clipnodes_to_planes();

    // [...]

    return;
}
#endif


void IVP_SurfaceBuilder_Q12::nodes_to_planes()
{
    int i;
    
    for (i=0; i<this->nodes.len(); i++) {
	dplane_t *bsp_plane = &dplanes[dnodes[(int)nodes.element_at(i)].planenum];
	if ( i == this->nodes.len()-1 ) {
	    if ( dnodes[(int)this->nodes.element_at(i)].children[0] == -1 ) {
		create_and_insert_plane( bsp_plane->normal[0],  bsp_plane->normal[1],  bsp_plane->normal[2], bsp_plane->dist);
	    }
	    else {
		create_and_insert_plane(-bsp_plane->normal[0], -bsp_plane->normal[1], -bsp_plane->normal[2], -bsp_plane->dist);
	    }
	}
	else {
	    if ( dnodes[(int)this->nodes.element_at(i)].children[0] == (int)this->nodes.element_at(i+1) ) {
		create_and_insert_plane( bsp_plane->normal[0],  bsp_plane->normal[1],  bsp_plane->normal[2], bsp_plane->dist);
	    }
	    else {
		create_and_insert_plane(-bsp_plane->normal[0], -bsp_plane->normal[1], -bsp_plane->normal[2], -bsp_plane->dist);
	    }
	}
    }

    return;
}


#if 0 /* not used right now, but don't delete!*/
void IVP_SurfaceBuilder_Q12::clipnodes_to_planes()
{
    int i;
    
    for (i=0; i<this->nodes.len(); i++) {
	dplane_t *bsp_plane = &dplanes[dclipnodes[(int)nodes.element_at(i)].planenum];
	if ( i == this->nodes.len()-1 ) {
	    if ( dclipnodes[(int)this->nodes.element_at(i)].children[0] == -1 ) {
		create_and_insert_plane( bsp_plane->normal[0],  bsp_plane->normal[1],  bsp_plane->normal[2], bsp_plane->dist);
	    }
	    else {
		create_and_insert_plane(-bsp_plane->normal[0], -bsp_plane->normal[1], -bsp_plane->normal[2], -bsp_plane->dist);
	    }
	}
	else {
	    if ( dclipnodes[(int)this->nodes.element_at(i)].children[0] == (int)this->nodes.element_at(i+1) ) {
		create_and_insert_plane( bsp_plane->normal[0],  bsp_plane->normal[1],  bsp_plane->normal[2], bsp_plane->dist);
	    }
	    else {
		create_and_insert_plane(-bsp_plane->normal[0], -bsp_plane->normal[1], -bsp_plane->normal[2], -bsp_plane->dist);
	    }
	}
    }

    return;
}
#endif


// ------------------------------------------------------------------------
// create_and_insert_plane
// =======================
//
// create a plane and insert it into the planelist
// ------------------------------------------------------------------------
void IVP_SurfaceBuilder_Q12::create_and_insert_plane(IVP_FLOAT nx, IVP_FLOAT ny, IVP_FLOAT nz, IVP_FLOAT dist)
{
#ifdef CREATE_AND_INSERT_PLANE_DEBUG    
    printf("New ivp plane         : {x:%f, y:%f, z:%f}, %f\n", nx, -nz, ny, -dist);
    printf("  (original bsp plane : {x:%f, y:%f, z:%f}, %f)\n", nx, ny, nz, dist);
#endif    

    IVP_U_Hesse plane;
    plane.set(nx, -nz, ny);
    plane.hesse_val = -(dist+this->shrink_value) * this->scale; // scale to a basis of 1 unit = 1 meter

    halfspaces->add_halfspace( &plane );
    return;
}





void IVP_SurfaceBuilder_Q12::cleanup()
{
    // --------
    // clean up
    // --------
    P_DELETE( this->halfspaces );
    return;
}


void IVP_SurfaceBuilder_Q12::unload_q12bsp()
{
    if ( this->bsptree_loaded_from_disk ) {
	P_FREE(this->dmodels);
	P_FREE(this->dplanes);
	P_FREE(this->dnodes);
	P_FREE(this->dclipnodes);
	this->bsptree_loaded_from_disk = IVP_FALSE;
    }
    return;
}


IVP_SurfaceBuilder_Q12::IVP_SurfaceBuilder_Q12()
{
    this->dmodels = NULL;
    this->dplanes = NULL;
    this->dnodes = NULL;
    this->dclipnodes = NULL;
    this->scale = 1.0f;
    this->shrink_value = 0.0f;
    this->bsptree_loaded_from_disk = IVP_FALSE;
    this->halfspaces = new IVP_Halfspacesoup();

    this->zero = new IVP_q12_int(0);
    this->one = new IVP_q12_int(1);
    return;
}


IVP_SurfaceBuilder_Q12::~IVP_SurfaceBuilder_Q12()
{
    this->unload_q12bsp();
    P_DELETE(this->zero);
    P_DELETE(this->one);
    P_DELETE(this->halfspaces);
    return;
}


void IVP_SurfaceBuilder_Q12::convert_q12bsp_model_to_compact_ledges(int model,
								    IVP_DOUBLE scaling_factor,
								    IVP_DOUBLE shrink_value_in,
 								    IVP_FLOAT pointmerge_threshold_in,
								    IVP_U_Vector<IVP_Compact_Ledge> *ledges_out)
{
    if ( !this->dmodels ) return; // something went wrong while loading/initializing the bsp data. aborting...

    this->scale = (IVP_FLOAT)scaling_factor;
    this->ledges = ledges_out;
    this->shrink_value = (IVP_FLOAT)((1.0f/scaling_factor)*shrink_value_in);
    this->pointmerge_threshold = pointmerge_threshold_in;

    this->convert_model(model);

    return;
}


IVP_Compact_Surface *IVP_SurfaceBuilder_Q12::convert_q12bsp_model_to_single_compact_surface(int model,
											    IVP_DOUBLE scaling_factor,
											    IVP_DOUBLE shrink_value_in,
											    IVP_FLOAT pointmerge_threshold_in)
{
    int i;
    IVP_U_Vector<IVP_Compact_Ledge> ledges_local;

    IVP_SurfaceBuilder_Q12::convert_q12bsp_model_to_compact_ledges(model, scaling_factor, shrink_value_in, pointmerge_threshold_in, &ledges_local);

    IVP_SurfaceBuilder_Ledge_Soup ledge_soup;
    for (i=0; i<ledges_local.len(); i++) {
	ledge_soup.insert_ledge(ledges_local.element_at(i));
    }
    IVP_Compact_Surface *surface = ledge_soup.compile();

    return(surface);
}


⌨️ 快捷键说明

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