//  This method is like a constructor (which we can't use because billboards are allocated from a pool).
        //  It starts/initializes a billboard. Refs used only for optimalization
        public void Start(ref MyQuad quad, MyTransparentMaterialEnum materialEnum, MyTransparentMaterialEnum blendMaterial, float textureBlendRatio,
                          ref Vector4 color, ref Vector3 origin, Vector2 uvOffset, bool colorize = false, bool near = false, bool lowres = false)
        {
            MaterialEnum      = materialEnum;
            BlendMaterial     = blendMaterial;
            BlendTextureRatio = textureBlendRatio;

            MyUtils.AssertIsValid(quad.Point0);
            MyUtils.AssertIsValid(quad.Point1);
            MyUtils.AssertIsValid(quad.Point2);
            MyUtils.AssertIsValid(quad.Point3);


            //  Billboard vertexes
            Position0 = quad.Point0;
            Position1 = quad.Point1;
            Position2 = quad.Point2;
            Position3 = quad.Point3;

            UVOffset = uvOffset;

            EnableColorize = colorize;

            if (EnableColorize)
            {
                Size = (Position0 - Position2).Length();
            }

            //  Distance for sorting
            //  IMPORTANT: Must be calculated before we do color and alpha misting, because we need distance there
            DistanceSquared = Vector3.DistanceSquared(MyCamera.Position, origin);

            //  Color
            Color = color;

            Near   = near;
            Lowres = lowres;

            //  Alpha depends on distance to camera. Very close bilboards are more transparent, so player won't see billboard errors or rotating billboards
            var mat = MyTransparentMaterialConstants.GetMaterialProperties(MaterialEnum);

            if (mat.AlphaMistingEnable)
            {
                Color *= MathHelper.Clamp(((float)Math.Sqrt(DistanceSquared) - mat.AlphaMistingStart) / (mat.AlphaMistingEnd - mat.AlphaMistingStart), 0, 1);
            }

            ContainedBillboards.Clear();
        }
        public void Deserialize(XmlReader reader)
        {
            m_name = reader.GetAttribute("name");
            int version = Convert.ToInt32(reader.GetAttribute("version"));

            reader.ReadStartElement(); //ParticleGeneration

            foreach (IMyConstProperty property in m_properties)
            {
                if (reader.Name == "Emitter")
                {
                    break; //we added new property which is not in xml yet
                }
                property.Deserialize(reader);
            }

            reader.ReadStartElement();
            m_emitter.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadEndElement(); //ParticleGeneration

            //Disable texture blending if it is set but unneccessary
            if (BlendTextures)
            {
                bool someMaterialKeysDifferent = false;
                for (int j = 0; j < Material.GetKeysCount(); j++)
                {
                    MyAnimatedPropertyInt key;
                    float time;
                    Material.GetKey(j, out time, out key);

                    int previousMaterial = -1;
                    for (int i = 0; i < key.GetKeysCount(); i++)
                    {
                        float timeMat;
                        int   material;
                        key.GetKey(i, out timeMat, out material);

                        if (previousMaterial != -1 && (previousMaterial != material))
                        {
                            MyTransparentMaterialProperties prevMaterialProperties = MyTransparentMaterialConstants.GetMaterialProperties((MyTransparentMaterialEnum)previousMaterial);
                            MyTransparentMaterialProperties materialProperties     = MyTransparentMaterialConstants.GetMaterialProperties((MyTransparentMaterialEnum)material);
                            if (prevMaterialProperties.Texture != materialProperties.Texture)
                            {
                                someMaterialKeysDifferent = true;
                                break;
                            }
                        }
                        previousMaterial = material;
                    }

                    if (someMaterialKeysDifferent)
                    {
                        break;
                    }
                }

                if (!someMaterialKeysDifferent)
                {
                    BlendTextures.SetValue(false);
                }
            }
        }