private void ParseInterAreaPortals(idLexer lexer) { lexer.ExpectTokenString("{"); _portalAreaCount = lexer.ParseInt(); if(_portalAreaCount < 0) { lexer.Error("ParseInterAreaPortals: bad portalAreaCount"); } _portalAreas = new PortalArea[_portalAreaCount]; _areaScreenRect = new idScreenRect[_portalAreaCount]; for(int i = 0; i < _portalAreaCount; i++) { _portalAreas[i] = new PortalArea(); _areaScreenRect[i] = new idScreenRect(); } // set the doubly linked lists SetupAreaReferences(); _interAreaPortalCount = lexer.ParseInt(); if(_interAreaPortalCount < 0) { lexer.Error("ParseInterAreaPortals: bad interAreaPortalCount"); } _doublePortals = new DoublePortal[_interAreaPortalCount]; for(int i = 0; i < _interAreaPortalCount; i++) { _doublePortals[i] = new DoublePortal(); int pointCount = lexer.ParseInt(); int a1 = lexer.ParseInt(); int a2 = lexer.ParseInt(); idWinding w = new idWinding(pointCount); for(int j = 0; j < pointCount; j++) { float[] tmp = lexer.Parse1DMatrix(3); w[j,0] = tmp[0]; w[j,1] = tmp[1]; w[j,2] = tmp[2]; // no texture coordinates w[j,3] = 0; w[j,4] = 0; } // add the portal to a1 Portal p = new Portal(); p.IntoArea = a2; p.DoublePortal = _doublePortals[i]; p.Winding = w; p.Plane = w.GetPlane(); p.Next = _portalAreas[a1].Portals; _portalAreas[a1].Portals = p; _doublePortals[i].Portals[0] = p; // reverse it for a2 p = new Portal(); p.IntoArea = a1; p.DoublePortal = _doublePortals[i]; p.Winding = w.Reverse(); p.Plane = w.GetPlane(); p.Next = _portalAreas[a2].Portals; _portalAreas[a2].Portals = p; _doublePortals[i].Portals[1] = p; } lexer.ExpectTokenString("}"); }
/// <summary> /// This is called by R_PushVolumeIntoTree and also directly /// for the world model references that are precalculated. /// </summary> /// <param name="def"></param> /// <param name="area"></param> private void AddEntityRefToArea(idRenderEntity def, PortalArea area) { if(def == null) { idConsole.Error("idRenderWorld::AddEntityRefToArea: null def"); } AreaReference areaRef = new AreaReference(); // TODO: counters tr.pc.c_entityReferences++; areaRef.Entity = def; // link to entityDef areaRef.NextOwner = def.EntityReference; def.EntityReference = areaRef; // link to end of area list areaRef.Area = area; areaRef.NextArea = area.EntityReference; areaRef.PreviousArea = area.EntityReference.PreviousArea; areaRef.NextArea.PreviousArea = areaRef; areaRef.PreviousArea.NextArea = areaRef; }
private void FloodConnectedAreas(PortalArea area, int portalAttributeIndex) { if(area.ConnectedAreaNumber[portalAttributeIndex] == _connectedAreaNumber) { return; } area.ConnectedAreaNumber[portalAttributeIndex] = _connectedAreaNumber; for(Portal p = area.Portals; p != null; p = p.Next) { if((p.DoublePortal.BlockingBits & ((PortalConnection) (1 << portalAttributeIndex))) == 0) { FloodConnectedAreas(_portalAreas[p.IntoArea], portalAttributeIndex); } } }