private static void AddVertexToBuffer(MySingleMaterialHelper materialHelper, ref MyVoxelVertex vertex0, int matIndex, short vertexIndex0) { MyVoxelCacheCellRenderHelper.CreateArrayIfNotExist(matIndex); if (MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter != MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex]) { int nextVertexIndex = materialHelper.VertexCount; // Short overflow check System.Diagnostics.Debug.Assert(nextVertexIndex <= short.MaxValue); // copy position and ambient materialHelper.Vertices[nextVertexIndex].Position = vertex0.Position; materialHelper.Vertices[nextVertexIndex].Ambient = vertex0.Ambient; // Copy normal materialHelper.Vertices[nextVertexIndex].Normal = vertex0.Normal; MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex]; MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].VertexIndex = (short)nextVertexIndex; materialHelper.VertexCount++; } }
// This method adds triangles from one data cell into this render cell. Single-texture triangles are added using indices (so we use m_notCompressedIndex buffer). // For this we need to find indices. We use lookup array for it. // Now we support only 16-bit indices, so vertex buffer can't have more then short.MaxValue vertices. public void AddTriangles(List <MyVoxelGeometry.CellData> cacheDataArray) { foreach (var cacheData in cacheDataArray) { // Increase lookup count, so we will think that all vertexes in helper arrays are new for (int i = 0; i < MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount.Length; i++) { MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[i]++; } for (int i = 0; i < cacheData.VoxelTrianglesCount; i++) { MyVoxelTriangle triangle = cacheData.VoxelTriangles[i]; MyVoxelVertex vertex0, vertex1, vertex2; cacheData.GetUnpackedVertex(triangle.VertexIndex0, out vertex0); cacheData.GetUnpackedVertex(triangle.VertexIndex1, out vertex1); cacheData.GetUnpackedVertex(triangle.VertexIndex2, out vertex2); vertex0.Position = (vertex0.Position - m_positionOffset) / m_positionScale; vertex1.Position = (vertex1.Position - m_positionOffset) / m_positionScale; vertex2.Position = (vertex2.Position - m_positionOffset) / m_positionScale; Debug.Assert(vertex0.Position.IsInsideInclusive(ref Vector3.Zero, ref Vector3.One)); Debug.Assert(vertex1.Position.IsInsideInclusive(ref Vector3.Zero, ref Vector3.One)); Debug.Assert(vertex2.Position.IsInsideInclusive(ref Vector3.Zero, ref Vector3.One)); if ((vertex0.Material == vertex1.Material) && (vertex0.Material == vertex2.Material)) { var matDef = MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)vertex0.Material); // This is single-texture triangleVertexes, so we can choose material from any edge MySingleMaterialHelper materialHelper = MyVoxelCacheCellRenderHelper.GetForMaterial(matDef); // Add vertex0 to vertex buffer AddVertexToBuffer(materialHelper, ref vertex0, matDef.Index, triangle.VertexIndex0); // Add vertex1 to vertex buffer AddVertexToBuffer(materialHelper, ref vertex1, matDef.Index, triangle.VertexIndex1); // Add vertex2 to vertex buffer AddVertexToBuffer(materialHelper, ref vertex2, matDef.Index, triangle.VertexIndex2); MyVoxelCacheCellRenderHelper.CreateArrayIfNotExist(matDef.Index); // Add indices int nextTriangleIndex = materialHelper.IndexCount; materialHelper.Indices[nextTriangleIndex + 0] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matDef.Index][triangle.VertexIndex0].VertexIndex; materialHelper.Indices[nextTriangleIndex + 1] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matDef.Index][triangle.VertexIndex1].VertexIndex; materialHelper.Indices[nextTriangleIndex + 2] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matDef.Index][triangle.VertexIndex2].VertexIndex; materialHelper.IndexCount += 3; if ((materialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP) || (materialHelper.IndexCount >= MyVoxelCacheCellRenderHelper.MAX_INDICES_COUNT_STOP)) { // If this batch is almost full (or is full), we end it and start with new one EndSingleMaterial(materialHelper); } } else { int id = GetMultimaterialId(vertex0.Material, vertex1.Material, vertex2.Material); // Assign current material MyMultiMaterialHelper multiMaterialHelper = MyVoxelCacheCellRenderHelper.GetForMultimaterial(vertex0.Material, vertex1.Material, vertex2.Material); // Copy packed normals multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 0].Normal = vertex0.Normal; multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 1].Normal = vertex0.Normal; multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 2].Normal = vertex0.Normal; multiMaterialHelper.AddVertex(ref vertex0); multiMaterialHelper.AddVertex(ref vertex1); multiMaterialHelper.AddVertex(ref vertex2); if (multiMaterialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP) { EndMultiMaterial(multiMaterialHelper); } } } } }