public OpenHeightfield build(SolidHeightfield sourceField , bool performFullGeneration ) { if( sourceField == null ) { Logger.LogError("[OpenHeightfieldBuilder][build] sourceField null "); return null; } OpenHeightfield result = new OpenHeightfield( sourceField.boundsMin(), sourceField.boundsMax(), sourceField.cellSize(), sourceField.cellHeight() ); for(int depthIndex = 0; depthIndex < sourceField.depth(); depthIndex++) { for(int widthIndex = 0; widthIndex < sourceField.width(); widthIndex++) { OpenHeightSpan baseSpan = null; OpenHeightSpan previousSpan = null; for (HeightSpan span = sourceField.getData(widthIndex, depthIndex); span != null; span = span.next() ) { if ( span.flags() != mFilterFlags ) { continue; } //当前Solid Span的max对应的是对应OpenSpan的floor int floor = span.max(); //下一个Next Solid Span的min对应当前OpenSpan的Ceil。 int ceiling = (span.next() != null ? span.next().min() : int.MaxValue) ; //对应的Open Span OpenHeightSpan oSpan = new OpenHeightSpan(floor, (ceiling - floor ) ); if( baseSpan == null ) { baseSpan = oSpan; } if( previousSpan != null ) { previousSpan.setNext(oSpan); } previousSpan = oSpan; result.incrementSpanCount(); } //for if( baseSpan != null ) { result.addData(widthIndex, depthIndex, baseSpan); } }//for } //for if( performFullGeneration ) { generateNeighborLinks(result); generateDistanceField(result); blurDistanceField(result); generateRegions(result); } return result; }
//vertices是以(x,y,z)(x,y,z)三组三组为一个顶点 public SolidHeightfield build(float[] vertices, int[] indices) { if (vertices == null || indices == null || vertices.Length % 3 != 0 || indices.Length % 3 != 0) { Logger.LogError("[SolidHeightfieldBuilder][build]invalid"); return(null); } SolidHeightfield result = new SolidHeightfield(mCellSize, mCellHeight); //用作分母,方便后面计算的 float inverseCellSize = 1 / result.cellSize(); float inverseCellHeight = 1 / result.cellHeight(); float xmin = vertices[0]; float ymin = vertices[1]; float zmin = vertices[2]; float xmax = vertices[0]; float ymax = vertices[1]; float zmax = vertices[2]; //遍历所有顶点,找出最大的Bounds for (int i = 3; i < vertices.Length; i += 3) { xmax = Math.Max(vertices[i], xmax); ymax = Math.Max(vertices[i + 1], ymax); zmax = Math.Max(vertices[i + 2], zmax); xmin = Math.Min(vertices[i], xmin); ymin = Math.Min(vertices[i + 1], ymin); zmin = Math.Min(vertices[i + 2], zmin); } result.setBounds(xmin, ymin, zmin, xmax, ymax, zmax); //判断哪些多边形的表面是可以行走的,坡度不能太大 int[] polyFlags = markInputMeshWalkableFlags(vertices, indices); //开始对每个面进行体素化 int polyCount = indices.Length / 3; for (int iPoly = 0; iPoly < polyCount; iPoly++) { voxelizeTriangle(iPoly, vertices, indices, polyFlags[iPoly], inverseCellSize, inverseCellHeight, result); } markLowHeightSpans(result); if (mClipLedges) { markLedgeSpans(result); } return(result); }