private void ScanTree(SamplerTree sampler)
{
sampler.RunSampler(this);
if (!stitchBorder)
return;
int detailedX = curXIdx * detailedSize;
int detailedZ = curZIdx * detailedSize;
//boundary
float bfx = curXIdx * gridSize[0];
float bfz = curZIdx * gridSize[1];
float borderOffset = 0;
if (curXIdx == 0 || curZIdx == 0 || curXIdx == maxX - 1 || curZIdx == maxZ - 1)
borderOffset = 0.000001f;
RayCastBoundary(bfx + borderOffset, bfz + borderOffset,
detailedX, detailedZ, SamplerTree.LBCorner, sampler);
RayCastBoundary(bfx + borderOffset, bfz + gridSize[1] - borderOffset,
detailedX, detailedZ + detailedSize - 1, SamplerTree.LTCorner, sampler);
RayCastBoundary(bfx + gridSize[0] - borderOffset, bfz + gridSize[1] - borderOffset,
detailedX + detailedSize - 1, detailedZ + detailedSize - 1, SamplerTree.RTCorner, sampler);
RayCastBoundary(bfx + gridSize[0] - borderOffset, bfz + borderOffset,
detailedX + detailedSize - 1, detailedZ, SamplerTree.RBCorner, sampler);
for (int u = 1; u < detailedSize; ++u)
{
float fx = (curXIdx + (float)u / detailedSize) * gridSize[0];
RayCastBoundary(fx, bfz + borderOffset, u + detailedX, detailedZ, SamplerTree.BBorder, sampler);
RayCastBoundary(fx, bfz + gridSize[1] - borderOffset,
u + detailedX, detailedZ + detailedSize - 1, SamplerTree.TBorder, sampler);
}
for (int v = 1; v < detailedSize; ++v)
{
float fz = (curZIdx + (float)v / detailedSize) * gridSize[1];
RayCastBoundary(bfx + borderOffset, fz, detailedX, v + detailedZ, SamplerTree.LBorder, sampler);
RayCastBoundary(bfx + gridSize[0] - borderOffset, fz,
detailedX + detailedSize - 1, v + detailedZ, SamplerTree.RBorder, sampler);
}
}
这里是深度优先扫描树,对节点和叶子节点的位置和法线重新进行了侦测赋值。
主要是使用了:
terrain.SampleHeight(center) + terrain.gameObject.transform.position.y;
和
terrain.terrainData.GetInterpolatedNormal(fx, fy);
两个函数,才有高度和取法线操作。
上面的函数RayCastBoundary,就是计算各个点的位置、uv、法线。
private void RayCastBoundary(float fx, float fz, int x, int z, byte bk, SamplerTree sampler)
{
Vector3 hitpos = check_start + fx * Vector3.right + fz * Vector3.forward;
hitpos.x = Mathf.Clamp(hitpos.x, volBnd.min.x, volBnd.max.x);
hitpos.z = Mathf.Clamp(hitpos.z, volBnd.min.z, volBnd.max.z);
float local_x = (hitpos.x - volBnd.min.x) / volBnd.size.x;
float local_y = (hitpos.z - volBnd.min.z) / volBnd.size.z;
hitpos.y = terrain.SampleHeight(hitpos) + terrain.gameObject.transform.position.y;
var hitnormal = terrain.terrainData.GetInterpolatedNormal(local_x, local_y);
SampleVertexData vert = new SampleVertexData();
vert.Position = hitpos;
vert.Normal = hitnormal;
vert.UV = new Vector2(fx / maxX / gridSize[0], fz / maxZ / gridSize[1]);
sampler.AddBoundary(subdivision, x, z, bk, vert);
}
public void AddBoundary(int subdivision, int x, int z, byte bk, SampleVertexData vert)
{
if (mNode is SamplerNode)
{
SamplerNode node = (SamplerNode)mNode;
node.AddBoundary(subdivision, x, z, bk, vert);
}
}
public override void AddBoundary(int subdivision, int x, int z, byte bk, SampleVertexData vert)
{
Boundaries.Add(bk, vert);
}
直到加入到叶子节点为止。
经过上面的操作,将128*128的边上的点,和角点加入到叶子节点边界中了。