示例#1
0
void gl_InitPortals()
{
	FPortalMap collection;

	if (numnodes == 0) return;

	for(int i=0;i<numnodes;i++)
	{
		node_t *no = &nodes[i];
		double fdx = (double)no->dx;
		double fdy = (double)no->dy;
		no->len = (float)sqrt(fdx * fdx + fdy * fdy);
	}

	CollectPortalSectors(collection);
	portals.Clear();

	FPortalMap::Iterator it(collection);
	FPortalMap::Pair *pair;
	int c = 0;
	int planeflags = 0;
	while (it.NextPair(pair))
	{
		for(unsigned i=0;i<pair->Value.Size(); i++)
		{
			if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1;
			else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2;
		}
		for (int i=1;i<=2;i<<=1)
		{
			// For now, add separate portals for floor and ceiling. They can be merged once
			// proper plane clipping is in.
			if (planeflags & i)
			{
				FPortal *portal = new FPortal;
				portal->xDisplacement = pair->Key.mXDisplacement;
				portal->yDisplacement = pair->Key.mYDisplacement;
				portal->plane = (i==1? sector_t::floor : sector_t::ceiling);	/**/
				portal->glportal = NULL;
				portals.Push(portal);
				for(unsigned j=0;j<pair->Value.Size(); j++)
				{
					sector_t *sec = pair->Value[j].mSub;
					int plane = pair->Value[j].mPlane;
					if (portal->plane == plane)
					{
						for(int k=0;k<sec->subsectorcount; k++)
						{
							subsector_t *sub = sec->subsectors[k];
							gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, portal);
						}
						sec->portals[plane] = portal;
					}
				}
			}
		}
	}
}
示例#2
0
void gl_InitPortals()
{
	FPortalMap collection;

	if (level.nodes.Size() == 0) return;

	
	CollectPortalSectors(collection);
	glSectorPortals.Clear();

	FPortalMap::Iterator it(collection);
	FPortalMap::Pair *pair;
	int c = 0;
	int planeflags = 0;
	while (it.NextPair(pair))
	{
		for(unsigned i=0;i<pair->Value.Size(); i++)
		{
			if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1;
			else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2;
		}
		for (int i=1;i<=2;i<<=1)
		{
			// add separate glSectorPortals for floor and ceiling.
			if (planeflags & i)
			{
				FPortal *portal = new FPortal;
				portal->mDisplacement = pair->Key.mDisplacement;
				portal->plane = (i==1? sector_t::floor : sector_t::ceiling);	/**/
				portal->glportal = NULL;
				glSectorPortals.Push(portal);
				for(unsigned j=0;j<pair->Value.Size(); j++)
				{
					sector_t *sec = pair->Value[j].mSub;
					int plane = pair->Value[j].mPlane;
					if (portal->plane == plane)
					{
						for(int k=0;k<sec->subsectorcount; k++)
						{
							subsector_t *sub = sec->subsectors[k];
							gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement);
						}
						sec->portals[plane] = portal;
					}
				}
			}
		}
	}

	// Now group the line glSectorPortals (each group must be a continuous set of colinear linedefs with no gaps)
	glLinePortals.Clear();
	linePortalToGL.Clear();
	TArray<int> tempindex;

	tempindex.Reserve(linePortals.Size());
	memset(&tempindex[0], -1, linePortals.Size() * sizeof(int));

	for (unsigned i = 0; i < linePortals.Size(); i++)
	{
		auto port = linePortals[i];
		bool gotsome;

		if (tempindex[i] == -1)
		{
			tempindex[i] = glLinePortals.Size();
			line_t *pSrcLine = linePortals[i].mOrigin;
			line_t *pLine = linePortals[i].mDestination;
			FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)];
			glport.lines.Push(&linePortals[i]);

			// We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time.
			if (linePortals[i].mType == PORTT_LINKED && pLine != nullptr)
			{
				glport.v1 = pLine->v1;
				glport.v2 = pLine->v2;
				do
				{
					// now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match
					gotsome = false;
					for (unsigned j = 0; j < linePortals.Size(); j++)
					{
						if (tempindex[j] == -1)
						{
							line_t *pSrcLine2 = linePortals[j].mOrigin;
							line_t *pLine2 = linePortals[j].mDestination;
							// angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.)
							unsigned srcang = pSrcLine->Delta().Angle().BAMs();
							unsigned dstang = pLine->Delta().Angle().BAMs();
							if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) ||
								(pSrcLine->v1 == pSrcLine2->v2 && pLine->v2 == pLine2->v1))
							{
								// The line connects, now check the translation
								unsigned srcang2 = pSrcLine2->Delta().Angle().BAMs();
								unsigned dstang2 = pLine2->Delta().Angle().BAMs();
								if (srcang == srcang2 && dstang == dstang2)
								{
									// The lines connect and  both source and destination are colinear, so this is a match
									gotsome = true;
									tempindex[j] = tempindex[i];
									if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1;
									else glport.v2 = pLine2->v2;
									glport.lines.Push(&linePortals[j]);
								}
							}
						}
					}
				} while (gotsome);
			}
		}
	}
	linePortalToGL.Resize(linePortals.Size());
	for (unsigned i = 0; i < linePortals.Size(); i++)
	{
		linePortalToGL[i] = &glLinePortals[tempindex[i]];
		/*
		Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n",
			int(linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.);
		*/
	}
}