// 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); } } }
public MyDecalsForRenderObjectsTriangleBuffer GetTrianglesBuffer(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { MyDecalsForModelsDictionaryKey key = new MyDecalsForModelsDictionaryKey(renderObject, decalTexture); MyDecalsForRenderObjectsTriangleBuffer outValue; if (m_triangleBuffersByKey.TryGetValue(key, out outValue)) { // Combination of model/texture was found in dictionary, so we can return in right now return outValue; } else { if (m_triangleBuffersByKey.Count >= m_capacity) { // We are full, can't place decal on a new model/texture. Need to wait for next CheckBufferFull. return null; } else { // This is first time we want to place decal on this model/texture, so here we allocate and initialize buffer MyDecalsForRenderObjectsTriangleBuffer newBuffer = m_freeTriangleBuffers.Pop(); m_triangleBuffersByKey.Add(key, newBuffer); m_usedTriangleBuffers.Add(newBuffer); newBuffer.Start(renderObject, decalTexture); return newBuffer; } } }
public static bool IsLargeTexture(MyDecalTexturesEnum decalTexture) { if (decalTexture == MyDecalTexturesEnum.ExplosionSmut) { return(true); } return(false); }
// Add decal and all surounding triangles for model intersection static void AddDecalModel(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) { MyDecalsForPhysObjectsTriangleBuffer decalsBuffer = m_decalsForModels.GetTrianglesBuffer(intersection.Entity, decalTexture); // If we get null, buffer is full so no new decals can't be placed 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. BoundingSphere decalSphere = new BoundingSphere(intersection.IntersectionPointInObjectSpace, decalSize); m_neighbourTriangles.Clear(); intersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, intersection.NormalInObjectSpace, MyDecalsConstants.MAX_NEIGHBOUR_ANGLE, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles); int trianglesToAdd = m_neighbourTriangles.Count; if (trianglesToAdd == 0) { return; } if (decalsBuffer.CanAddTriangles(trianglesToAdd)) { Vector3 normalSum = Vector3.Zero; if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS) { normalSum = CalculateDominantNormal(m_neighbourTriangles); normalSum *= decalNormalOffset; } // Create decal for every neighbour triangleVertexes for (int i = 0; i < m_neighbourTriangles.Count; i++) { trianglesToAdd--; if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS) { 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.Triangle.InputTriangleNormal, ref rightPlane, ref upPlane, decalScale, decalSize, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInObjectSpace, emissivity); } } }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyEntity entity, MyDecalTexturesEnum decalTexture) { Entity = entity; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; if (MyDecals.IsLargeTexture(decalTexture) == true) { //m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; } else { //m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyEntity entity, MyDecalTexturesEnum decalTexture) { Entity = entity; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; if (MyDecals.IsLargeTexture(decalTexture) == true) { //m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; } else { //m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyRenderVoxelCell voxelMap, MyDecalTexturesEnum decalTexture) { VoxelCell = voxelMap; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; /* * if (MyDecals.IsLargeTexture(decalTexture) == true) * { * m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; * m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); * m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); * MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; * } * else*/ { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyVoxelMap voxelMap, ref MyMwcVector3Int renderCellCoord, MyDecalTexturesEnum decalTexture, ref BoundingBox renderCellBoundingBox) { VoxelMap = voxelMap; RenderCellCoord = renderCellCoord; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; RenderCellBoundingBox = renderCellBoundingBox; if (MyDecals.IsLargeTexture(decalTexture) == true) { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; } else { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyVoxelMap voxelMap, ref MyMwcVector3Int renderCellCoord, MyDecalTexturesEnum decalTexture, ref BoundingBox renderCellBoundingBox) { VoxelMap = voxelMap; RenderCellCoord = renderCellCoord; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; RenderCellBoundingBox = renderCellBoundingBox; if (MyDecals.IsLargeTexture(decalTexture) == true) { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; } else { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
// Add decal and all surounding triangles for model intersection internal static void AddDecal(MyRenderObject renderObject, ref MyDecalTriangle_Data triangle, int trianglesToAdd, MyDecalTexturesEnum decalTexture, Vector3D position, float lightSize, float emissivity) { IMyDecalsBuffer decalsBuffer = null; if (renderObject is MyRenderVoxelCell) { // If we get null, buffer is full so no new decals can't be placed decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(renderObject as MyRenderVoxelCell, decalTexture); } else if (renderObject is MyRenderTransformObject) { decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); } if (renderObject is MyManualCullableRenderObject) { decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); } // If we get null, buffer is full so no new decals can't be placed if (decalsBuffer == null) { return; } if (decalsBuffer.CanAddTriangles(trianglesToAdd)) { Vector3 normalSum = Vector3.Zero; decalsBuffer.Add(triangle, trianglesToAdd, position, lightSize, emissivity); } }
public MyDecalsForModelsDictionaryKey(MyEntity physObject, MyDecalTexturesEnum decalTexture) { PhysObject = physObject; DecalTexture = decalTexture; }
public MyDecalsForRenderObjectsTriangleBuffer GetTrianglesBuffer(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { MyDecalsForModelsDictionaryKey key = new MyDecalsForModelsDictionaryKey(renderObject, decalTexture); MyDecalsForRenderObjectsTriangleBuffer outValue; if (m_triangleBuffersByKey.TryGetValue(key, out outValue)) { // Combination of model/texture was found in dictionary, so we can return in right now return(outValue); } else { if (m_triangleBuffersByKey.Count >= m_capacity) { // We are full, can't place decal on a new model/texture. Need to wait for next CheckBufferFull. return(null); } else { // This is first time we want to place decal on this model/texture, so here we allocate and initialize buffer MyDecalsForRenderObjectsTriangleBuffer newBuffer = m_freeTriangleBuffers.Pop(); m_triangleBuffersByKey.Add(key, newBuffer); m_usedTriangleBuffers.Add(newBuffer); newBuffer.Start(renderObject, decalTexture); return(newBuffer); } } }
public MyDecalsForModelsDictionaryKey(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { RenderObject = renderObject; DecalTexture = decalTexture; }
public MyDecalsForVoxelsDictionaryKey(int voxelMapId, ref MyMwcVector3Int renderCellCoord, MyDecalTexturesEnum decalTexture) { VoxelMapId = voxelMapId; RenderCellCoord = renderCellCoord; DecalTexture = decalTexture; }
public MyDecalsForModelsDictionaryKey(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { RenderObject = renderObject; DecalTexture = decalTexture; }
// Add decal and all surounding triangles for model intersection internal static void AddDecal(MyRenderObject renderObject, ref MyDecalTriangle_Data triangle, int trianglesToAdd, MyDecalTexturesEnum decalTexture, Vector3D position, float lightSize, float emissivity) { IMyDecalsBuffer decalsBuffer = null; if (renderObject is MyRenderVoxelCell) // If we get null, buffer is full so no new decals can't be placed decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(renderObject as MyRenderVoxelCell, decalTexture); else if (renderObject is MyRenderTransformObject) decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); if (renderObject is MyManualCullableRenderObject) { decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); } // If we get null, buffer is full so no new decals can't be placed if (decalsBuffer == null) return; if (decalsBuffer.CanAddTriangles(trianglesToAdd)) { Vector3 normalSum = Vector3.Zero; decalsBuffer.Add(triangle, trianglesToAdd, position, lightSize, emissivity); } }
public MyDecalsForVoxelsTriangleBuffer GetTrianglesBuffer(MyVoxelMap voxelMap, ref MyMwcVector3Int renderCellCoord, MyDecalTexturesEnum decalTexture, ref BoundingBox renderCellBoundingBox) { MyDecalsForVoxelsDictionaryKey key = new MyDecalsForVoxelsDictionaryKey(voxelMap.VoxelMapId, ref renderCellCoord, decalTexture); MyDecalsForVoxelsTriangleBuffer outValue; if (m_triangleBuffersByKey.TryGetValue(key, out outValue) == true) { // Combination of cell/texture was found in dictionary, so we can return in right now return(outValue); } else { if (m_triangleBuffersByKey.Count >= m_capacity) { // We are full, can't place decal on a new cell/texture. Need to wait for next CheckBufferFull. return(null); } else { // This is first time we want to place decal to this cell/texture, so here we allocate and initialize buffer MyDecalsForVoxelsTriangleBuffer newBuffer = m_freeTriangleBuffers.Pop(); m_triangleBuffersByKey.Add(key, newBuffer); m_usedTriangleBuffers.Enqueue(newBuffer); newBuffer.Start(voxelMap, ref renderCellCoord, decalTexture, ref renderCellBoundingBox); return(newBuffer); } } }
public MyDecalsForModelsDictionaryKey(MyEntity physObject, MyDecalTexturesEnum decalTexture) { PhysObject = physObject; DecalTexture = decalTexture; }
public MyDecalsForVoxelsDictionaryKey(uint voxelMapId, MyDecalTexturesEnum decalTexture) { VoxelMapId = voxelMapId; DecalTexture = decalTexture; }
// Add decal and all surounding triangles according to the type of intersection (model or voxel) public static void Add(MyDecalTexturesEnum decalTexture, float decalSize, float angle, Vector4 color, bool alphaBlendByAngle, ref MyIntersectionResultLineTriangleEx intersection, float lightSize, float emissivity, float decalNormalOffset) { if (!MyRenderConstants.RenderQualityProfile.EnableDecals) { return; } // Ignore decals too far away if (Vector3.Distance(MyCamera.Position, intersection.IntersectionPointInWorldSpace) > (MyDecalsConstants.MAX_DISTANCE_FOR_ADDING_DECALS / MyCamera.Zoom.GetZoomLevel())) { return; } // Polomer decalu a scale faktor pre vypocet textury. // Decal size is something as radius of a decal, so when converting from real metres to texture space, we need to divide by 2.0 float decalScale = 1.0f / (2.0f * decalSize); // Fix: This is safer way to get right vector. Vector3 rightVector; MyTriangle_Vertexes triangle = intersection.Triangle.InputTriangle; if ((triangle.Vertex0 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON) { rightVector = MyMwcUtils.Normalize(triangle.Vertex0 - intersection.IntersectionPointInObjectSpace); } else if ((triangle.Vertex1 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON) { rightVector = MyMwcUtils.Normalize(triangle.Vertex1 - intersection.IntersectionPointInObjectSpace); } else if ((triangle.Vertex2 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON) { rightVector = MyMwcUtils.Normalize(triangle.Vertex2 - intersection.IntersectionPointInObjectSpace); } else { System.Diagnostics.Debug.Assert(false, "Normal has zero length! Probably invalid intersection point!"); return; } Vector3 upVector = Vector3.Cross(rightVector, intersection.NormalInObjectSpace); if (!MyMwcUtils.HasValidLength(upVector)) { //System.Diagnostics.Debug.Assert(false, "Invalid result of cross produt!"); return; } upVector = MyMwcUtils.Normalize(upVector); // We create world matrix for the decal and then rotate the matrix, so we can extract rotated right/up vectors/planes for texture coord0 calculations Matrix decalMatrix = Matrix.CreateRotationZ(angle) * Matrix.CreateWorld(intersection.IntersectionPointInObjectSpace, intersection.NormalInObjectSpace, upVector); // Right plane MyPlane rightPlane; rightPlane.Point = intersection.IntersectionPointInObjectSpace; rightPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Right, ref decalMatrix); // Up plane MyPlane upPlane; upPlane.Point = intersection.IntersectionPointInObjectSpace; upPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Up, ref decalMatrix); if (intersection.Entity is MyVoxelMap) { AddDecalVoxel(decalTexture, decalSize, decalScale, color, alphaBlendByAngle, ref intersection, ref rightPlane, ref upPlane, lightSize, emissivity, decalNormalOffset); } else { AddDecalModel(decalTexture, decalSize, decalScale, color, alphaBlendByAngle, ref intersection, ref rightPlane, ref upPlane, lightSize, emissivity, decalNormalOffset); } }
// Add decal and all surounding triangles according to the type of intersection (model or voxel) public static void Add(MyDecalTexturesEnum decalTexture, float decalSize, float angle, Vector4 color, bool alphaBlendByAngle, ref MyIntersectionResultLineTriangleEx intersection, float lightSize, float emissivity, float decalNormalOffset) { if (!MyRenderConstants.RenderQualityProfile.EnableDecals) return; // Ignore decals too far away if (Vector3.Distance(MyCamera.Position, intersection.IntersectionPointInWorldSpace) > (MyDecalsConstants.MAX_DISTANCE_FOR_ADDING_DECALS / MyCamera.Zoom.GetZoomLevel())) return; // Polomer decalu a scale faktor pre vypocet textury. // Decal size is something as radius of a decal, so when converting from real metres to texture space, we need to divide by 2.0 float decalScale = 1.0f / (2.0f * decalSize); // Fix: This is safer way to get right vector. Vector3 rightVector; MyTriangle_Vertexes triangle = intersection.Triangle.InputTriangle; if ((triangle.Vertex0 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON) { rightVector = MyMwcUtils.Normalize(triangle.Vertex0 - intersection.IntersectionPointInObjectSpace); } else if ((triangle.Vertex1 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON) { rightVector = MyMwcUtils.Normalize(triangle.Vertex1 - intersection.IntersectionPointInObjectSpace); } else if ((triangle.Vertex2 - intersection.IntersectionPointInObjectSpace).Length() > MyMwcMathConstants.EPSILON) { rightVector = MyMwcUtils.Normalize(triangle.Vertex2 - intersection.IntersectionPointInObjectSpace); } else { System.Diagnostics.Debug.Assert(false, "Normal has zero length! Probably invalid intersection point!"); return; } Vector3 upVector = Vector3.Cross(rightVector, intersection.NormalInObjectSpace); if (!MyMwcUtils.HasValidLength(upVector)) { //System.Diagnostics.Debug.Assert(false, "Invalid result of cross produt!"); return; } upVector = MyMwcUtils.Normalize(upVector); // We create world matrix for the decal and then rotate the matrix, so we can extract rotated right/up vectors/planes for texture coord0 calculations Matrix decalMatrix = Matrix.CreateRotationZ(angle) * Matrix.CreateWorld(intersection.IntersectionPointInObjectSpace, intersection.NormalInObjectSpace, upVector); // Right plane MyPlane rightPlane; rightPlane.Point = intersection.IntersectionPointInObjectSpace; rightPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Right, ref decalMatrix); // Up plane MyPlane upPlane; upPlane.Point = intersection.IntersectionPointInObjectSpace; upPlane.Normal = MyUtils.GetTransformNormalNormalized(Vector3.Up, ref decalMatrix); if (intersection.Entity is MyVoxelMap) { AddDecalVoxel(decalTexture, decalSize, decalScale, color, alphaBlendByAngle, ref intersection, ref rightPlane, ref upPlane, lightSize, emissivity, decalNormalOffset); } else { AddDecalModel(decalTexture, decalSize, decalScale, color, alphaBlendByAngle, ref intersection, ref rightPlane, ref upPlane, lightSize, emissivity, decalNormalOffset); } }
public static bool IsLargeTexture(MyDecalTexturesEnum decalTexture) { if (decalTexture == MyDecalTexturesEnum.ExplosionSmut) return true; return false; }
// Add decal and all surounding triangles for model intersection static void AddDecalModel(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) { MyDecalsForPhysObjectsTriangleBuffer decalsBuffer = m_decalsForModels.GetTrianglesBuffer(intersection.Entity, decalTexture); // If we get null, buffer is full so no new decals can't be placed 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. BoundingSphere decalSphere = new BoundingSphere(intersection.IntersectionPointInObjectSpace, decalSize); m_neighbourTriangles.Clear(); intersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, intersection.NormalInObjectSpace, MyDecalsConstants.MAX_NEIGHBOUR_ANGLE, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles); int trianglesToAdd = m_neighbourTriangles.Count; if (trianglesToAdd == 0) { return; } if (decalsBuffer.CanAddTriangles(trianglesToAdd)) { Vector3 normalSum = Vector3.Zero; if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS) { normalSum = CalculateDominantNormal(m_neighbourTriangles); normalSum *= decalNormalOffset; } // Create decal for every neighbour triangleVertexes for (int i = 0; i < m_neighbourTriangles.Count; i++) { trianglesToAdd--; if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS) { 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.Triangle.InputTriangleNormal, ref rightPlane, ref upPlane, decalScale, decalSize, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInObjectSpace, emissivity); } } }
// 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); } } }