示例#1
0
        /// <returns>True if visible decals are found</returns>
        private static bool IterateVisibleRenderIDs(HashSet <uint> visibleRenderIDs, MyDecalFlags targetFlag, float squaredDistanceMax, uint sinceStartTs)
        {
            bool ret = false;

            foreach (uint renderID in visibleRenderIDs)
            {
                List <DecalNode> decals;
                bool             found = m_entityDecals.TryGetValue(renderID, out decals);
                if (!found)
                {
                    continue;
                }

                foreach (DecalNode node in decals)
                {
                    if (node.Value.FadeTimestamp < sinceStartTs)
                    {
                        RemoveDecalByNode(node);
                        continue;
                    }

                    MyScreenDecal decal = node.Value;
                    MyDecalFlags  flag  = decal.Flags & MyDecalFlags.Transparent;
                    if (flag == targetFlag && IsDecalWithinRadius(decal, squaredDistanceMax))
                    {
                        AddDecalNodeForDraw(node);
                        ret = true;
                    }
                }
            }

            return(ret);
        }
示例#2
0
        /// <returns>True if visible decals are found</returns>
        private static bool IterateDecals(HashSet <uint> visibleRenderIDs, MyDecalFlags targetFlag, float squaredDistanceMax, uint sinceStartTs)
        {
            bool ret = false;

            int       count   = m_decals.Count;
            DecalNode current = m_decals.First;
            int       it      = 0;

            while (current != null && it < count)
            {
                DecalNode next = current.Next;
                if (current.Value.FadeTimestamp < sinceStartTs)
                {
                    RemoveDecalByNode(current);
                    current = next;
                    continue;
                }

                MyScreenDecal decal = current.Value;
                MyDecalFlags  flag  = decal.Flags & MyDecalFlags.Transparent;
                if (flag == targetFlag && (visibleRenderIDs == null || visibleRenderIDs.Contains(decal.ParentID)) &&
                    IsDecalWithinRadius(decal, squaredDistanceMax))
                {
                    AddDecalNodeForDraw(current);
                    ret = true;
                }

                current = next;
                it++;
            }

            return(ret);
        }
        // ENABLE-ME: As soon as a relieble list of frustum visible ojects IDs is available
        internal static void Draw(HashSet <uint> visibleRenderIDs, bool transparent)
        {
            if (m_decals.Count == 0)
            {
                return;
            }

            uint sinceStartTs = GetTimeStampSinceStart();

            MyDecalFlags targetFlag = transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;

            bool visibleDecals;

            if (visibleRenderIDs.Count > m_decals.Count)
            {
                visibleDecals = IterateDecals(visibleRenderIDs, targetFlag, sinceStartTs);
            }
            else
            {
                visibleDecals = IterateVisibleRenderIDs(visibleRenderIDs, targetFlag, sinceStartTs);
            }

            if (!visibleDecals)
            {
                return;
            }

            DrawInternal(transparent, sinceStartTs);
        }
示例#4
0
        /// <param name="visibleRenderIDs">Optional list of visible render object IDs</param>
        internal static void Draw(bool transparent, HashSet <uint> visibleRenderIDs = null, float squaredDistanceMax = VISIBLE_DECALS_SQ_TH)
        {
            if (m_decals.Count == 0)
            {
                return;
            }

            uint         sinceStartTs = GetTimeStampSinceStart();
            MyDecalFlags targetFlag   = transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;

            bool visibleDecals;

            if (visibleRenderIDs == null || visibleRenderIDs.Count > m_decals.Count)
            {
                visibleDecals = IterateDecals(visibleRenderIDs, targetFlag, squaredDistanceMax, sinceStartTs);
            }
            else
            {
                visibleDecals = IterateVisibleRenderIDs(visibleRenderIDs, targetFlag, squaredDistanceMax, sinceStartTs);
            }

            if (!visibleDecals)
            {
                return;
            }

            DrawInternal(transparent, sinceStartTs);
        }
        /// <returns>True if visible decals are found</returns>
        private static bool IterateDecals(HashSet <uint> visibleRenderIDs, MyDecalFlags targetFlag, uint sinceStartTs)
        {
            bool ret = false;

            int       count   = m_decals.Count;
            DecalNode current = m_decals.First;
            int       it      = 0;

            while (current != null && it < count)
            {
                DecalNode next = current.Next;
                if (current.Value.FadeTimestamp < sinceStartTs)
                {
                    RemoveDecalByNode(current);
                    current = next;
                    continue;
                }

                MyDecalFlags flag = current.Value.Flags & MyDecalFlags.Transparent;
                if (flag == targetFlag && visibleRenderIDs.Contains(current.Value.ParentID))
                {
                    AddDecalNodeForDraw(current);
                    ret = true;
                }

                current = next;
                it++;
            }

            return(ret);
        }
        private static Matrix ComputeOBB(ref MyDecalTopoData data, MyDecalFlags flags)
        {
            var perp = Vector3.CalculatePerpendicularVector(data.Normal);

            if (data.Rotation != 0)
            {
                // Rotate around normal
                Quaternion q = Quaternion.CreateFromAxisAngle(data.Normal, data.Rotation);
                perp = new Vector3((new Quaternion(perp, 0) * q).ToVector4());
            }

            Matrix pos = Matrix.CreateWorld(data.Position, data.Normal, perp);

            return(Matrix.CreateScale(data.Scale) * pos);
        }
        internal static void Draw(bool transparent)
        {
            if (m_decals.Count == 0)
            {
                return;
            }

            uint sinceStart = GetTimeStampSinceStart();

            MyDecalFlags targetFlag   = transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;
            bool         decalsToDraw = false;

            DecalNode current = m_decals.First;

            while (current != null)
            {
                DecalNode next = current.Next;
                if (current.Value.FadeTimestamp < sinceStart)
                {
                    RemoveDecalByNode(current);
                    current = next;
                    continue;
                }

                MyDecalFlags flag = current.Value.Flags & MyDecalFlags.Transparent;
                if (targetFlag == flag)
                {
                    AddDecalForDraw(current.Value);
                    decalsToDraw = true;
                }

                current = next;
            }

            if (!decalsToDraw)
            {
                return;
            }

            DrawInternal(transparent, sinceStart);
        }
示例#8
0
        internal static void AddDecal(uint ID, uint ParentID, ref MyDecalTopoData topoData, MyDecalFlags flags, string sourceTarget, string material, int matIndex)
        {
            if (m_decals.Count >= m_decalsQueueSize && m_decals.Count != 0)
            {
                MarkForRemove(m_decals.First);
            }

            MyScreenDecal decal = new MyScreenDecal();

            decal.FadeTimestamp = uint.MaxValue;
            decal.ID            = ID;
            decal.ParentID      = ParentID;
            decal.TopoData      = topoData;
            decal.Flags         = flags;
            decal.SourceTarget  = sourceTarget;
            decal.Material      = material;
            decal.MaterialId    = X.TEXT_(material);
            decal.MaterialIndex = matIndex;

            if (!flags.HasFlag(MyDecalFlags.World))
            {
                var parent = MyIDTracker <MyActor> .FindByID(ParentID);

                if (parent == null)
                {
                    return;
                }

                decal.TopoData.WorldPosition = Vector3D.Transform(topoData.MatrixCurrent.Translation, ref parent.WorldMatrix);
            }

            DecalNode node = m_decals.AddLast(decal);

            m_nodeMap[ID] = node;

            List <DecalNode> handles;
            bool             found = m_entityDecals.TryGetValue(ParentID, out handles);

            if (!found)
            {
                handles = new List <DecalNode>();
                m_entityDecals.Add(ParentID, handles);
            }

            handles.Add(node);
        }
        public static void AddDecal(uint ID, uint ParentID, ref MyDecalTopoData data, MyDecalFlags flags, string sourceTarget, string material, int matIndex)
        {
            if (m_decals.Count == m_decalsQueueSize)
            {
                MarkForRemove(m_decals.First.Value);
            }

            MyScreenDecal decal = new MyScreenDecal();

            decal.FadeTimestamp = uint.MaxValue;
            decal.ID            = ID;
            decal.ParentID      = ParentID;
            decal.Data          = data;
            decal.Flags         = flags;
            decal.OBBox         = ComputeOBB(ref data, flags);
            decal.SourceTarget  = sourceTarget;
            decal.Material      = material;
            decal.MaterialId    = X.TEXT_(material);
            decal.MaterialIndex = matIndex;

            DecalNode node = m_decals.AddLast(decal);

            m_nodeMap[ID] = node;

            List <DecalNode> handles;
            bool             found = m_entityDecals.TryGetValue(ParentID, out handles);

            if (!found)
            {
                handles = new List <DecalNode>();
                m_entityDecals.Add(ParentID, handles);
            }

            handles.Add(node);
        }
示例#10
0
        public static uint CreateDecal(int parentId, ref MyDecalTopoData data, MyDecalFlags flags, string sourceTarget, string material, int matIndex)
        {
            var message = MessagePool.Get<MyRenderMessageCreateScreenDecal>(MyRenderMessageEnum.CreateScreenDecal);
            message.ID = GetMessageId(ObjectType.ScreenDecal);
            message.ParentID = (uint) parentId;
            message.TopoData = data;
            message.SourceTarget = sourceTarget;
            message.Flags = flags;
            message.Material = material;
            message.MaterialIndex = matIndex;

            EnqueueMessage(message);

            return message.ID;
        }
示例#11
0
        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;

            MyDecalFlags flags = material.Transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;

            string sourceTarget = MyDecalMaterials.GetStringId(Source, data.Material);

            return(MyRenderProxy.CreateDecal(data.RenderObjectId, ref topoData, data.Flags | flags, sourceTarget, material.StringId, index));
        }