// Hook displacements into the bsp tree static void DispTreeLeafnum(World world) { // // get the number of displacements per leaf // List<dDispTri> tris = new List<dDispTri>(); world.dispCollTrees = new DispCollTree[world.DispIndexToFaceIndex.Length]; List<dDispVert> verts = new List<dDispVert>(); int currTri = 0, currVert = 0; for (int i = 0; i < world.DispIndexToFaceIndex.Length; i++) { int j; int faceIndex = world.DispIndexToFaceIndex[i]; int dispId = world.faces_t[faceIndex].dispinfo; ddispinfo_t info = world.ddispinfos[dispId]; int power = info.power; int nVerts = (((1 << (power)) + 1) * ((1 << (power)) + 1)); verts.Clear(); // fail code for (j = 0; j < nVerts; j++) { verts.Add(world.dispVerts[j + currVert]); } currVert += nVerts; int nTris = ((1 << (power)) * (1 << (power)) * 2); tris.Clear(); for (j = 0; j < nTris; j++) { tris.Add(world.dispTris[j + currTri]); } currTri += nTris; Displacement displace = new Displacement(); displace.Surface = new DispSurface(); DispSurface dispSurf = displace.Surface; dispSurf.m_PointStart = info.startPosition; dispSurf.m_Contents = info.contents; displace.InitDispInfo(info.power, info.minTess, info.smoothingAngle, verts, tris); dispSurf.m_Index = faceIndex; face_t face = world.faces_t[faceIndex]; if (face.numedges > 4) continue; Vector3[] surfPoints = new Vector3[4]; dispSurf.m_PointCount = face.numedges; for (j = 0; j < face.numedges; j++) { int eIndex = world.surfEdges[face.firstedge + j]; if (eIndex < 0) surfPoints[j] = world.verts[world.edges[-eIndex].v[1]].position; else surfPoints[j] = world.verts[world.edges[eIndex].v[0]].position; } dispSurf.m_Points = surfPoints; dispSurf.FindSurfPointStartIndex(); dispSurf.AdjustSurfPointData(); // // generate the collision displacement surfaces // world.dispCollTrees[i] = new DispCollTree(); DispCollTree dispTree = world.dispCollTrees[i]; // // check for null faces, should have been taken care of in vbsp!!! // if (dispSurf.m_PointCount != 4) continue; displace.Create(); // new collision dispTree.Create(displace); DispTreeLeafnum_r(world, faceIndex, i, 0); } }
//----------------------------------------------------------------------------- // Purpose: allocate and initialize the displacement collision tree data // Input: pDisp - displacement surface data // Output: success? (true/false) //----------------------------------------------------------------------------- public bool Create(Displacement pDisp) { // Displacement size. Power = pDisp.Power; // Displacement contents. DispSurface pSurf = pDisp.Surface; m_Contents = pSurf.m_Contents; // Displacement stab direction = base face normal. m_StabDir = pSurf.GetNormal(); // Copy the base surface points. for (int iPt = 0; iPt < 4; iPt++) { m_SurfPoints[iPt] = pSurf.m_Points[iPt]; } // Allocate collision tree data. bool ResultNodes = Nodes_Alloc(); bool ResultVert = AllocVertData(); bool ResultTris = Tris_Alloc(); if (!ResultTris || !ResultVert || !ResultNodes) { // Clean up m_pNodes = null; m_NodeCount = 0; m_pVerts = null; m_pOriginalVerts = null; m_pVertNormals = null; m_VertCount = 0; m_pTris = null; m_nTriCount = 0; return false; } // Copy the vertices and vertex normals. for (int iVert = 0; iVert < m_VertCount; iVert++) { m_pVerts[iVert] = pDisp.Verts[iVert].m_Vert; m_pOriginalVerts[iVert] = m_pVerts[iVert]; m_pVertNormals[iVert] = pDisp.Verts[iVert].m_Normal; } // Copy the triangle flags data. for (int iTri = 0; iTri < m_nTriCount; ++iTri ) { ushort[] ind = pDisp.Tris[iTri].m_iIndex; m_pTris[iTri].m_uiVerts = ind; m_pTris[iTri].m_nFlags = pDisp.Tris[iTri].m_uiTags; // Calculate the surface props. float totalAlpha = 0.0f; for (int iVert = 0; iVert < 3; ++iVert) { totalAlpha += pDisp.Verts[m_pTris[iTri].m_uiVerts[iVert]].m_Alpha; } m_pTris[iTri].m_iSurfProp = 0; if (totalAlpha > 382.5f) { m_pTris[iTri].m_iSurfProp = 1; } // Add the displacement surface flag! m_pTris[iTri].m_nFlags |= (1 << 0); Tri_CalcPlane(iTri); } // create leaf nodes Leafs_Create(); // create tree nodes Nodes_Create(); // create the bounding box of the displacement surface + the base face CalcFullBBox(); // tree successfully created! return true; }