/* * ============== * R_RemoveEdges * ============== */ static void R_RemoveEdges(edge_t pedge) { do { pedge.next.prev = pedge.prev; pedge.prev.next = pedge.next; } while ((pedge = pedge.nextremove) != null); }
static void Main(string[] args) { edge_t[] edges = new edge_t[100]; int NV; // Количество вершин в графе int NE; // Количество ребер в графе int i; if (File.Exists(path)) //если файл с данными существует { readLine = File.ReadAllLines(path); consoleInput = false; //будем читать с файла } else { consoleInput = true; //будем читать с клавиатуры } Console.WriteLine("Введите количество вершин и ребер: "); NV = Convert.ToInt32(consoleInput ? Console.ReadLine() : ReadFromFile(0)); NE = Convert.ToInt32(consoleInput ? Console.ReadLine() : ReadFromFile(1)); for (i = 0; i < NV; i++) { nodes[i] = -1 - i; //присваиваем уникальный цвет для каждой вершины } Console.WriteLine("Введите матрицу: Начало, Конец, Вес "); for (i = 0; i < NE; i++) { string[] OutS = (consoleInput ? Console.ReadLine() : ReadFromFile(2 + i)).Split(' '); //массив вершин и веса ребра между ними edges[i].x = Convert.ToInt32(OutS[0]); //вершина "начало" edges[i].y = Convert.ToInt32(OutS[1]); //вершина "конец" edges[i].w = Convert.ToInt32(OutS[2]); //вес ребра между вершинами "начало" и "конец" } Console.WriteLine("Минимальный остов: "); var sVes = from h in edges orderby h.w select h; //сортируем ребра по весу (ро возрастанию) foreach (var s in sVes) //для каждого ребра { int c = getColor(s.y); //сохраняем цвет с номером ребра "конец" if (getColor(s.x) != c) { // Если ребро соединяет вершины различных цветов-мы его добавляем // и перекрашиваем вершину в last_n nodes[last_n] = s.y; Console.WriteLine(s.x + " =>> " + s.y + " с весом:" + s.w); //вывод строки } } Console.ReadLine(); }
public static void BubbleSort() { for (int i = edges.Length - 1; i >= 0; i--) { for (int j = 0; j < i; j++) { if (edges[j].len < edges[j + 1].len) { edge_t temp = edges[j]; edges[j] = edges[j + 1]; edges[j + 1] = temp; } } } }
static void Main(string[] args) { edge_t[] edges = new edge_t[100]; int NV; // Количество вершин в графе int NE; // Количество ребер в графе int i; Random ran = new Random(); Console.WriteLine("Введите количество вершин: "); NV = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Введите количество ребер: "); NE = Convert.ToInt32(Console.ReadLine()); for (i = 0; i < NV; i++) { nodes[i] = -1 - i; } Console.WriteLine("Введите матрицу: "); for (i = 0; i < NE; i++) { edges[i].x = Convert.ToInt32(ran.Next(10)); Console.Write(edges[i].x); edges[i].y = Convert.ToInt32(ran.Next(10)); Console.Write(edges[i].y); edges[i].w = Convert.ToInt32(ran.Next(10)); Console.Write(edges[i].w); } Console.WriteLine("\nОстовный граф: "); var sVes = from h in edges orderby h.w select h; foreach (var s in sVes) { for (i = 0; i < NE; i++) { // пока не прошли все ребра int c = getColor(s.y); if (getColor(s.x) != c) { // Если ребро соединяет вершины различных цветов-мы его добавляем // и перекрашиваем вершины nodes[last_n] = s.y; Console.Write(s.x + " " + s.y + " " + s.w + " "); } } } Console.ReadLine(); }
/* * ============== * R_InsertNewEdges * * Adds the edges in the linked list edgestoadd, adding them to the edges in the * linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a * sentinel at the end (actually, this is the active edge table starting at * edge_head.next). * ============== */ static void R_InsertNewEdges(edge_t edgestoadd, edge_t edgelist) { edge_t next_edge; do { next_edge = edgestoadd.next; edgesearch: if (edgelist.u >= edgestoadd.u) { goto addedge; } edgelist = edgelist.next; if (edgelist.u >= edgestoadd.u) { goto addedge; } edgelist = edgelist.next; if (edgelist.u >= edgestoadd.u) { goto addedge; } edgelist = edgelist.next; if (edgelist.u >= edgestoadd.u) { goto addedge; } edgelist = edgelist.next; goto edgesearch; // insert edgestoadd before edgelist addedge: edgestoadd.next = edgelist; edgestoadd.prev = edgelist.prev; edgelist.prev.next = edgestoadd; edgelist.prev = edgestoadd; } while ((edgestoadd = next_edge) != null); }
/* * ============== * R_TrailingEdge * ============== */ static void R_TrailingEdge(surf_t surf, edge_t edge) { espan_t span; int iu; // don't generate a span if this is an inverted span, with the end // edge preceding the start edge (that is, we haven't seen the // start edge yet) if (--surf.spanstate == 0) { if (surf.insubmodel) { r_bmodelactive--; } if (surf == surfaces[0].next) { // emit a span (current top going away) iu = edge.u >> 20; if (iu > surf.last_u) { span = basespans[span_p++]; span.u = surf.last_u; span.count = iu - span.u; span.v = current_iv; span.pnext = surf.spans; surf.spans = span; } // set last_u on the surface below surf.next.last_u = iu; } surf.prev.next = surf.next; surf.next.prev = surf.prev; } }
/* ============== R_LeadingEdge ============== */ static void R_LeadingEdge(edge_t edge) { espan_t span; surf_t surf, surf2; int iu; double fu, newzi, testzi, newzitop, newzibottom; if (edge.surfs[1] != 0) { // it's adding a new surface in, so find the correct place surf = surfaces[edge.surfs[1] - 1]; // don't start a span if this is an inverted span, with the end // edge preceding the start edge (that is, we've already seen the // end edge) if (++surf.spanstate == 1) { if (surf.insubmodel) r_bmodelactive++; surf2 = surfaces[0].next; if (surf.key < surf2.key) goto newtop; // if it's two surfaces on the same plane, the one that's already // active is in front, so keep going unless it's a bmodel if (surf.insubmodel && (surf.key == surf2.key)) { // must be two bmodels in the same leaf; sort on 1/z fu = (double)(edge.u - 0xFFFFF) * (1.0 / 0x100000); newzi = surf.d_ziorigin + fv*surf.d_zistepv + fu*surf.d_zistepu; newzibottom = newzi * 0.99; testzi = surf2.d_ziorigin + fv*surf2.d_zistepv + fu*surf2.d_zistepu; if (newzibottom >= testzi) { goto newtop; } newzitop = newzi * 1.01; if (newzitop >= testzi) { if (surf.d_zistepu >= surf2.d_zistepu) { goto newtop; } } } continue_search: do { surf2 = surf2.next; } while (surf.key > surf2.key); if (surf.key == surf2.key) { // if it's two surfaces on the same plane, the one that's already // active is in front, so keep going unless it's a bmodel if (!surf.insubmodel) goto continue_search; // must be two bmodels in the same leaf; sort on 1/z fu = (double)(edge.u - 0xFFFFF) * (1.0 / 0x100000); newzi = surf.d_ziorigin + fv*surf.d_zistepv + fu*surf.d_zistepu; newzibottom = newzi * 0.99; testzi = surf2.d_ziorigin + fv*surf2.d_zistepv + fu*surf2.d_zistepu; if (newzibottom >= testzi) { goto gotposition; } newzitop = newzi * 1.01; if (newzitop >= testzi) { if (surf.d_zistepu >= surf2.d_zistepu) { goto gotposition; } } goto continue_search; } goto gotposition; newtop: // emit a span (obscures current top) iu = edge.u >> 20; if (iu > surf2.last_u) { span = basespans[span_p++]; span.u = surf2.last_u; span.count = iu - span.u; span.v = current_iv; span.pnext = surf2.spans; surf2.spans = span; } // set last_u on the new span surf.last_u = iu; gotposition: // insert before surf2 surf.next = surf2; surf.prev = surf2.prev; surf2.prev.next = surf; surf2.prev = surf; } } }
/* ============== R_InsertNewEdges Adds the edges in the linked list edgestoadd, adding them to the edges in the linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a sentinel at the end (actually, this is the active edge table starting at edge_head.next). ============== */ static void R_InsertNewEdges(edge_t edgestoadd, edge_t edgelist) { edge_t next_edge; do { next_edge = edgestoadd.next; edgesearch: if (edgelist.u >= edgestoadd.u) goto addedge; edgelist = edgelist.next; if (edgelist.u >= edgestoadd.u) goto addedge; edgelist = edgelist.next; if (edgelist.u >= edgestoadd.u) goto addedge; edgelist = edgelist.next; if (edgelist.u >= edgestoadd.u) goto addedge; edgelist = edgelist.next; goto edgesearch; // insert edgestoadd before edgelist addedge: edgestoadd.next = edgelist; edgestoadd.prev = edgelist.prev; edgelist.prev.next = edgestoadd; edgelist.prev = edgestoadd; } while ((edgestoadd = next_edge) != null); }
static void LoadFaces(BinaryReader br, Header header) { // Read vertexes.. br.BaseStream.Seek(header.lumps[3].fileofs, SeekOrigin.Begin); int nVertexes = header.lumps[3].filelen / 12; Vector3[] loadedverts = new Vector3[nVertexes]; for (int i = 0; i < nVertexes; i++) { Vector3 vec = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); // swap z and y axis vec = SwapZY(vec); loadedverts[i] = vec; } // Reade edge lump br.BaseStream.Seek(header.lumps[12].fileofs, SeekOrigin.Begin); int nEdges = header.lumps[12].filelen / (sizeof(short) * 2); edge_t[] edges = new edge_t[nEdges]; for (int i = 0; i < nEdges; i++) { edge_t edge; edge.v = new ushort[] { br.ReadUInt16(), br.ReadUInt16() }; edges[i] = edge; } world.edges = edges; // Read surfedges br.BaseStream.Seek(header.lumps[13].fileofs, SeekOrigin.Begin); int nSurfEdges = header.lumps[13].filelen / sizeof(int); int[] surfEdges = new int[nSurfEdges]; for (int i = 0; i < nSurfEdges; i++) { surfEdges[i] = br.ReadInt32(); } world.surfEdges = surfEdges; // Read faces br.BaseStream.Seek(header.lumps[7].fileofs, SeekOrigin.Begin); int nFaces = header.lumps[7].filelen / 56; if (header.lumps[7].filelen % 56 > 0) { Common.Instance.Error("Weird faces lumpsize"); } world.faces_t = new face_t[nFaces]; world.faces = new Face[world.faces_t.Length]; for (int i = 0; i < nFaces; i++) { face_t face; face.planenum = br.ReadUInt16(); face.side = br.ReadByte(); face.onNode = br.ReadByte(); face.firstedge = br.ReadInt32(); face.numedges = br.ReadInt16(); face.texinfo = br.ReadInt16(); face.dispinfo = br.ReadInt16(); face.surfaceFogVolumeID = br.ReadInt16(); face.styles = br.ReadBytes(4); face.lightlumpofs = br.ReadInt32(); if (face.lightlumpofs > -1) { face.lightlumpofs /= 4; // From 4byte offset to 1color offset } face.area = br.ReadSingle(); face.LightmapTextureMinsInLuxels = new int[] { br.ReadInt32(), br.ReadInt32() }; face.LightmapTextureSizeInLuxels = new int[] { br.ReadInt32(), br.ReadInt32() }; face.origFace = br.ReadInt32(); face.numPrims = br.ReadUInt16(); face.firstPrimID = br.ReadUInt16(); face.smoothingGroups = br.ReadUInt32(); // Prepare Faces structure Face face2 = new Face(); face.face = face2; face2.face_t = face; face2.nVerts = face.numedges; face2.plane_t = world.planes[face.planenum]; face2.texinfo = world.texinfos[face.texinfo]; if ((face2.texinfo.flags & (SurfFlags.SURF_NODRAW | SurfFlags.SURF_HINT | SurfFlags.SURF_FLOWING | SurfFlags.SURF_NOLIGHT | SurfFlags.SURF_SKIP)) == 0) nVertIndex += face.numedges; world.faces[i] = face2; world.faces_t[i] = face; // Reverse mapping from displacement to face if (face.dispinfo != -1 && face.dispinfo < world.ddispinfos.Length) { world.DispIndexToFaceIndex[face.dispinfo] = i; } } // Prepare lightmap texture Texture lightmapTexture = new Texture(Renderer.Instance.device, LightmapSize.Width, LightmapSize.Height, 1, Usage.Dynamic, Format.A16B16G16R16F, (Renderer.Instance.Is3D9Ex ? Pool.Default : Pool.Managed)); DataRectangle textureData = lightmapTexture.LockRectangle(0, LockFlags.None); DataStream ds = textureData.Data; TextureNode texturePacker = new TextureNode(new System.Drawing.Rectangle(0, 0, LightmapSize.Width, LightmapSize.Height), null); TextureNode insertedNode = null; // TExtureNode result for each face int vertIndex = 0; world.verts = new List<VertexPositionNormalTexturedLightmap>(); for (int i = 0; i < world.faces.Length; i++) { face_t face_t = world.faces[i].face_t; Face face = world.faces[i]; if ((face.texinfo.flags & SurfFlags.SURF_NODRAW) > 0 || (face.texinfo.flags & SurfFlags.SURF_HINT) > 0 || (face.texinfo.flags & SurfFlags.SURF_FLOWING) > 0 || (face.texinfo.flags & SurfFlags.SURF_NOLIGHT) > 0 || (face.texinfo.flags & SurfFlags.SURF_SKIP) > 0) continue; // Dont draw this // Add faces lightmap to lightmap texture int lmWidth = face_t.LightmapTextureSizeInLuxels[0] + 1; int lmHeight = face_t.LightmapTextureSizeInLuxels[1] + 1; int lmSize = lmWidth * lmHeight; for (int lightstyles = 0; lightstyles < 4; lightstyles++) { if (face_t.styles[lightstyles] == 255) { continue; } if (face_t.lightlumpofs + (lmSize * lightstyles) >= world.LightData.Length || face_t.lightlumpofs == -1) { Common.Instance.WriteLine("WARNING: Face wants more lightdata than is available, or no offset"); break; } // Try to fit it in the texture.. insertedNode = texturePacker.Insert(ref world.LightData, lmWidth, lmHeight, face_t.lightlumpofs + (lmSize * lightstyles), ref ds, (face.face_t.dispinfo == -1 ? false : true)); if (insertedNode == null) System.Console.WriteLine("Could not fit lightmap into a texture :( w:" + lmWidth + " h:" + lmHeight); else// if (lightstyles == 0) { // Save lightmap coordinates face.lightOffsetX = insertedNode.Rectangle.X; face.lightOffsetY = insertedNode.Rectangle.Y; } } // Build VertexPositionNormalTexturedLightmap's for face float s, t; int v; int pedge = face.face_t.firstedge; for (int j = 0;j < face.face_t.numedges; j++) { int edge = surfEdges[pedge++]; if (edge < 0) { v = 1; edge = -edge; } else v = 0; // Base Texture Vector3 vert = loadedverts[edges[edge].v[v]]; // Texture coordinates Vector3 texs = new Vector3(face.texinfo.textureVecs[0].X, face.texinfo.textureVecs[0].Y, face.texinfo.textureVecs[0].Z); Vector3 text = new Vector3(face.texinfo.textureVecs[1].X, face.texinfo.textureVecs[1].Y, face.texinfo.textureVecs[1].Z); s = (Vector3.Dot(vert, texs) + face.texinfo.textureVecs[0].W) / face.texinfo.texdata_t.width; t = (Vector3.Dot(vert, text) + face.texinfo.textureVecs[1].W) / face.texinfo.texdata_t.height; // Generate Lightmap Coordinates float l_s = 0.5f, l_t = 0.5f; if (face.face_t.LightmapTextureSizeInLuxels[0] != 0 && face.face_t.LightmapTextureSizeInLuxels[1] != 0) { //Vector3 vecs = new Vector3(face.texinfo.lightmapVecs[0].X, face.texinfo.lightmapVecs[0].Y, face.texinfo.lightmapVecs[0].Z); //Vector3 vect = new Vector3(face.texinfo.lightmapVecs[1].X, face.texinfo.lightmapVecs[1].Y, face.texinfo.lightmapVecs[1].Z); l_s = Vector3.Dot(vert, face.texinfo.lightmapVecs[0]) + face.texinfo.lightmapVecs2[0] - face.face_t.LightmapTextureMinsInLuxels[0]; l_s /= face.face_t.LightmapTextureSizeInLuxels[0]; l_t = Vector3.Dot(vert, face.texinfo.lightmapVecs[1]) + face.texinfo.lightmapVecs2[1] - face.face_t.LightmapTextureMinsInLuxels[1]; l_t /= face.face_t.LightmapTextureSizeInLuxels[1]; float divx = (float)(face.face_t.LightmapTextureSizeInLuxels[0]) / (LightmapSize.Width); float startx = (float)(face.lightOffsetX + 0.5f) / (LightmapSize.Width); l_s = divx * l_s + startx; float divy = (float)(face.face_t.LightmapTextureSizeInLuxels[1]) / (LightmapSize.Height); float starty = (float)(face.lightOffsetY + 0.5f) / (LightmapSize.Height); l_t = divy * l_t + starty; } // Set vertex offset for face if (face.VertexOffset == -1) face.VertexOffset = vertIndex; world.verts.Add(new VertexPositionNormalTexturedLightmap(vert, face.plane_t.normal, new Vector2(s, t), new Vector2(l_s, l_t))); vertIndex++; } } //DispCollTree[] dispCollTrees = new DispCollTree[world.ddispinfos.Length]; //for (int i = 0; i < dispCollTrees.Length; i++) //{ // dispCollTrees[i] = new DispCollTree(); //} // Handle displacement face int iCurVert = 0, iCurTri = 0; for (int i = 0; i < world.ddispinfos.Length; i++) { int nFaceIndex = world.DispIndexToFaceIndex[i]; // Check for missing mapping to face if (nFaceIndex == 0) continue; // Get the displacement info ddispinfo_t currentDispInfo = world.ddispinfos[i]; Face face = world.faces[nFaceIndex]; //// Read in vertices //int nVerts = (((1 << (currentDispInfo.power)) + 1) * ((1 << (currentDispInfo.power)) + 1)); //List<dDispVert> dispVerts = new List<dDispVert>(); //for (int j = 0; j < nVerts; j++) //{ // dispVerts.Add(world.dispVerts[iCurVert + j]); //} //iCurVert += nVerts; //// Read in triangles //int nTris = ((1 << (currentDispInfo.power)) * (1 << (currentDispInfo.power)) * 2); //List<dDispTri> dispTris = new List<dDispTri>(); //for (int j = 0; j < nTris; j++) //{ // dispTris.Add(world.dispTris[iCurTri + j]); //} //iCurTri += nTris; //Displacement disp = new Displacement(); //DispSurface dispSurf = disp.Surface; //dispSurf.m_PointStart = currentDispInfo.startPosition; //dispSurf.m_Contents = currentDispInfo.contents; //disp.InitDispInfo(currentDispInfo.power, currentDispInfo.minTess, currentDispInfo.smoothingAngle, dispVerts, dispTris); //// Hook the disp surface to the face //dispSurf.m_Index = nFaceIndex; //// get points //if (world.faces_t[nFaceIndex].numedges > 4) // continue; //face_t fac = world.faces_t[nFaceIndex]; //Vector3[] surfPoints = new Vector3[4]; //dispSurf.m_PointCount = fac.numedges; //int h = 0; //for (h = 0; h < fac.numedges; h++ ) //{ // int eIndex = surfEdges[fac.firstedge + h]; // if (eIndex < 0) // { // surfPoints[h] = world.verts[edges[-eIndex].v[1]].position; // } // else // { // surfPoints[h] = world.verts[edges[eIndex].v[0]].position; // } //} //for (h = 0; h < 4; h++) //{ // dispSurf.m_Points[h] = surfPoints[h]; //} //dispSurf.FindSurfPointStartIndex(); //dispSurf.AdjustSurfPointData(); //// //// generate the collision displacement surfaces //// //DispCollTree dispTree = dispCollTrees[i]; //dispTree.Power = 0; //// //// check for null faces, should have been taken care of in vbsp!!! //// //int pointCount = dispSurf.m_PointCount; //if (pointCount != 4) // continue; //disp.Create(); //DispCollTree pDispTree = dispCollTrees[i]; //pDispTree.Power = 0; //pDispTree.Create(disp); // Generate the displacement surface createDispSurface(face, currentDispInfo, world, nFaceIndex); } //world.dispCollTrees = dispCollTrees; lightmapTexture.UnlockRectangle(0); world.LightmapTexture = lightmapTexture; }
public static bool CheckIncorrect(edge_t edge1, edge_t edge2) { return((edge1.vertex1 == edge2.vertex1 && edge1.vertex2 == edge2.vertex2) || (edge1.vertex1 == edge2.vertex2 && edge1.vertex2 == edge2.vertex1) || edge1.vertex1 == edge1.vertex2); }
/* ============== R_StepActiveU ============== */ static void R_StepActiveU(edge_t pedge) { edge_t pnext_edge, pwedge; while (true) { nextedge: pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) goto pushback; pedge = pedge.next; pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) goto pushback; pedge = pedge.next; pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) goto pushback; pedge = pedge.next; pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) goto pushback; pedge = pedge.next; goto nextedge; pushback: if (pedge == edge_aftertail) return; // push it back to keep it sorted pnext_edge = pedge.next; // pull the edge out of the edge list pedge.next.prev = pedge.prev; pedge.prev.next = pedge.next; // find out where the edge goes in the edge list pwedge = pedge.prev.prev; while (pwedge.u > pedge.u) { pwedge = pwedge.prev; } // put the edge back into the edge list pedge.next = pwedge.next; pedge.prev = pwedge; pedge.next.prev = pedge; pwedge.next = pedge; pedge = pnext_edge; if (pedge == edge_tail) return; } }
/* * ============== * R_LeadingEdgeBackwards * ============== */ static void R_LeadingEdgeBackwards(edge_t edge) { }
/* * ============== * R_StepActiveU * ============== */ static void R_StepActiveU(edge_t pedge) { edge_t pnext_edge, pwedge; while (true) { nextedge: pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) { goto pushback; } pedge = pedge.next; pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) { goto pushback; } pedge = pedge.next; pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) { goto pushback; } pedge = pedge.next; pedge.u += pedge.u_step; if (pedge.u < pedge.prev.u) { goto pushback; } pedge = pedge.next; goto nextedge; pushback: if (pedge == edge_aftertail) { return; } // push it back to keep it sorted pnext_edge = pedge.next; // pull the edge out of the edge list pedge.next.prev = pedge.prev; pedge.prev.next = pedge.next; // find out where the edge goes in the edge list pwedge = pedge.prev.prev; while (pwedge.u > pedge.u) { pwedge = pwedge.prev; } // put the edge back into the edge list pedge.next = pwedge.next; pedge.prev = pwedge; pedge.next.prev = pedge; pwedge.next = pedge; pedge = pnext_edge; if (pedge == edge_tail) { return; } } }
/* ============== R_LeadingEdgeBackwards ============== */ static void R_LeadingEdgeBackwards(edge_t edge) { }
/* * ============== * R_LeadingEdge * ============== */ static void R_LeadingEdge(edge_t edge) { espan_t span; surf_t surf, surf2; int iu; double fu, newzi, testzi, newzitop, newzibottom; if (edge.surfs[1] != 0) { // it's adding a new surface in, so find the correct place surf = surfaces[edge.surfs[1] - 1]; // don't start a span if this is an inverted span, with the end // edge preceding the start edge (that is, we've already seen the // end edge) if (++surf.spanstate == 1) { if (surf.insubmodel) { r_bmodelactive++; } surf2 = surfaces[0].next; if (surf.key < surf2.key) { goto newtop; } // if it's two surfaces on the same plane, the one that's already // active is in front, so keep going unless it's a bmodel if (surf.insubmodel && (surf.key == surf2.key)) { // must be two bmodels in the same leaf; sort on 1/z fu = (double)(edge.u - 0xFFFFF) * (1.0 / 0x100000); newzi = surf.d_ziorigin + fv * surf.d_zistepv + fu * surf.d_zistepu; newzibottom = newzi * 0.99; testzi = surf2.d_ziorigin + fv * surf2.d_zistepv + fu * surf2.d_zistepu; if (newzibottom >= testzi) { goto newtop; } newzitop = newzi * 1.01; if (newzitop >= testzi) { if (surf.d_zistepu >= surf2.d_zistepu) { goto newtop; } } } continue_search: do { surf2 = surf2.next; } while (surf.key > surf2.key); if (surf.key == surf2.key) { // if it's two surfaces on the same plane, the one that's already // active is in front, so keep going unless it's a bmodel if (!surf.insubmodel) { goto continue_search; } // must be two bmodels in the same leaf; sort on 1/z fu = (double)(edge.u - 0xFFFFF) * (1.0 / 0x100000); newzi = surf.d_ziorigin + fv * surf.d_zistepv + fu * surf.d_zistepu; newzibottom = newzi * 0.99; testzi = surf2.d_ziorigin + fv * surf2.d_zistepv + fu * surf2.d_zistepu; if (newzibottom >= testzi) { goto gotposition; } newzitop = newzi * 1.01; if (newzitop >= testzi) { if (surf.d_zistepu >= surf2.d_zistepu) { goto gotposition; } } goto continue_search; } goto gotposition; newtop: // emit a span (obscures current top) iu = edge.u >> 20; if (iu > surf2.last_u) { span = basespans[span_p++]; span.u = surf2.last_u; span.count = iu - span.u; span.v = current_iv; span.pnext = surf2.spans; surf2.spans = span; } // set last_u on the new span surf.last_u = iu; gotposition: // insert before surf2 surf.next = surf2; surf.prev = surf2.prev; surf2.prev.next = surf; surf2.prev = surf; } } }
/* ============== R_RemoveEdges ============== */ static void R_RemoveEdges(edge_t pedge) { do { pedge.next.prev = pedge.prev; pedge.prev.next = pedge.next; } while ((pedge = pedge.nextremove) != null); }
/* =============== R_NewMap =============== */ public static void R_NewMap() { int i; // clear out efrags in case the level hasn't been reloaded // FIXME: is this one short? for (i = 0; i < client.cl.worldmodel.numleafs; i++) client.cl.worldmodel.leafs[i].efrags = null; r_viewleaf = null; R_ClearParticles(); r_cnumsurfs = (int)r_maxsurfs.value; if (r_cnumsurfs <= MINSURFACES) r_cnumsurfs = MINSURFACES; if (r_cnumsurfs <= NUMSTACKSURFACES) { surfaces = new surf_t[r_cnumsurfs]; for (int kk = 0; kk < r_cnumsurfs; kk++) surfaces[kk] = new surf_t(); surface_p = 0; surf_max = r_cnumsurfs; r_surfsonstack = false; // surface 0 doesn't really exist; it's just a dummy because index 0 // is used to indicate no edge attached to surface } else { r_surfsonstack = true; } r_maxedgesseen = 0; r_maxsurfsseen = 0; r_numallocatededges = (int)r_maxedges.value; if (r_numallocatededges < MINEDGES) r_numallocatededges = MINEDGES; if (r_numallocatededges <= NUMSTACKEDGES) { auxedges = new edge_t[r_numallocatededges]; for (int kk = 0; kk < r_numallocatededges; kk++) auxedges[kk] = new edge_t(); } r_dowarpold = false; r_viewchanged = false; }
/* ============== R_TrailingEdge ============== */ static void R_TrailingEdge(surf_t surf, edge_t edge) { espan_t span; int iu; // don't generate a span if this is an inverted span, with the end // edge preceding the start edge (that is, we haven't seen the // start edge yet) if (--surf.spanstate == 0) { if (surf.insubmodel) r_bmodelactive--; if (surf == surfaces[0].next) { // emit a span (current top going away) iu = edge.u >> 20; if (iu > surf.last_u) { span = basespans[span_p++]; span.u = surf.last_u; span.count = iu - span.u; span.v = current_iv; span.pnext = surf.spans; surf.spans = span; } // set last_u on the surface below surf.next.last_u = iu; } surf.prev.next = surf.next; surf.next.prev = surf.prev; } }
/* * =============== * R_NewMap * =============== */ public static void R_NewMap() { int i; // clear out efrags in case the level hasn't been reloaded // FIXME: is this one short? for (i = 0; i < client.cl.worldmodel.numleafs; i++) { client.cl.worldmodel.leafs[i].efrags = null; } r_viewleaf = null; R_ClearParticles(); r_cnumsurfs = (int)r_maxsurfs.value; if (r_cnumsurfs <= MINSURFACES) { r_cnumsurfs = MINSURFACES; } if (r_cnumsurfs <= NUMSTACKSURFACES) { surfaces = new surf_t[r_cnumsurfs]; for (int kk = 0; kk < r_cnumsurfs; kk++) { surfaces[kk] = new surf_t(); } surface_p = 0; surf_max = r_cnumsurfs; r_surfsonstack = false; // surface 0 doesn't really exist; it's just a dummy because index 0 // is used to indicate no edge attached to surface } else { r_surfsonstack = true; } r_maxedgesseen = 0; r_maxsurfsseen = 0; r_numallocatededges = (int)r_maxedges.value; if (r_numallocatededges < MINEDGES) { r_numallocatededges = MINEDGES; } if (r_numallocatededges <= NUMSTACKEDGES) { auxedges = new edge_t[r_numallocatededges]; for (int kk = 0; kk < r_numallocatededges; kk++) { auxedges[kk] = new edge_t(); } } r_dowarpold = false; r_viewchanged = false; }