public MyDecalsForPhysObjectsTriangleBuffer GetTrianglesBuffer(MyEntity physObject, MyDecalTexturesEnum decalTexture)
        {
            MyDecalsForModelsDictionaryKey key = new MyDecalsForModelsDictionaryKey(physObject, decalTexture);

            MyDecalsForPhysObjectsTriangleBuffer 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
                    MyDecalsForPhysObjectsTriangleBuffer newBuffer = m_freeTriangleBuffers.Pop();
                    m_triangleBuffersByKey.Add(key, newBuffer);
                    m_usedTriangleBuffers.Add(newBuffer);
                    newBuffer.Start(physObject, decalTexture);
                    return(newBuffer);
                }
            }
        }
Ejemplo n.º 2
0
        //  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);
                }
            }
        }
        public void ReturnTrianglesBuffer(MyEntity physObject)
        {
            foreach (byte value in Enum.GetValues(typeof(MyDecalTexturesEnum)))
            {
                var key = new MyDecalsForModelsDictionaryKey(physObject, (MyDecalTexturesEnum)value);

                MyDecalsForPhysObjectsTriangleBuffer outValue;
                if (m_triangleBuffersByKey.TryGetValue(key, out outValue))
                {
                    MyDecalsForPhysObjectsTriangleBuffer usedBuffer = outValue;

                    m_triangleBuffersByKey.Remove(key);
                    usedBuffer.Clear();
                    m_usedTriangleBuffers.Remove(usedBuffer);
                    m_freeTriangleBuffers.Push(usedBuffer);
                }
            }
        }
        public MyDecalsForPhysObjects(int capacity)
        {
            m_status                = MyDecalForModelsState.READY;
            m_capacity              = capacity;
            m_fadingOutStartLimit   = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT);
            m_fadingOutBuffersCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT);

            m_sortTriangleBuffersByTexture = new List <MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);
            m_triangleBuffersByKey         = new Dictionary <MyDecalsForModelsDictionaryKey, MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);
            m_freeTriangleBuffers          = new Stack <MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);
            m_usedTriangleBuffers          = new List <MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);

            m_triangleBuffers = new MyDecalsForPhysObjectsTriangleBuffer[m_capacity];
            for (int i = 0; i < m_capacity; i++)
            {
                m_triangleBuffers[i] = new MyDecalsForPhysObjectsTriangleBuffer(MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER);
                m_freeTriangleBuffers.Push(m_triangleBuffers[i]);
            }
        }
        public MyDecalsForPhysObjects(int capacity)
        {
            m_status = MyDecalForModelsState.READY;
            m_capacity = capacity;
            m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT);
            m_fadingOutBuffersCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT);

            m_sortTriangleBuffersByTexture = new List<MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);
            m_triangleBuffersByKey = new Dictionary<MyDecalsForModelsDictionaryKey, MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);
            m_freeTriangleBuffers = new Stack<MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);
            m_usedTriangleBuffers = new List<MyDecalsForPhysObjectsTriangleBuffer>(m_capacity);

            m_triangleBuffers = new MyDecalsForPhysObjectsTriangleBuffer[m_capacity];
            for (int i = 0; i < m_capacity; i++)
            {
                m_triangleBuffers[i] = new MyDecalsForPhysObjectsTriangleBuffer(MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER);
                m_freeTriangleBuffers.Push(m_triangleBuffers[i]);
            }
        }
        public void CheckIfBufferIsFull()
        {
            if (m_status == MyDecalForModelsState.FADING_OUT)
            {
                if ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_fadingOutStartTime) > MyDecalsConstants.DECALS_FADE_OUT_INTERVAL_MILISECONDS)
                {
                    //  If fading-out phase finished, we change state and remove faded-out buffers
                    for (int i = 0; i < m_fadingOutBuffersCount; i++)
                    {
                        if (m_usedTriangleBuffers.Count > 0)
                        {
                            MyDecalsForPhysObjectsTriangleBuffer releasedBuffer = m_usedTriangleBuffers[0];
                            m_usedTriangleBuffers.RemoveAt(0);
                            releasedBuffer.Clear();
                            m_freeTriangleBuffers.Push(releasedBuffer);
                            m_triangleBuffersByKey.Remove(new MyDecalsForModelsDictionaryKey(releasedBuffer.Entity, releasedBuffer.DecalTexture));
                        }
                    }

                    m_status = MyDecalForModelsState.READY;
                }
            }
            else
            {
                if (m_triangleBuffersByKey.Count >= m_fadingOutStartLimit)
                {
                    int i = 0;
                    foreach (MyDecalsForPhysObjectsTriangleBuffer buffer in m_usedTriangleBuffers)
                    {
                        if (i < m_fadingOutBuffersCount)
                        {
                            buffer.FadeOutAll();
                        }
                        i++;
                    }

                    m_status             = MyDecalForModelsState.FADING_OUT;
                    m_fadingOutStartTime = MyMinerGame.TotalGamePlayTimeInMilliseconds;
                }
            }
        }
        public void Draw(MyVertexFormatDecal[] vertices, MyEffectDecals effect, MyTexture2D[] texturesDiffuse, MyTexture2D[] texturesNormalMap)
        {
            CheckIfBufferIsFull();

            //  SortForSAP buffers by texture
            m_sortTriangleBuffersByTexture.Clear();
            foreach (MyDecalsForPhysObjectsTriangleBuffer buffer in m_usedTriangleBuffers)
            {
                if (buffer.Entity.IsVisible() == true)
                {
                    if ((buffer.Entity == MyGuiScreenGamePlay.Static.ControlledEntity ||
                         buffer.Entity.Parent == MyGuiScreenGamePlay.Static.ControlledEntity) &&
                        MyGuiScreenGamePlay.Static.IsFirstPersonView)
                    {
                        //  Don't draw decals if they are on an entity in which the camera is
                        continue;
                    }

                    // Decal with "ExplosionSmut" texture is much larger, so it must be drawed to larger distance.
                    float fadeoutDistance = MyDecals.GetMaxDistanceForDrawingDecals();
                    if (buffer.DecalTexture == MyDecalTexturesEnum.ExplosionSmut)
                    {
                        fadeoutDistance *= MyDecalsConstants.DISTANCE_MULTIPLIER_FOR_LARGE_DECALS;
                    }

                    //if (Vector3.Distance(MyCamera.m_initialSunWindPosition, buffer.PhysObject.GetPosition()) >= (MyDecals.GetMaxDistanceForDrawingDecals()))
                    //if (buffer.PhysObject.GetDistanceBetweenCameraAndBoundingSphere() >= MyDecals.GetMaxDistanceForDrawingDecals())
                    if (buffer.Entity.GetDistanceBetweenCameraAndBoundingSphere() >= fadeoutDistance)
                    {
                        continue;
                    }

                    m_sortTriangleBuffersByTexture.Add(buffer);
                }
            }
            m_sortTriangleBuffersByTexture.Sort();

            //  Draw decals - sorted by texture
            MyDecalTexturesEnum?lastDecalTexture = null;

            for (int i = 0; i < m_sortTriangleBuffersByTexture.Count; i++)
            {
                MyDecalsForPhysObjectsTriangleBuffer buffer = m_sortTriangleBuffersByTexture[i];

                int trianglesCount = buffer.CopyDecalsToVertices(vertices);

                if (trianglesCount <= 0)
                {
                    continue;
                }

                //  Switch texture only if different than previous one
                if ((lastDecalTexture == null) || (lastDecalTexture != buffer.DecalTexture))
                {
                    int textureIndex = (int)buffer.DecalTexture;
                    effect.SetDecalDiffuseTexture(texturesDiffuse[textureIndex]);
                    effect.SetDecalNormalMapTexture(texturesNormalMap[textureIndex]);
                    lastDecalTexture = buffer.DecalTexture;
                }

                //effect.SetWorldMatrix(buffer.Entity.WorldMatrix * Matrix.CreateTranslation(-MyCamera.Position));
                effect.SetWorldMatrix(buffer.Entity.GetWorldMatrixForDraw());
                effect.SetViewProjectionMatrix(MyCamera.ViewProjectionMatrixAtZero);

                // set FadeoutDistance
                float fadeoutDistance = MyDecals.GetMaxDistanceForDrawingDecals();
                if (buffer.DecalTexture == MyDecalTexturesEnum.ExplosionSmut)
                {
                    fadeoutDistance *= MyDecalsConstants.DISTANCE_MULTIPLIER_FOR_LARGE_DECALS;
                }

                effect.SetFadeoutDistance(fadeoutDistance);

                if (!MyRenderConstants.RenderQualityProfile.ForwardRender)
                {
                    effect.SetTechnique(MyEffectDecals.Technique.Model);
                }
                else
                {
                    effect.SetTechnique(MyEffectDecals.Technique.ModelForward);
                }

                MyMinerGame.Static.GraphicsDevice.VertexDeclaration = MyVertexFormatDecal.VertexDeclaration;

                effect.Begin();
                MyMinerGame.Static.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, 0, trianglesCount, vertices);
                effect.End();

                MyPerformanceCounter.PerCameraDraw.DecalsForEntitiesInFrustum += trianglesCount;
            }
        }
Ejemplo n.º 8
0
        //  For sorting buffers by texture
        public int CompareTo(object compareToObject)
        {
            MyDecalsForPhysObjectsTriangleBuffer compareToBuffer = (MyDecalsForPhysObjectsTriangleBuffer)compareToObject;

            return(((int)compareToBuffer.DecalTexture).CompareTo((int)this.DecalTexture));
        }