void FNodeBuilder::Extract (FLevelLocals &level) { int i; auto &outVerts = level.vertexes; int vertCount = Vertices.Size (); outVerts.Alloc(vertCount); for (i = 0; i < vertCount; ++i) { outVerts[i].set(Vertices[i].x, Vertices[i].y); } auto &outSubs = level.subsectors; auto subCount = Subsectors.Size(); outSubs.Alloc(subCount); memset(&outSubs[0], 0, subCount * sizeof(subsector_t)); auto &outNodes = level.nodes; auto nodeCount = Nodes.Size (); outNodes.Alloc(nodeCount); memcpy (&outNodes[0], &Nodes[0], nodeCount*sizeof(node_t)); for (unsigned i = 0; i < nodeCount; ++i) { D(Printf(PRINT_LOG, "Node %d: Splitter[%08x,%08x] [%08x,%08x]\n", i, outNodes[i].x, outNodes[i].y, outNodes[i].dx, outNodes[i].dy)); // Go backwards because on 64-bit systems, both of the intchildren are // inside the first in-game child. for (int j = 1; j >= 0; --j) { if (outNodes[i].intchildren[j] & 0x80000000) { D(Printf(PRINT_LOG, " subsector %d\n", outNodes[i].intchildren[j] & 0x7FFFFFFF)); outNodes[i].children[j] = (uint8_t *)(&outSubs[(outNodes[i].intchildren[j] & 0x7fffffff)]) + 1; } else { D(Printf(PRINT_LOG, " node %d\n", outNodes[i].intchildren[j])); outNodes[i].children[j] = &outNodes[outNodes[i].intchildren[j]]; } } for (int j = 0; j < 2; ++j) { for (int k = 0; k < 4; ++k) { outNodes[i].bbox[j][k] = FIXED2FLOAT(outNodes[i].nb_bbox[j][k]); } } } auto &outSegs = level.segs; if (GLNodes) { TArray<glseg_t> segs (Segs.Size()*5/4); for (unsigned i = 0; i < subCount; ++i) { uint32_t numsegs = CloseSubsector (segs, i, &outVerts[0]); outSubs[i].numlines = numsegs; outSubs[i].firstline = (seg_t *)(size_t)(segs.Size() - numsegs); } auto segCount = segs.Size (); outSegs.Alloc(segCount); for (unsigned i = 0; i < segCount; ++i) { outSegs[i] = *(seg_t *)&segs[i]; if (segs[i].Partner != DWORD_MAX) { const uint32_t storedseg = Segs[segs[i].Partner].storedseg; outSegs[i].PartnerSeg = DWORD_MAX == storedseg ? nullptr : &outSegs[storedseg]; } else { outSegs[i].PartnerSeg = nullptr; } } } else { memcpy (&outSubs[0], &Subsectors[0], subCount*sizeof(subsector_t)); auto segCount = Segs.Size (); outSegs.Alloc(segCount); for (unsigned i = 0; i < segCount; ++i) { const FPrivSeg *org = &Segs[SegList[i].SegNum]; seg_t *out = &outSegs[i]; D(Printf(PRINT_LOG, "Seg %d: v1(%d) -> v2(%d)\n", i, org->v1, org->v2)); out->v1 = &outVerts[org->v1]; out->v2 = &outVerts[org->v2]; out->backsector = org->backsector; out->frontsector = org->frontsector; out->linedef = Level.Lines + org->linedef; out->sidedef = Level.Sides + org->sidedef; out->PartnerSeg = nullptr; } } for (unsigned i = 0; i < subCount; ++i) { outSubs[i].firstline = &outSegs[(size_t)outSubs[i].firstline]; } D(Printf("%i segs, %i nodes, %i subsectors\n", segCount, nodeCount, subCount)); for (i = 0; i < Level.NumLines; ++i) { Level.Lines[i].v1 = &outVerts[(size_t)Level.Lines[i].v1]; Level.Lines[i].v2 = &outVerts[(size_t)Level.Lines[i].v2]; } }
void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, seg_t *&outSegs, int &segCount, subsector_t *&outSubs, int &subCount, vertex_t *&outVerts, int &vertCount) { int i; vertCount = Vertices.Size (); outVerts = new vertex_t[vertCount]; for (i = 0; i < vertCount; ++i) { outVerts[i].x = Vertices[i].x; outVerts[i].y = Vertices[i].y; } subCount = Subsectors.Size(); outSubs = new subsector_t[subCount]; nodeCount = Nodes.Size (); outNodes = new node_t[nodeCount]; memcpy (outNodes, &Nodes[0], nodeCount*sizeof(node_t)); for (i = 0; i < nodeCount; ++i) { for (int j = 0; j < 2; ++j) { if (outNodes[i].intchildren[j] & 0x80000000) { outNodes[i].children[j] = (BYTE *)(outSubs + (outNodes[i].intchildren[j] & 0x7fffffff)) + 1; } else { outNodes[i].children[j] = outNodes + outNodes[i].intchildren[j]; } } } if (GLNodes) { TArray<seg_t> segs (Segs.Size()*5/4); for (i = 0; i < subCount; ++i) { DWORD numsegs = CloseSubsector (segs, i, outVerts); outSubs[i].numlines = numsegs; outSubs[i].firstline = segs.Size() - numsegs; outSubs[i].poly = NULL; } segCount = segs.Size (); outSegs = new seg_t[segCount]; memcpy (outSegs, &segs[0], segCount*sizeof(seg_t)); for (i = 0; i < segCount; ++i) { if (outSegs[i].PartnerSeg != NULL) { outSegs[i].PartnerSeg = &outSegs[Segs[(unsigned int)(size_t)outSegs[i].PartnerSeg-1].storedseg]; } } } else { memcpy (outSubs, &Subsectors[0], subCount*sizeof(subsector_t)); segCount = Segs.Size (); outSegs = new seg_t[segCount]; for (i = 0; i < segCount; ++i) { const FPrivSeg *org = &Segs[SegList[i].SegNum]; seg_t *out = &outSegs[i]; out->v1 = outVerts + org->v1; out->v2 = outVerts + org->v2; out->backsector = org->backsector; out->frontsector = org->frontsector; out->linedef = Level.Lines + org->linedef; out->sidedef = Level.Sides + org->sidedef; out->PartnerSeg = NULL; out->bPolySeg = false; } } //Printf ("%i segs, %i nodes, %i subsectors\n", segCount, nodeCount, subCount); for (i = 0; i < Level.NumLines; ++i) { Level.Lines[i].v1 = outVerts + (size_t)Level.Lines[i].v1; Level.Lines[i].v2 = outVerts + (size_t)Level.Lines[i].v2; } }
void FNodeBuilder::ExtractMini (FMiniBSP *bsp) { unsigned int i; bsp->bDirty = false; bsp->Verts.Resize(Vertices.Size()); for (i = 0; i < Vertices.Size(); ++i) { bsp->Verts[i].set(Vertices[i].x, Vertices[i].y); } bsp->Subsectors.Resize(Subsectors.Size()); memset(&bsp->Subsectors[0], 0, Subsectors.Size() * sizeof(subsector_t)); bsp->Nodes.Resize(Nodes.Size()); memcpy(&bsp->Nodes[0], &Nodes[0], Nodes.Size()*sizeof(node_t)); for (i = 0; i < Nodes.Size(); ++i) { D(Printf(PRINT_LOG, "Node %d:\n", i)); // Go backwards because on 64-bit systems, both of the intchildren are // inside the first in-game child. for (int j = 1; j >= 0; --j) { if (bsp->Nodes[i].intchildren[j] & 0x80000000) { D(Printf(PRINT_LOG, " subsector %d\n", bsp->Nodes[i].intchildren[j] & 0x7FFFFFFF)); bsp->Nodes[i].children[j] = (uint8_t *)&bsp->Subsectors[bsp->Nodes[i].intchildren[j] & 0x7fffffff] + 1; } else { D(Printf(PRINT_LOG, " node %d\n", bsp->Nodes[i].intchildren[j])); bsp->Nodes[i].children[j] = &bsp->Nodes[bsp->Nodes[i].intchildren[j]]; } } for (int j = 0; j < 2; ++j) { for (int k = 0; k < 4; ++k) { bsp->Nodes[i].bbox[j][k] = FIXED2FLOAT(bsp->Nodes[i].nb_bbox[j][k]); } } } if (GLNodes) { TArray<glseg_t> glsegs; for (i = 0; i < Subsectors.Size(); ++i) { uint32_t numsegs = CloseSubsector (glsegs, i, &bsp->Verts[0]); bsp->Subsectors[i].numlines = numsegs; bsp->Subsectors[i].firstline = &bsp->Segs[bsp->Segs.Size() - numsegs]; } bsp->Segs.Resize(glsegs.Size()); for (i = 0; i < glsegs.Size(); ++i) { bsp->Segs[i] = *(seg_t *)&glsegs[i]; } } else { memcpy(&bsp->Subsectors[0], &Subsectors[0], Subsectors.Size()*sizeof(subsector_t)); bsp->Segs.Resize(Segs.Size()); for (i = 0; i < Segs.Size(); ++i) { const FPrivSeg *org = &Segs[SegList[i].SegNum]; seg_t *out = &bsp->Segs[i]; D(Printf(PRINT_LOG, "Seg %d: v1(%d) -> v2(%d)\n", i, org->v1, org->v2)); out->v1 = &bsp->Verts[org->v1]; out->v2 = &bsp->Verts[org->v2]; out->backsector = org->backsector; out->frontsector = org->frontsector; if (org->sidedef != int(NO_SIDE)) { out->linedef = Level.Lines + org->linedef; out->sidedef = Level.Sides + org->sidedef; } else // part of a miniseg { out->linedef = NULL; out->sidedef = NULL; } } for (i = 0; i < bsp->Subsectors.Size(); ++i) { bsp->Subsectors[i].firstline = &bsp->Segs[(size_t)bsp->Subsectors[i].firstline]; } } }