📄 ivp_surbuild_q12.cxx
字号:
// 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 + -