internal void Finalize(float[,] heightMap, float scaleX, float scaleZ) { m_minBounds.x = scaleX * m_minX; m_minBounds.z = scaleZ * m_minZ; m_maxBounds.x = scaleX * m_maxX; m_maxBounds.z = scaleZ * m_maxZ; var scissoredTriangleCount = new ScissoredTriangleCount(); // scissor triangles if any if (m_bScissor && 0 < m_patchListToScissor.Count) { var numTrianglesToScissor = 0; for (var i = 0; i < m_patchListToScissor.Count; ++i) { var w = m_patchListToScissor[i].m_width; numTrianglesToScissor += 2 * w * w; } InitScissorBuffer(numTrianglesToScissor); for (var i = 0; i < m_patchListToScissor.Count; ++i) { var patch = m_patchListToScissor[i]; for (int z = patch.m_posZ, zEnd = patch.m_posZ + patch.m_width; z < zEnd; ++z) { for (int x = patch.m_posX, xEnd = patch.m_posX + patch.m_width; x < xEnd; ++x) { var v0 = new Vector3(scaleX * x, heightMap[z, x], scaleZ * z); var v1 = new Vector3(scaleX * (x + 1), heightMap[z, x + 1], scaleZ * z); var v2 = new Vector3(scaleX * x, heightMap[z + 1, x], scaleZ * (z + 1)); var v3 = new Vector3(scaleX * (x + 1), heightMap[z + 1, x + 1], scaleZ * (z + 1)); ScissorTriangle(v0, v2, v3, ref scissoredTriangleCount, m_patchList.Count == 0); ScissorTriangle(v0, v3, v1, ref scissoredTriangleCount, m_patchList.Count == 0); } } } } // create result buffer var vertexCount = scissoredTriangleCount.m_nVertexCount + (m_maxX - m_minX + 1) * (m_maxZ - m_minZ + 1); var indexCount = scissoredTriangleCount.m_nIndexCount + m_indexCount; InitResultBuffer(vertexCount, indexCount, false); m_bOutputNormals = false; // fill result buffer var nVertex = 0; var nIndex = 0; for (var z = m_minZ; z <= m_maxZ; ++z) { for (var x = m_minX; x <= m_maxX; ++x) { m_result[nVertex++] = new Vector3(scaleX * x, heightMap[z, x], scaleZ * z); } } var width = m_maxX - m_minX + 1; for (var i = 0; i < m_patchList.Count; ++i) { var patch = m_patchList[i]; var offset = (patch.m_posZ - m_minZ) * width + (patch.m_posX - m_minX); for (var z = 0; z < patch.m_width; ++z) { var vtx = offset; for (var x = 0; x < patch.m_width; ++x) { m_resultIndices[nIndex++] = vtx; m_resultIndices[nIndex++] = vtx + width; m_resultIndices[nIndex++] = vtx + width + 1; m_resultIndices[nIndex++] = vtx; m_resultIndices[nIndex++] = vtx + width + 1; m_resultIndices[nIndex++] = ++vtx; } offset += width; } } FillResultWithScissoredTriangles(scissoredTriangleCount.m_nTriangleCount, ref nVertex, ref nIndex); var lastIndex = 0 < nIndex ? m_resultIndices[nIndex - 1] : 0; while (nIndex < m_resultIndices.Length) { m_resultIndices[nIndex++] = lastIndex; } }
protected int ScissorTriangle(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 n0, Vector3 n1, Vector3 n2, ref ScissoredTriangleCount triCount, bool bResetBounds) { var numVertices = 3; var vertices = m_scissoredTriangles[triCount.m_nTriangleCount]; var normals = m_scissoredTriangleNormals[triCount.m_nTriangleCount]; vertices[0] = v0; vertices[1] = v1; vertices[2] = v2; normals[0] = n0; normals[1] = n1; normals[2] = n2; if (m_clipPlanes.twoSideClipping) { for (var j = 0; j < m_clipPlanes.scissorPlaneCount; ++j) { var clipPlane = m_clipPlanes.clipPlanes[j]; var maxDistance = m_clipPlanes.maxDistance[j]; var firstDistance = clipPlane.GetDistanceToPoint(vertices[0]); var firstDistance2 = maxDistance - firstDistance; var lastDistance = firstDistance; var lastDistance2 = firstDistance2; var newVertexCount = 0; for (var k = 1; k < numVertices; ++k) { var distance = clipPlane.GetDistanceToPoint(vertices[k]); var distance2 = maxDistance - distance; if (distance <= 0) { if (lastDistance2 <= 0) { var w = distance2 / (distance2 - lastDistance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k], vertices[k - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k], normals[k - 1], w); ++newVertexCount; } if (0 < lastDistance) { var w = lastDistance / (lastDistance - distance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k - 1], vertices[k], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k - 1], normals[k], w); ++newVertexCount; } } else { if (lastDistance <= 0) { var w = distance / (distance - lastDistance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k], vertices[k - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k], normals[k - 1], w); ++newVertexCount; if (distance2 <= 0) { var w2 = lastDistance2 / (lastDistance2 - distance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k - 1], vertices[k], w2); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k - 1], normals[k], w2); ++newVertexCount; } } else if (distance2 <= 0) { if (0 < lastDistance2) { var w = lastDistance2 / (lastDistance2 - distance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k - 1], vertices[k], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k - 1], normals[k], w); ++newVertexCount; } } else { if (lastDistance2 <= 0) { var w = distance2 / (distance2 - lastDistance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k], vertices[k - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k], normals[k - 1], w); ++newVertexCount; } } } if (0 < distance && 0 < distance2) { m_tempScissorBuffer[newVertexCount] = vertices[k]; m_tempScissorNormalBuffer[newVertexCount] = normals[k]; ++newVertexCount; } lastDistance = distance; lastDistance2 = distance2; } if (firstDistance <= 0) { if (lastDistance2 <= 0) { var w = firstDistance2 / (firstDistance2 - lastDistance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[0], vertices[numVertices - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[0], normals[numVertices - 1], w); ++newVertexCount; } if (0 < lastDistance) { var w = lastDistance / (lastDistance - firstDistance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[numVertices - 1], vertices[0], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[numVertices - 1], normals[0], w); ++newVertexCount; } } else { if (lastDistance <= 0) { var w = firstDistance / (firstDistance - lastDistance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[0], vertices[numVertices - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[0], normals[numVertices - 1], w); ++newVertexCount; if (firstDistance2 <= 0) { var w2 = lastDistance2 / (lastDistance2 - firstDistance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[numVertices - 1], vertices[0], w2); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[numVertices - 1], normals[0], w2); ++newVertexCount; } } else if (firstDistance2 <= 0) { if (0 < lastDistance2) { var w = lastDistance2 / (lastDistance2 - firstDistance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[numVertices - 1], vertices[0], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[numVertices - 1], normals[0], w); ++newVertexCount; } } else { if (lastDistance2 <= 0) { var w = firstDistance2 / (firstDistance2 - lastDistance2); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[0], vertices[numVertices - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[0], normals[numVertices - 1], w); ++newVertexCount; } } } if (0 < firstDistance && 0 < firstDistance2) { m_tempScissorBuffer[newVertexCount] = vertices[0]; m_tempScissorNormalBuffer[newVertexCount] = normals[0]; ++newVertexCount; } numVertices = newVertexCount; vertices = m_tempScissorBuffer; normals = m_tempScissorNormalBuffer; m_tempScissorBuffer = m_scissoredTriangles[triCount.m_nTriangleCount]; m_tempScissorNormalBuffer = m_scissoredTriangleNormals[triCount.m_nTriangleCount]; m_scissoredTriangles[triCount.m_nTriangleCount] = vertices; m_scissoredTriangleNormals[triCount.m_nTriangleCount] = normals; if (numVertices < 3) { return(0); } } } else { for (var j = 0; j < m_clipPlanes.scissorPlaneCount; ++j) { var clipPlane = m_clipPlanes.clipPlanes[j]; var firstDistance = clipPlane.GetDistanceToPoint(vertices[0]); var lastDistance = firstDistance; var newVertexCount = 0; for (var k = 1; k < numVertices; ++k) { var distance = clipPlane.GetDistanceToPoint(vertices[k]); if (distance <= 0) { if (0 < lastDistance) { var w = lastDistance / (lastDistance - distance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k - 1], vertices[k], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k - 1], normals[k], w); ++newVertexCount; } } else { if (lastDistance <= 0) { var w = distance / (distance - lastDistance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[k], vertices[k - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[k], normals[k - 1], w); ++newVertexCount; } m_tempScissorBuffer[newVertexCount] = vertices[k]; m_tempScissorNormalBuffer[newVertexCount] = normals[k]; ++newVertexCount; } lastDistance = distance; } if (firstDistance <= 0) { if (0 < lastDistance) { var w = lastDistance / (lastDistance - firstDistance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[numVertices - 1], vertices[0], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[numVertices - 1], normals[0], w); ++newVertexCount; } } else { if (lastDistance <= 0) { var w = firstDistance / (firstDistance - lastDistance); m_tempScissorBuffer[newVertexCount] = Vector3.Lerp(vertices[0], vertices[numVertices - 1], w); m_tempScissorNormalBuffer[newVertexCount] = Vector3.Lerp(normals[0], normals[numVertices - 1], w); ++newVertexCount; } m_tempScissorBuffer[newVertexCount] = vertices[0]; m_tempScissorNormalBuffer[newVertexCount] = normals[0]; ++newVertexCount; } numVertices = newVertexCount; vertices = m_tempScissorBuffer; normals = m_tempScissorNormalBuffer; m_tempScissorBuffer = m_scissoredTriangles[triCount.m_nTriangleCount]; m_tempScissorNormalBuffer = m_scissoredTriangleNormals[triCount.m_nTriangleCount]; m_scissoredTriangles[triCount.m_nTriangleCount] = vertices; m_scissoredTriangleNormals[triCount.m_nTriangleCount] = normals; if (numVertices < 3) { return(0); } } } if (bResetBounds && triCount.m_nTriangleCount == 0) { m_maxBounds = m_minBounds = m_scissoredTriangles[triCount.m_nTriangleCount][0]; } for (var j = 0; j < numVertices; ++j) { var v = m_scissoredTriangles[triCount.m_nTriangleCount][j]; m_minBounds.x = Mathf.Min(m_minBounds.x, v.x); m_minBounds.y = Mathf.Min(m_minBounds.y, v.y); m_minBounds.z = Mathf.Min(m_minBounds.z, v.z); m_maxBounds.x = Mathf.Max(m_maxBounds.x, v.x); m_maxBounds.y = Mathf.Max(m_maxBounds.y, v.y); m_maxBounds.z = Mathf.Max(m_maxBounds.z, v.z); } m_scissoredTriangleVertexCount[triCount.m_nTriangleCount++] = numVertices; triCount.m_nVertexCount += numVertices; triCount.m_nIndexCount += (numVertices - 2) * 3; return(numVertices); }
internal void Finalize(Vector3[] vertices, int[] indices) { var scissoredTriangleCount = new ScissoredTriangleCount(); // scissor triangles if any if (m_bScissor && 0 < m_triangleListToScissor.Count) { var numTrianglesToScissor = 0; for (var i = 0; i < m_triangleListToScissor.Count; ++i) { numTrianglesToScissor += m_triangleListToScissor[i].Length; } InitScissorBuffer(numTrianglesToScissor); if (m_bBackfaceCulling) { for (var i = 0; i < m_triangleListToScissor.Count; ++i) { var triangles = m_triangleListToScissor[i]; for (var tri = 0; tri < triangles.Length; ++tri) { var index = triangles[tri]; var v0 = vertices[indices[index++]]; var v1 = vertices[indices[index++]]; var v2 = vertices[indices[index++]]; if (isFrontFaceTriangle(v0, v1, v2)) { ScissorTriangle(v0, v1, v2, ref scissoredTriangleCount, m_triangleList.Count == 0); } } } } else { for (var i = 0; i < m_triangleListToScissor.Count; ++i) { var triangles = m_triangleListToScissor[i]; for (var tri = 0; tri < triangles.Length; ++tri) { var index = triangles[tri]; var v0 = vertices[indices[index++]]; var v1 = vertices[indices[index++]]; var v2 = vertices[indices[index++]]; ScissorTriangle(v0, v1, v2, ref scissoredTriangleCount, m_triangleList.Count == 0); } } } } // count vertices and indices var numVertexCount = 0; for (var i = 0; i < m_triangleList.Count; ++i) { numVertexCount += m_triangleList[i].Length * 3; } var numIndexCount = numVertexCount; numVertexCount += scissoredTriangleCount.m_nVertexCount; numIndexCount += scissoredTriangleCount.m_nIndexCount; // create result buffer InitResultBuffer(numVertexCount, numIndexCount, false); m_bOutputNormals = false; // fill result buffer var nVertex = 0; var nIndex = 0; if (m_bBackfaceCulling) { for (var i = 0; i < m_triangleList.Count; ++i) { var triangles = m_triangleList[i]; for (var tri = 0; tri < triangles.Length; ++tri) { var index = triangles[tri]; var v0 = vertices[indices[index++]]; var v1 = vertices[indices[index++]]; var v2 = vertices[indices[index++]]; if (isFrontFaceTriangle(v0, v1, v2)) { m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = v0; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = v1; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = v2; } } } } else { for (var i = 0; i < m_triangleList.Count; ++i) { var triangles = m_triangleList[i]; for (var tri = 0; tri < triangles.Length; ++tri) { var index = triangles[tri]; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = vertices[indices[index++]]; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = vertices[indices[index++]]; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = vertices[indices[index++]]; } } } FillResultWithScissoredTriangles(scissoredTriangleCount.m_nTriangleCount, ref nVertex, ref nIndex); var lastIndex = 0 < nIndex ? m_resultIndices[nIndex - 1] : 0; while (nIndex < m_resultIndices.Length) { m_resultIndices[nIndex++] = lastIndex; } }
internal void Finalize(Vector3[] vertices, int[] indices) { var nVertexCount = 0; var nIndexCount = 0; var numTriangles = m_triangleList.Count; var scissoredTriangleCount = 0; if (m_bScissor) { InitScissorBuffer(numTriangles); var scissorCount = new ScissoredTriangleCount(); if (m_bBackfaceCulling) { for (var i = 0; i < numTriangles; ++i) { var index = m_triangleList[i]; var v0 = vertices[indices[index++]]; var v1 = vertices[indices[index++]]; var v2 = vertices[indices[index++]]; if (isFrontFaceTriangle(v0, v1, v2)) { ScissorTriangle(v0, v1, v2, ref scissorCount, true); } } } else { for (var i = 0; i < numTriangles; ++i) { var index = m_triangleList[i]; var v0 = vertices[indices[index++]]; var v1 = vertices[indices[index++]]; var v2 = vertices[indices[index++]]; ScissorTriangle(v0, v1, v2, ref scissorCount, true); } } nVertexCount = scissorCount.m_nVertexCount; nIndexCount = scissorCount.m_nIndexCount; scissoredTriangleCount = scissorCount.m_nTriangleCount; } else { nVertexCount = 3 * numTriangles; nIndexCount = 3 * numTriangles; } // create result buffer InitResultBuffer(nVertexCount, nIndexCount, false); m_bOutputNormals = false; // fill result buffer var nVertex = 0; var nIndex = 0; if (m_bScissor) { FillResultWithScissoredTriangles(scissoredTriangleCount, ref nVertex, ref nIndex); } else { if (m_bBackfaceCulling) { for (var i = 0; i < numTriangles; ++i) { var index = m_triangleList[i]; var v0 = vertices[indices[index++]]; var v1 = vertices[indices[index++]]; var v2 = vertices[indices[index++]]; if (isFrontFaceTriangle(v0, v1, v2)) { m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = v0; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = v1; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = v2; } } } else { for (var i = 0; i < numTriangles; ++i) { var index = m_triangleList[i]; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = vertices[indices[index++]]; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = vertices[indices[index++]]; m_resultIndices[nIndex++] = nVertex; m_result[nVertex++] = vertices[indices[index++]]; } } } var lastIndex = 0 < nIndex ? m_resultIndices[nIndex - 1] : 0; while (nIndex < m_resultIndices.Length) { m_resultIndices[nIndex++] = lastIndex; } }