// Add decal and all surounding triangles for voxel intersection static void AddDecalVoxel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle, ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset) { MyVoxelMap voxelMap = (MyVoxelMap)intersection.Entity; MyMwcVector3Int renderCellCoord = voxelMap.GetVoxelRenderCellCoordinateFromMeters(ref intersection.IntersectionPointInWorldSpace); BoundingSphere decalBoundingSphere = new BoundingSphere(intersection.IntersectionPointInWorldSpace, decalSize); // If whole decal can't fit inside of render cell, we won't add any of its triangles. This is because // when hiding/removing triangles after explosion, it is easier to check only one render cell. BoundingBox renderCellBoundingBox; voxelMap.GetRenderCellBoundingBox(ref renderCellCoord, out renderCellBoundingBox); // TODO simon - commented as an experiment. If there are bugs with decals on voxels, remove the comment below //if (renderCellBoundingBox.Contains(decalBoundingSphere) != ContainmentType.Contains) return; // If we get null, buffer is full so no new decals can't be placed MyDecalsForVoxelsTriangleBuffer decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(voxelMap, ref renderCellCoord, decalTexture, ref renderCellBoundingBox); if (decalsBuffer == null) { return; } // We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them. // We check triangles from same voxelmap or model only. m_neighbourTriangles.Clear(); //intersection.VoxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, intersection.TriangleHelperIndex, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles); voxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles, false); int trianglesToAdd = m_neighbourTriangles.Count;// +1; if (trianglesToAdd == 0) { return; } if (decalsBuffer.CanAddTriangles(trianglesToAdd) == true) { var normalSum = CalculateDominantNormal(m_neighbourTriangles); normalSum *= decalNormalOffset; // Create decal for every neighbour triangleVertexes for (int i = 0; i < m_neighbourTriangles.Count; i++) { trianglesToAdd--; var triangle = m_neighbourTriangles[i]; triangle.Vertexes.Vertex0 += normalSum; triangle.Vertexes.Vertex1 += normalSum; triangle.Vertexes.Vertex2 += normalSum; m_neighbourTriangles[i] = triangle; decalsBuffer.Add(m_neighbourTriangles[i], intersection.NormalInWorldSpace, ref rightPlane, ref upPlane, decalScale, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInWorldSpace, emissivity); } } }
// Blends-out triangles affected by explosion (radius + some safe delta). Triangles there have zero alpha are flaged to not-draw at all. public static void HideTrianglesAfterExplosion(MyVoxelMap voxelMap, ref BoundingSphere explosionSphere) { MyRender.GetRenderProfiler().StartProfilingBlock("MyDecals::HideTrianglesAfterExplosion"); MyMwcVector3Int renderCellCoord = voxelMap.GetVoxelRenderCellCoordinateFromMeters(ref explosionSphere.Center); m_decalsForVoxels.HideTrianglesAfterExplosion(voxelMap.VoxelMapId, ref renderCellCoord, ref explosionSphere); MyRender.GetRenderProfiler().EndProfilingBlock(); }