uint? IMyDecalHandler.AddDecal(ref MyDecalRenderInfo data) { CheckEnabled(); IReadOnlyList<MyDecalMaterial> materials; bool found = MyDecalMaterials.TryGetDecalMaterial(Source.String, data.Material.String, out materials); if (!found) { if (MyFakes.ENABLE_USE_DEFAULT_DAMAGE_DECAL) found = MyDecalMaterials.TryGetDecalMaterial(DEFAULT, DEFAULT, out materials); if (!found) return null; } int index = (int)Math.Round(MyRandom.Instance.NextFloat() * (materials.Count - 1)); MyDecalMaterial material = materials[index]; float rotation = material.Rotation; if (material.Rotation == float.PositiveInfinity) rotation = MyRandom.Instance.NextFloat() * MathHelper.TwoPi; var size = material.MinSize; if (material.MaxSize > material.MinSize) size += MyRandom.Instance.NextFloat() * (material.MaxSize - material.MinSize); MyDecalTopoData topoData = new MyDecalTopoData(); topoData.Position = data.Position; topoData.Normal = data.Normal; topoData.Scale = new Vector3(size, size, material.Depth); topoData.Rotation = rotation; string sourceTarget = MyDecalMaterials.GetStringId(Source, data.Material); return MyRenderProxy.CreateDecal(data.RenderObjectId, ref topoData, data.Flags, sourceTarget, material.StringId, index); }
uint?IMyDecalHandler.AddDecal(ref MyDecalRenderInfo data) { CheckEnabled(); IReadOnlyList <MyDecalMaterial> materials; bool found = MyDecalMaterials.TryGetDecalMaterial(Source.String, data.Material.String, out materials); if (!found) { if (MyFakes.ENABLE_USE_DEFAULT_DAMAGE_DECAL) { found = MyDecalMaterials.TryGetDecalMaterial(DEFAULT, DEFAULT, out materials); } if (!found) { return(null); } } MyDecalBindingInfo binding; if (data.Binding == null) { binding = new MyDecalBindingInfo(); binding.Position = data.Position; binding.Normal = data.Normal; binding.Transformation = Matrix.Identity; } else { binding = data.Binding.Value; } int index = (int)Math.Round(MyRandom.Instance.NextFloat() * (materials.Count - 1)); MyDecalMaterial material = materials[index]; float rotation = material.Rotation; if (material.Rotation == float.PositiveInfinity) { rotation = MyRandom.Instance.NextFloat() * MathHelper.TwoPi; } var bindingPerp = Vector3.CalculatePerpendicularVector(binding.Normal); if (rotation != 0) { // Rotate around normal Quaternion q = Quaternion.CreateFromAxisAngle(binding.Normal, rotation); bindingPerp = new Vector3((new Quaternion(bindingPerp, 0) * q).ToVector4()); } bindingPerp = Vector3.Normalize(bindingPerp); var size = material.MinSize; if (material.MaxSize > material.MinSize) { size += MyRandom.Instance.NextFloat() * (material.MaxSize - material.MinSize); } Vector3 scale = new Vector3(size, size, material.Depth); MyDecalTopoData topoData = new MyDecalTopoData(); Matrix pos; Vector3 worldPosition; if (data.Flags.HasFlag(MyDecalFlags.World)) { // Using tre translation component here would loose accuracy pos = Matrix.CreateWorld(Vector3.Zero, binding.Normal, bindingPerp); worldPosition = data.Position; } else { pos = Matrix.CreateWorld(binding.Position, binding.Normal, bindingPerp); worldPosition = Vector3.Invalid; // Set in the render thread } topoData.MatrixBinding = Matrix.CreateScale(scale) * pos; topoData.WorldPosition = worldPosition; topoData.MatrixCurrent = binding.Transformation * topoData.MatrixBinding; topoData.BoneIndices = data.BoneIndices; topoData.BoneWeights = data.BoneWeights; string sourceTarget = MyDecalMaterials.GetStringId(Source, data.Material); return(MyRenderProxy.CreateDecal(data.RenderObjectId, ref topoData, data.Flags, sourceTarget, material.StringId, index)); }