void MakeFlatPoly(BSP_FlatPoly &dst, pcs_polygon &src, std::unordered_map<vector3d, int> &norms, std::unordered_map<vector3d, int> &verts, BSP_DefPoints &dpnts) { dst.head.id = 2; dst.normal = src.norm; dst.nverts = src.verts.size(); dst.green = dst.blue = dst.pad = 0; dst.red = 0xFF; dst.verts.resize(dst.nverts); std::vector<vector3d> vertices; vertices.reserve(dst.nverts); for (unsigned int i = 0; i < (unsigned)dst.nverts; i++) { vertices.push_back(src.verts[i].point); dst.verts[i].vertnum = verts[src.verts[i].point]; dst.verts[i].normnum = norms[src.verts[i].norm]; } dst.center = src.centeroid; // recalculate these just for accracy dst.center = dst.MyCenter(vertices); dst.radius = dst.MyRadius(dst.center, vertices); // last thing dst.head.size = dst.MySize(); }
int PackTreeInBSP(bsp_tree_node* root, int offset, char *buffer, std::vector<pcs_polygon> &polygons, std::unordered_map<vector3d, int> &norms, std::unordered_map<vector3d, int> &verts, BSP_DefPoints &dpnts, vector3d geo_center, int buffsize, int &error_flags) { // ----------- error detection --------------- // abort if error detected if (error_flags != BSP_NOERRORS) return 0; // we're going to write off the end of the buffer gauranteed (smallest element is EOF - 8 bytes if (offset >= buffsize-7) { error_flags |= BSP_PACK_PREOVERFLOW; return 0; } // either we're written this node already, or it didn't get counted in size calculation.. this is bad, skip if (root != NULL && root->used == true) { error_flags |= BSP_PACK_DOUBLEUSE; return 0; } if (root != NULL && root->counted == false) { error_flags |= BSP_PACK_UNCOUNTED; return 0; } // ----------- finish error detection --------------- int size = 0; BSP_BlockHeader EndOfFile; EndOfFile.id = 0; EndOfFile.size = 0; BSP_BoundBox Bounding; Bounding.head.id = 5; Bounding.head.size = Bounding.MySize(); BSP_TmapPoly tpoly; BSP_FlatPoly fpoly; BSP_SortNorm snorm; if (root == NULL) { EndOfFile.Write(buffer+offset); return 8; } switch(root->Type) { case POLY: // write BBOX Bounding.max_point = root->bound_max; Bounding.min_point = root->bound_min; Bounding.Write(buffer+offset+size); size += Bounding.MySize(); if (offset+CalculateTreeSize(root, polygons) > buffsize) { error_flags |= BSP_PACK_PREPOLYOVERFLOW; return 0; } // Size is BBOX (32 bytes) + Poly (variable on type and count) + EOF ( 8 bytes) // write POLY for(unsigned int i = 0; i<root->poly_num.size(); i++){ if (polygons[root->poly_num[i]].texture_id == -1) { MakeFlatPoly(fpoly, polygons[root->poly_num[i]], norms, verts, dpnts); fpoly.Write(buffer+offset+size); size += fpoly.MySize(); } else { MakeTmapPoly(tpoly, polygons[root->poly_num[i]], norms, verts, dpnts); tpoly.Write(buffer+offset+size); size += tpoly.MySize(); } } // write EOF EndOfFile.Write(buffer+offset+size); size += EndOfFile.MySize(); root->used = true; if (offset+size > buffsize) { error_flags |= BSP_PACK_POLYOVERFLOW; } return size; default: //SPLIT size = 80; memset((char*)&snorm, 0, sizeof(BSP_SortNorm)); snorm.head.id = 4; snorm.head.size = snorm.MySize(); snorm.plane_point = root->point; snorm.plane_normal = root->normal; snorm.max_bounding_box_point = root->bound_max; snorm.min_bounding_box_point = root->bound_min; if (offset+CalculateTreeSize(root, polygons) > buffsize) { error_flags |= BSP_PACK_PRESPLITOVERFLOW; return 0; } snorm.prelist_offset = size; size += PackTreeInBSP(NULL, offset+size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags); snorm.postlist_offset = size; size += PackTreeInBSP(NULL, offset + size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags); snorm.online_offset = size; size += PackTreeInBSP(NULL, offset + size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags); snorm.front_offset = size; size += PackTreeInBSP(root->front.get(), offset+size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags); snorm.back_offset = size; size += PackTreeInBSP(root->back.get(), offset+size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags); snorm.Write(buffer+offset); // write a trailing BSP::EOF to make ourselves safe //EndOfFile.Write(buffer+offset+size); //size += EndOfFile.MySize(); root->used = true; if (offset+size > buffsize) { error_flags |= BSP_PACK_SPLITOVERFLOW; } return size; } return 0; }