public EELight(DVector3 Position, Vector3 Color, float Distance, float MaxLife)
 {
     this.Position = Position;
     this.Color = Color;
     this.Distance = Distance;
     this.MaxLife = MaxLife;
 }
        public MeshContainer(Engine.Serialize.Mesh M)
        {
            if (M != null)
            {
                LocalAABBMax = M.AABBMax;
                LocalAABBMin = M.AABBMin;

                VertexsCount = M.VertexCount;
                FaceCount = M.FaceCount;
                BytesPerVertex = M.VertexData.Length / VertexsCount;

                using (var vertices = new DataStream(BytesPerVertex * VertexsCount, true, true))
                {
                    vertices.WriteRange<byte>(M.VertexData, 0, M.VertexData.Length);
                    vertices.Position = 0;
                    Vertexs = new Buffer(ModelViewer.Program.device, vertices, BytesPerVertex * VertexsCount, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                    binding = new VertexBufferBinding(Vertexs, BytesPerVertex, 0);
                }

                using (var indices = new DataStream(4 * FaceCount * 3, true, true))
                {
                    indices.WriteRange<byte>(M.IndexData, 0, M.IndexData.Length);
                    indices.Position = 0;
                    Indices = new Buffer(ModelViewer.Program.device, indices, 4 * FaceCount * 3, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                }
            }
        }
        public MultiMeshContainer(Engine.Serialize.MeshesContainer MC)
        {
            if (MC != null)
            {
                //Transform = Matrix.Scaling(1);

                Hardpoints = MC.HardPoints;
                if (MC.Materials != null && MC.Geometry != null && MC.Geometry.Meshes != null)
                {
                    BSP = MC.Geometry.BSP;
                    LocalAABBMax = MC.Geometry.AABBMax;
                    LocalAABBMin = MC.Geometry.AABBMin;

                    Meshes = new Serialize.MeshLink[MC.Materials.Length];
                    Materials = new MaterialContainer[MC.Materials.Length];
                    for (int i = 0; i < MC.Materials.Length; i++)
                    {
                        Meshes[i] = MC.Geometry.Meshes[i];
                        Materials[i] = new MaterialContainer(MC.Materials[i]);
                    }

                    VertexsCount = MC.Geometry.VertexCount;
                    BytesPerVertex = MC.Geometry.VertexData.Length / VertexsCount;
                    FaceCount = MC.Geometry.IndexData.Length / 12;

                    using (var vertices = new DataStream(BytesPerVertex * VertexsCount, true, true))
                    {
                        vertices.WriteRange<byte>(MC.Geometry.VertexData, 0, MC.Geometry.VertexData.Length);
                        vertices.Position = 0;
                        Vertexs = new Buffer(ModelViewer.Program.device, vertices, BytesPerVertex * VertexsCount, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                        binding = new VertexBufferBinding(Vertexs, BytesPerVertex, 0);
                    }

                    using (var indices = new DataStream(4 * FaceCount * 3, true, true))
                    {
                        indices.WriteRange<byte>(MC.Geometry.IndexData, 0, MC.Geometry.IndexData.Length);
                        indices.Position = 0;
                        Indices = new Buffer(ModelViewer.Program.device, indices, 4 * FaceCount * 3, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                    }

                    BufferDescription bd = new BufferDescription();
                    bd.SizeInBytes = Marshal.SizeOf(typeof(ShaderConstants));
                    bd.Usage = ResourceUsage.Dynamic;
                    bd.BindFlags = BindFlags.ConstantBuffer;
                    bd.CpuAccessFlags = CpuAccessFlags.Write;
                    bd.OptionFlags = ResourceOptionFlags.None;
                    bd.StructureByteStride = 0;

                    constantsBuffer = new Buffer(ModelViewer.Program.device, bd);
                    constants = new ShaderConstants();
                }
            }
        }
        public static void DrawAABB(DVector3 Max, DVector3 Min, Vector3 color)
        {
            LineList.Add(new DebugLine(new DVector3(Max.X, Max.Y, Max.Z), new DVector3(Max.X, Max.Y, Min.Z), color));
            LineList.Add(new DebugLine(new DVector3(Max.X, Max.Y, Min.Z), new DVector3(Min.X, Max.Y, Min.Z), color));
            LineList.Add(new DebugLine(new DVector3(Min.X, Max.Y, Min.Z), new DVector3(Min.X, Max.Y, Max.Z), color));
            LineList.Add(new DebugLine(new DVector3(Min.X, Max.Y, Max.Z), new DVector3(Max.X, Max.Y, Max.Z), color));

            LineList.Add(new DebugLine(new DVector3(Max.X, Min.Y, Max.Z), new DVector3(Max.X, Min.Y, Min.Z), color));
            LineList.Add(new DebugLine(new DVector3(Max.X, Min.Y, Min.Z), new DVector3(Min.X, Min.Y, Min.Z), color));
            LineList.Add(new DebugLine(new DVector3(Min.X, Min.Y, Min.Z), new DVector3(Min.X, Min.Y, Max.Z), color));
            LineList.Add(new DebugLine(new DVector3(Min.X, Min.Y, Max.Z), new DVector3(Max.X, Min.Y, Max.Z), color));

            LineList.Add(new DebugLine(new DVector3(Max.X, Max.Y, Max.Z), new DVector3(Max.X, Min.Y, Max.Z), color));
            LineList.Add(new DebugLine(new DVector3(Max.X, Max.Y, Min.Z), new DVector3(Max.X, Min.Y, Min.Z), color));
            LineList.Add(new DebugLine(new DVector3(Min.X, Max.Y, Min.Z), new DVector3(Min.X, Min.Y, Min.Z), color));
            LineList.Add(new DebugLine(new DVector3(Min.X, Max.Y, Max.Z), new DVector3(Min.X, Min.Y, Max.Z), color));
        }
 public EELightShadow(DVector3 Position, Vector3 Color)
 {
     this.Position = Position;
     this.Color = Color;
     SCamera = new EEShadowCamera(1f, 1000f);
 }
 public static void DrawLocator(DVector3 Pos, double Size, Vector3 color)
 {
     LineList.Add(new DebugLine(new DVector3(Pos.X - Size, Pos.Y, Pos.Z), new DVector3(Pos.X + Size, Pos.Y, Pos.Z), color));
     LineList.Add(new DebugLine(new DVector3(Pos.X, Pos.Y - Size, Pos.Z), new DVector3(Pos.X, Pos.Y + Size, Pos.Z), color));
     LineList.Add(new DebugLine(new DVector3(Pos.X, Pos.Y, Pos.Z - Size), new DVector3(Pos.X, Pos.Y, Pos.Z + Size), color));
 }
 public static void DrawKDTree(KDtree KD, Vector3 Color)
 {
     if (KD != null && KD.Root != null)
     RecursyKD(KD.Root, Color);
 }
        public void SetSplit(Vector3[] Fr0, Vector3 PosN,float FovCor)
        {
            Vector3 tt_ = (Fr0[0] + Fr0[1] + Fr0[2] + Fr0[3] + Fr0[4] + Fr0[5] + Fr0[6] + Fr0[7]) / 8f;
            Update(PosN, tt_);
            //return;

            float maxX = 0, maxY = 0, minX = 0, minY = 0, maxZ = 0, minZ = 0;
            bool one = true;
            for (int t = 0; t < 8; t++ )
                {
                    Vector3 Temp = Fr0[t];
                    Vector3 T = Conversion.ToVector3(Vector3.Transform(Temp, viewMatrix));
                    float Ax = (float)System.Math.Asin(T.X / (new Vector3(T.X, 0f, T.Z)).Length());
                    float Ay = (float)System.Math.Asin(T.Y / (new Vector3(0f, T.Y, T.Z)).Length());
                    float Dz = (PosN - Temp).Length();
                    if (one)
                    {
                        minX = Ax;
                        maxX = Ax;
                        minY = Ay;
                        maxY = Ay;
                        minZ = Dz;
                        maxZ = Dz;
                        one = false;
                    }
                    if (Ax < minX) minX = Ax;
                    if (Ax > maxX) maxX = Ax;
                    if (Ay < minY) minY = Ay;
                    if (Ay > maxY) maxY = Ay;
                    if (Dz < minZ) minZ = Dz;
                    if (Dz > maxZ) maxZ = Dz;
                }

            float D_ = maxZ;// tt_.Length();
            float tminX = (float)System.Math.Sin(minX) * D_;
            float tminY = (float)System.Math.Sin(minY) * D_;
            float tmaxX = (float)System.Math.Sin(maxX) * D_;
            float tmaxY = (float)System.Math.Sin(maxY) * D_;
            //кусок кода для тестов
            //             ulong DD = 0, D = 0;
            //             unsafe
            //             {
            //                 SSEmath.SSEmath.CpuTicks((uint)&DD);
            //             }

            Vector3 t00 = new Vector3(tminX, tminY, D_);
            Vector3 t02 = new Vector3(tmaxX, tmaxY, D_);
            Vector3 t01 = new Vector3(tminX, tmaxY, D_);
            Vector3 t03 = new Vector3(tmaxX, tminY, D_);
            unsafe
            {
                Matrix invertViewMatrix = this.invertViewMatrix;

                t00 = Conversion.ToVector3(Vector3.Transform(t00, invertViewMatrix));
                t01 = Conversion.ToVector3(Vector3.Transform(t01, invertViewMatrix));
                t02 = Conversion.ToVector3(Vector3.Transform(t02, invertViewMatrix));
                t03 = Conversion.ToVector3(Vector3.Transform(t03, invertViewMatrix));

                //SSEmath.SSEmath.Transform_void_Vector3_Vector3_Vector3_Vector3_Matrix4x4((uint)&t00, (uint)&t01, (uint)&t02, (uint)&t03, (uint)&invertViewMatrix);
            }
            //кусок кода для тестов
            //             unsafe
            //             {
            //                 SSEmath.SSEmath.CpuTicks((uint)&D);
            //             }
            //             D -= DD;
            //             SSEmath.SSEmath.counter++;
            //             if (SSEmath.SSEmath.min > D)
            //             {
            //                 SSEmath.SSEmath.min = D;
            //             }
            //             if (SSEmath.SSEmath.counter == 5)
            //             {
            //                 SSEmath.SSEmath.counter = 0;
            //                 Console.WriteLine("min: " + SSEmath.SSEmath.min + "\treal: " + D);
            //                 SSEmath.SSEmath.min = 999999999;
            //             }
            //
            fov = (maxY - minY);// *FovCor;
            aspectRatio = (maxX - minX) / fov;

            Vector3 Cr = (t00 + t01 + t02 + t03) / 4f;
            farClip = maxZ * 2f;
            nearClip = minZ / 2f;

            Update(PosN, Cr);
        }
        public void Initialize()
        {
            LoadSky(0);

            Texture2DDescription descTex = new Texture2DDescription();
            descTex.ArraySize = 6;
            descTex.Width = Size;
            descTex.Height = Size;
            descTex.Usage = ResourceUsage.Default;
            descTex.CpuAccessFlags = CpuAccessFlags.None;
            descTex.Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm;
            descTex.SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0);
            descTex.MipLevels = MipLevel;
            descTex.BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget;
            descTex.OptionFlags = ResourceOptionFlags.GenerateMipMaps | ResourceOptionFlags.TextureCube;

            //Create the texture and shader view
            CubeTexture = new Texture2D(ModelViewer.Program.device, descTex);
            CubeSRV = new ShaderResourceView(ModelViewer.Program.device, CubeTexture);

            RenderTargetViewDescription RTVD = new RenderTargetViewDescription();
            RTVD.Format = descTex.Format;
            RTVD.Dimension = RenderTargetViewDimension.Texture2DArray;
            RTVD.Texture2DArray.FirstArraySlice = 0;
            RTVD.Texture2DArray.ArraySize = 1;
            RTVD.Texture2DArray.MipSlice = 0;

            CubeRenderTarget = new RenderTargetView[6];

            for (int i = 0; i < 6; i++)
            {
                RTVD.Texture2DArray.FirstArraySlice = i;
                CubeRenderTarget[i] = new RenderTargetView(ModelViewer.Program.device, CubeTexture, RTVD);
            }

            SamplerStateDescription a = new SamplerStateDescription();
            a.AddressU = TextureAddressMode.Clamp;
            a.AddressV = TextureAddressMode.Clamp;
            a.AddressW = TextureAddressMode.Clamp;
            a.Filter = Filter.MinMagMipLinear;
            SSWrapMipLinear = new SamplerState(ModelViewer.Program.device, a);

            MContains = new MeshContainer();
            MContains.BytesPerVertex = 20;
            MContains.FaceCount = 12;
            MContains.VertexsCount = 24;

            Vector3 vExtents = new Vector3(500, 500, 500);

            var vertices = new DataStream(MContains.BytesPerVertex * MContains.VertexsCount, true, true);

            //Back
            vertices.Write(new Vector3(-vExtents.X, -vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(1, 1));
            vertices.Write(new Vector3(-vExtents.X, vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(1, 0));
            vertices.Write(new Vector3(vExtents.X, vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(0, 0));
            vertices.Write(new Vector3(vExtents.X, -vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(0, 1));
            //Front
            vertices.Write(new Vector3(vExtents.X, -vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(1, 1));
            vertices.Write(new Vector3(vExtents.X, vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(1, 0));
            vertices.Write(new Vector3(-vExtents.X, vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(0, 0));
            vertices.Write(new Vector3(-vExtents.X, -vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(0, 1));
            //Bottom
            vertices.Write(new Vector3(-vExtents.X, -vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(0, 0));
            vertices.Write(new Vector3(-vExtents.X, -vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(0, 1));
            vertices.Write(new Vector3(vExtents.X, -vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(1, 1));
            vertices.Write(new Vector3(vExtents.X, -vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(1, 0));
            //Top
            vertices.Write(new Vector3(vExtents.X, vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(1, 1));
            vertices.Write(new Vector3(vExtents.X, vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(1, 0));
            vertices.Write(new Vector3(-vExtents.X, vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(0, 0));
            vertices.Write(new Vector3(-vExtents.X, vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(0, 1));
            //Left
            vertices.Write(new Vector3(-vExtents.X, vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(1, 0));
            vertices.Write(new Vector3(-vExtents.X, vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(0, 0));
            vertices.Write(new Vector3(-vExtents.X, -vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(0, 1));
            vertices.Write(new Vector3(-vExtents.X, -vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(1, 1));
            //Right
            vertices.Write(new Vector3(vExtents.X, -vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(0, 1));
            vertices.Write(new Vector3(vExtents.X, -vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(1, 1));
            vertices.Write(new Vector3(vExtents.X, vExtents.Y, vExtents.Z));
            vertices.Write(new Vector2(1, 0));
            vertices.Write(new Vector3(vExtents.X, vExtents.Y, -vExtents.Z));
            vertices.Write(new Vector2(0, 0));

            vertices.Position = 0;
            InputElement[] elements11 = new[] {
                new InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0, 0) ,
                new InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 12, 0)};

            MContains.Vertexs = new Buffer(ModelViewer.Program.device, vertices, MContains.BytesPerVertex * MContains.VertexsCount, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

            var indices = new DataStream(4 * MContains.FaceCount * 3, true, true);
            for (int x = 0; x < 6; x++)
            {
                indices.Write((int)(x * 4 + 0));
                indices.Write((int)(x * 4 + 1));
                indices.Write((int)(x * 4 + 2));

                indices.Write((int)(x * 4 + 2));
                indices.Write((int)(x * 4 + 3));
                indices.Write((int)(x * 4 + 0));
            }
            indices.Position = 0;

            MContains.Indices = new Buffer(ModelViewer.Program.device, indices, 4 * MContains.FaceCount * 3, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            MContains.binding = new VertexBufferBinding(MContains.Vertexs, MContains.BytesPerVertex, 0);

            EEEM = ContentManager.LoadEffect("Content/Shaders/SkyBox", elements11);

            // Подготовка константного буффера
            BufferDescription bd = new BufferDescription();
            bd.SizeInBytes = Marshal.SizeOf(typeof(SkyShaderConstants));
            bd.Usage = ResourceUsage.Dynamic;
            bd.BindFlags = BindFlags.ConstantBuffer;
            bd.CpuAccessFlags = CpuAccessFlags.Write;
            bd.OptionFlags = ResourceOptionFlags.None;
            bd.StructureByteStride = 0;

            SkyConstantsBuffer = new Buffer(ModelViewer.Program.device, bd);
            SSC = new SkyShaderConstants();
        }
        public MaterialContainer(Material M)
        {
            if (M != null)
            {
                Name = M.MaterialName;
                InputElement[] IE = GetInputElementFromShaderName(M.Shader);
                Effect = ContentManager.LoadEffect(M.Shader, IE);
                Diffuse = ContentManager.LoadTexture2D(M.Diffuse);
                UV2Diffuse = ContentManager.LoadTexture2D(M.UV2Diffuse);
                NormalMap = ContentManager.LoadTexture2D(M.NormalMap);
                SpecularMap = ContentManager.LoadTexture2D(M.SpecularMap);
                SelfMap = ContentManager.LoadTexture2D(M.SelfMap);

                MipNormal = NormalMap.Texture2d.Description.MipLevels > 7;
                MipSpecular = SpecularMap.Texture2d.Description.MipLevels > 7;
                MipDiffuse = Diffuse.Texture2d.Description.MipLevels > 7;
                MipSelf = SelfMap.Texture2d.Description.MipLevels > 7;
                MipUV2Diffuse = UV2Diffuse.Texture2d.Description.MipLevels > 7;

                DiffuseMultipler = M.DiffuseMultipler;
                SpecularMultipler = M.SpecularMultipler;
                SelfMultipler = M.SelfMultipler;
                DoubleSide = M.DoubleSide;
                Alpha = M.Alpha;

                if (Global.Settings.TextureFiltering > -1)
                {
                    if (MipDiffuse) DiffuseSamplerState = DrawHelper.SamplAnsWrapMip;
                    else DiffuseSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipSpecular) SpecularMapSamplerState = DrawHelper.SamplAnsWrapMip;
                    else SpecularMapSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipNormal) NormalMapSamplerState = DrawHelper.SamplAnsWrapMip;
                    else NormalMapSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipSelf) SelfMapSamplerState = DrawHelper.SamplAnsWrapMip;
                    else SelfMapSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipUV2Diffuse) UV2DiffuseSamplerState = DrawHelper.SamplAnsWrapMip;
                    else UV2DiffuseSamplerState = DrawHelper.SamplAnsWrap;
                }
                else if (Global.Settings.TextureFiltering == -1)
                {
                    if (MipDiffuse) DiffuseSamplerState = DrawHelper.SamplLinWrapMip;
                    else DiffuseSamplerState = DrawHelper.SamplLinWrap;
                    if (MipSpecular) SpecularMapSamplerState = DrawHelper.SamplLinWrapMip;
                    else SpecularMapSamplerState = DrawHelper.SamplLinWrap;
                    if (MipNormal) NormalMapSamplerState = DrawHelper.SamplLinWrapMip;
                    else NormalMapSamplerState = DrawHelper.SamplLinWrap;
                    if (MipSelf) SelfMapSamplerState = DrawHelper.SamplLinWrapMip;
                    else SelfMapSamplerState = DrawHelper.SamplLinWrap;
                    if (MipUV2Diffuse) UV2DiffuseSamplerState = DrawHelper.SamplLinWrapMip;
                    else UV2DiffuseSamplerState = DrawHelper.SamplLinWrap;
                }
                else
                {
                    if (MipDiffuse) DiffuseSamplerState = DrawHelper.SamplPntWrapMip;
                    else DiffuseSamplerState = DrawHelper.SamplPntWrap;
                    if (MipSpecular) SpecularMapSamplerState = DrawHelper.SamplPntWrapMip;
                    else SpecularMapSamplerState = DrawHelper.SamplPntWrap;
                    if (MipNormal) NormalMapSamplerState = DrawHelper.SamplPntWrapMip;
                    else NormalMapSamplerState = DrawHelper.SamplPntWrap;
                    if (MipSelf) SelfMapSamplerState = DrawHelper.SamplPntWrapMip;
                    else SelfMapSamplerState = DrawHelper.SamplPntWrap;
                    if (MipUV2Diffuse) UV2DiffuseSamplerState = DrawHelper.SamplPntWrapMip;
                    else UV2DiffuseSamplerState = DrawHelper.SamplPntWrap;
                }
            }
        }
        private static void GenerateSplit(EEDCamera Camera, DVector3 ShadowVector)
        {
            Vector3 Up = new Vector3(0, 1, 0);
            NewShadowPos = Camera.position;
            DVector3.Normalize(ShadowVector);
            float d = Vector3.Dot(ShadowVector, Up);
            if (d == 1 || d == -1)
            {
                Up = new Vector3(1, 0, 0);
            }
            NewShadowPos -= ShadowDistance * ShadowVector;

            const int ShadowStep = 50;
            NewShadowPos.X = ((int)NewShadowPos.X) / ShadowStep * ShadowStep;
            NewShadowPos.Y = ((int)NewShadowPos.Y) / ShadowStep * ShadowStep;
            NewShadowPos.Z = ((int)NewShadowPos.Z) / ShadowStep * ShadowStep;

            double Coff = 0.125f;
            for (int i = 0; i < SplitsNumber + 1; i++)
            {
                SplitSlices[i] = (Camera.nearClip + (Camera.farClip - Camera.nearClip) * (float)i / (float)SplitsNumber) * (Coff);
                SplitSlices[i] += (Camera.nearClip * System.Math.Pow(Camera.farClip / Camera.nearClip, (float)i / (float)SplitsNumber)) * (1 - Coff);
                SplitSlices[i] /= Camera.farClip;
                SplitSlices[i] *= ShadowDistance;

                CamFrustumPos[i, 0] = Camera.position + (Camera.FarT1 - Camera.position) * (SplitSlices[i] / Camera.farClip);
                CamFrustumPos[i, 1] = Camera.position + (Camera.FarT2 - Camera.position) * (SplitSlices[i] / Camera.farClip);
                CamFrustumPos[i, 2] = Camera.position + (Camera.FarT3 - Camera.position) * (SplitSlices[i] / Camera.farClip);
                CamFrustumPos[i, 3] = Camera.position + (Camera.FarT4 - Camera.position) * (SplitSlices[i] / Camera.farClip);
            }

            Matrix ProjShadowMatrix = Matrix.OrthoRH(100f, 100f, (float)ShadowDistance / 1000f, (float)ShadowDistance * 2f);
            Matrix ViewShadowMatrix = Matrix.LookAtRH(new Vector3(0, 0, 0), Conversion.ToVector3(ShadowVector), Vector3.Cross(Camera.direction, ShadowVector));
            LightViewProjMatrix = ViewShadowMatrix * ProjShadowMatrix;

            for (int i = 0; i < SplitsNumber; i++)
            {

                Vector3[] TransformSplit = new Vector3[8];
                for (int t = 0; t < 4; t++)
                {
                    TransformSplit[t] = Conversion.ToVector3(Vector3.Transform(Conversion.ToVector3(CamFrustumPos[i, t] - NewShadowPos), LightViewProjMatrix));
                    TransformSplit[t + 4] = Conversion.ToVector3(Vector3.Transform(Conversion.ToVector3(CamFrustumPos[i + 1, t] - NewShadowPos), LightViewProjMatrix));
                }

                Vector3 AABBMax = TransformSplit[0];
                Vector3 AABBMin = TransformSplit[0];

                for (int y = 0; y < 8; y++)
                {
                    if (AABBMax.X < TransformSplit[y].X) AABBMax.X = TransformSplit[y].X;
                    if (AABBMax.Y < TransformSplit[y].Y) AABBMax.Y = TransformSplit[y].Y;
                    if (AABBMax.Z < TransformSplit[y].Z) AABBMax.Z = TransformSplit[y].Z;

                    if (AABBMin.X > TransformSplit[y].X) AABBMin.X = TransformSplit[y].X;
                    if (AABBMin.Y > TransformSplit[y].Y) AABBMin.Y = TransformSplit[y].Y;
                    if (AABBMin.Z > TransformSplit[y].Z) AABBMin.Z = TransformSplit[y].Z;
                }
                /*
                AABBMax += new Vector3(0.05f);
                AABBMin -= new Vector3(0.05f);
                */

                // Create the crop matrix
                float scaleX, scaleY, scaleZ;
                float offsetX, offsetY, offsetZ;
                // Use default near-plane value
                AABBMin.Z = 0.0f;

                scaleX = 2.0f / (AABBMax.X - AABBMin.X);
                scaleY = 2.0f / (AABBMax.Y - AABBMin.Y);
                offsetX = -0.5f * (AABBMax.X + AABBMin.X) * scaleX;
                offsetY = -0.5f * (AABBMax.Y + AABBMin.Y) * scaleY;
                scaleZ = 1.0f / ((AABBMax.Z - AABBMin.Z));
                offsetZ = -AABBMin.Z * scaleZ;

                const int CoffShadowStep = 5;
                const float CoffMulti = 100f;
                const float CoffMultiScale = 1000f;

                offsetX = ((float)(((int)(offsetX * CoffMulti)) / CoffShadowStep * CoffShadowStep)) / CoffMulti;
                offsetY = ((float)(((int)(offsetY * CoffMulti)) / CoffShadowStep * CoffShadowStep)) / CoffMulti;
                offsetZ = ((float)(((int)(offsetZ * CoffMulti)) / CoffShadowStep * CoffShadowStep)) / CoffMulti;

                scaleX = ((float)(((int)(scaleX * CoffMultiScale)) / CoffShadowStep * CoffShadowStep)) / CoffMultiScale;
                scaleY = ((float)(((int)(scaleY * CoffMultiScale)) / CoffShadowStep * CoffShadowStep)) / CoffMultiScale;
                scaleZ = ((float)(((int)(scaleZ * CoffMultiScale)) / CoffShadowStep * CoffShadowStep)) / CoffMultiScale;

                CropMatrices[i] = new Matrix(scaleX, 0.0f, 0.0f, 0.0f, 0.0f, scaleY, 0.0f, 0.0f, 0.0f, 0.0f, scaleZ, 0.0f, offsetX, offsetY, offsetZ, 1.0f);

                DMatrix Inv = DMatrix.Invert(Conversion.ToDoubleMatrix(LightViewProjMatrix * CropMatrices[i]));

                DVector3 LocPos = DVector3.Transform(new DVector3(), Inv);
                NewCamPositions[i] = NewShadowPos + LocPos;
            }
        }
        public static void RenderObj(float TimeMili, Device device, EEDCamera Camera, Vector3 LightDirection, Vector3 LightColor, List<GameObject> GOs)
        {
            Matrix[] S_VP = new Matrix[SplitsNumber];
            float[] SplitDistances = new float[SplitsNumber];
            for (int i = 0; i < SplitsNumber; i++)
            {
                S_VP[i] = LightViewProjMatrix * CropMatrices[i];
                SplitDistances[i] = (float)SplitSlices[i + 1];///Camera.farClip;
            }
            DMatrix W_S_CAM = DMatrix.CreateTranslation(-NewShadowPos);

            Matrix[] S_WVP = new Matrix[SplitsNumber];
            for (int i = 0; i < GOs.Count; i++)
                if (GOs[i] != null)
                {
                    for (int y = 0; y < SplitsNumber; y++)
                    {
                        S_WVP[y] = Conversion.ToMatrix(GOs[i].Transformation * DMatrix.CreateTranslation(-NewShadowPos)) * S_VP[y];
                    }

                    if (GOs[i].StopSplit > -1)
                        GOs[i].DrawPSSM(device, TimeMili, Camera, LightDirection, LightColor, S_WVP, SplitDistances);
                    else
                        GOs[i].Draw(device, Camera, LightColor, LightDirection);
                }
        }
        public void DrawSplitShadows(float TimeMili, Matrix Transform, Matrix VP, Vector3 LightDirection, Vector3 LightColor,
            Matrix[] SMatrixs, float[] SplitDistances)
        {
            constants.WVP = Matrix.Transpose(Transform * VP);
            constants.World = Matrix.Transpose(Transform);
            constants.LightPosition = Conversion.ToVector4(LightDirection);//LShadow.Position - Camera.position);
            constants.H = new Vector4(PSSMsHelper.SplitShadowsSize, 0, 0, 0);

            unsafe
            {
                fixed (float* buffer = constants.cropMatrix)
                {
                    for (int x = 0; x < PSSMsHelper.SplitsNumber; x++)
                    {
                        buffer[x * 16 + 0] = SMatrixs[x].M11;
                        buffer[x * 16 + 1] = SMatrixs[x].M21;
                        buffer[x * 16 + 2] = SMatrixs[x].M31;
                        buffer[x * 16 + 3] = SMatrixs[x].M41;

                        buffer[x * 16 + 4] = SMatrixs[x].M12;
                        buffer[x * 16 + 5] = SMatrixs[x].M22;
                        buffer[x * 16 + 6] = SMatrixs[x].M32;
                        buffer[x * 16 + 7] = SMatrixs[x].M42;

                        buffer[x * 16 + 8] = SMatrixs[x].M13;
                        buffer[x * 16 + 9] = SMatrixs[x].M23;
                        buffer[x * 16 + 10] = SMatrixs[x].M33;
                        buffer[x * 16 + 11] = SMatrixs[x].M43;

                        buffer[x * 16 + 12] = SMatrixs[x].M14;
                        buffer[x * 16 + 13] = SMatrixs[x].M24;
                        buffer[x * 16 + 14] = SMatrixs[x].M34;
                        buffer[x * 16 + 15] = SMatrixs[x].M44;
                    }
                }

                fixed (float* buffer = constants.SplitPlane)
                {
                    for (int x = 0; x < PSSMsHelper.SplitsNumber; x++)
                        buffer[x*4] = SplitDistances[x];
                }
            }

            Program.context.InputAssembler.InputLayout = Materials[0].Effect.layout;
            Program.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            Program.context.InputAssembler.SetVertexBuffers(0, binding);
            Program.context.InputAssembler.SetIndexBuffer(Indices, Format.R32_UInt, 0);

            DifuseName = "";
            SpecularMapName = "";
            NormalMapName = "";
            SelfMapName = "";
            UV2DifuseName = "";
            ShaderName = "";

            //NoDoubleSide
            for (int i = 0; i < Materials.Length; i++)
            {
                if (!Materials[i].DoubleSide)
                {
                    if (ShaderName != Materials[i].Effect.Name)
                    {
                        Materials[i].Effect.renderTechniques[2].GetPassByIndex(0).Apply(Program.context);
                        ShaderName = Materials[i].Effect.Name;
                        DifuseName = ""; SpecularMapName = ""; NormalMapName = "";
                        SelfMapName = ""; UV2DifuseName = ""; ShaderName = "";
                        Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV);
                        Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip);
                        Program.context.PixelShader.SetShaderResource(6, PSSMsHelper.SMArraySRV);

                    }

                    CahseSetTexture(Materials[i]);

                    constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f);

                    SetConstants(false);

                    Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0);
                }
            }
            DifuseName = "";
            SpecularMapName = "";
            NormalMapName = "";
            SelfMapName = "";
            UV2DifuseName = "";
            ShaderName = "";
            //DoubleSide
            for (int i = 0; i < Materials.Length; i++)
            {
                if (Materials[i].DoubleSide)
                {
                    if (ShaderName != Materials[i].Effect.Name)
                    {
                        Materials[i].Effect.renderTechniques[2].GetPassByIndex(1).Apply(Program.context);
                        ShaderName = Materials[i].Effect.Name;
                        DifuseName = ""; SpecularMapName = ""; NormalMapName = "";
                        SelfMapName = ""; UV2DifuseName = ""; ShaderName = "";
                        Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV);
                        Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip);
                        Program.context.PixelShader.SetShaderResource(6, PSSMsHelper.SMArraySRV);
                    }

                    CahseSetTexture(Materials[i]);
                    constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f);

                    SetConstants(false);

                    Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0);
                }
            }
        }
        public void DrawNoShadows(float TimeMili, Matrix Transform, Matrix VP, Vector3 LightDirection, Vector3 LightColor)
        {
            constants.WVP = Matrix.Transpose(Transform * VP);
            constants.World = Matrix.Transpose(Transform);
            constants.LightPosition = Conversion.ToVector4(LightDirection);//LShadow.Position - Camera.position);

            Program.context.InputAssembler.InputLayout = Materials[0].Effect.layout;
            Program.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            Program.context.InputAssembler.SetVertexBuffers(0, binding);
            Program.context.InputAssembler.SetIndexBuffer(Indices, Format.R32_UInt, 0);

            DifuseName = "";
            SpecularMapName = "";
            NormalMapName = "";
            SelfMapName = "";
            UV2DifuseName = "";
            ShaderName = "";

            //NoDoubleSide
            for (int i = 0; i < Materials.Length; i++)
            {
                if(!Materials[i].DoubleSide)
                {
                    if (ShaderName != Materials[i].Effect.Name)
                    {
                        Materials[i].Effect.renderTechniques[0].GetPassByIndex(0).Apply(Program.context);
                        ShaderName = Materials[i].Effect.Name;
                        DifuseName = ""; SpecularMapName = ""; NormalMapName = "";
                        SelfMapName = ""; UV2DifuseName = ""; ShaderName = "";
                        Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV);
                        //Program.context.PixelShader.SetShaderResource(5, PSSMsHelper.SMArraySRV);

                        Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip);
                    }

                    CahseSetTexture(Materials[i]);
                    constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f);
                    SetConstants(false);
                    Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0);
                }
            }
            DifuseName = "";
            SpecularMapName = "";
            NormalMapName = "";
            SelfMapName = "";
            UV2DifuseName = "";
            ShaderName = "";
            //DoubleSide
            for (int i = 0; i < Materials.Length; i++)
            {
                if (Materials[i].DoubleSide)
                {
                    if (ShaderName != Materials[i].Effect.Name)
                    {
                        Materials[i].Effect.renderTechniques[0].GetPassByIndex(1).Apply(Program.context);
                        ShaderName = Materials[i].Effect.Name;
                        DifuseName = ""; SpecularMapName = ""; NormalMapName = "";
                        SelfMapName = ""; UV2DifuseName = ""; ShaderName = "";
                        Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV);
                        Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip);
                    }

                    CahseSetTexture(Materials[i]);
                    constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f);
                    SetConstants(false);
                    Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0);
                }
            }
        }
        public Vector3 GetNormalDispersion(System.Random Random_)
        {
            //Преобразование Бокса — Мюллера
            double x = Random_.NextDouble() * 2d - 1d;
            double y = Random_.NextDouble() * 2d - 1d;
            double z = Random_.NextDouble() * 2d - 1d;
            double s = x * x + y * y + z * z;
            while (s <= 0 || s > 1)
            {
                x = Random_.NextDouble() * 2d - 1d;
                y = Random_.NextDouble() * 2d - 1d;
                z = Random_.NextDouble() * 2d - 1d;

                s = x * x + y * y + z * z;
            }
            double t = System.Math.Sqrt((-3 * System.Math.Log(s)) / s);
            double z0 = x * t;
            double z1 = y * t;
            double z2 = z * t;
            Vector3 r = new Vector3((float)z0, (float)z1, (float)z2);
            r.Normalize();
            return r;
        }
        public static void ShadowsShapshot()
        {
            L = new List<DebugLine> { };
            for (int i = 0; i < PSSMsHelper.SplitsNumber; i++)
            {

                DVector3 Pos = PSSMsHelper.NewCamPositions[i];
                double Size = 10;
                Vector3 color = new Vector3(((float)i) / ((float)PSSMsHelper.SplitsNumber), 0.5f, 1 - ((float)i) / ((float)PSSMsHelper.SplitsNumber));
                L.Add(new DebugLine(new DVector3(Pos.X - Size, Pos.Y, Pos.Z), new DVector3(Pos.X + Size, Pos.Y, Pos.Z), color));
                L.Add(new DebugLine(new DVector3(Pos.X, Pos.Y - Size, Pos.Z), new DVector3(Pos.X, Pos.Y + Size, Pos.Z), color));
                L.Add(new DebugLine(new DVector3(Pos.X, Pos.Y, Pos.Z - Size), new DVector3(Pos.X, Pos.Y, Pos.Z + Size), color));

                DMatrix Inv = DMatrix.Invert(Conversion.ToDoubleMatrix(PSSMsHelper.LightViewProjMatrix * PSSMsHelper.CropMatrices[i]));

                DVector3 p0 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(-1, 1, 0), Inv);
                DVector3 p1 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(1, 1, 0), Inv);
                DVector3 p2 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(1, -1, 0), Inv);
                DVector3 p3 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(-1, -1, 0), Inv);

                DVector3 p4 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(-1, 1, 1), Inv);
                DVector3 p5 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(1, 1, 1), Inv);
                DVector3 p6 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(1, -1, 1), Inv);
                DVector3 p7 = PSSMsHelper.NewShadowPos + DVector3.Transform(new DVector3(-1, -1, 1), Inv);

                L.Add(new DebugLine(p0, p4, color));
                L.Add(new DebugLine(p1, p5, color));
                L.Add(new DebugLine(p2, p6, color));
                L.Add(new DebugLine(p3, p7, color));

                L.Add(new DebugLine(p0, p1, color));
                L.Add(new DebugLine(p1, p2, color));
                L.Add(new DebugLine(p2, p3, color));
                L.Add(new DebugLine(p3, p0, color));

                L.Add(new DebugLine(p4, p5, color));
                L.Add(new DebugLine(p5, p6, color));
                L.Add(new DebugLine(p6, p7, color));
                L.Add(new DebugLine(p7, p4, color));
            }

            L.Add(new DebugLine(Program.MyScene.Camera.position, Program.MyScene.Camera.FarT1, new Vector3(1, 1, 1)));
            L.Add(new DebugLine(Program.MyScene.Camera.position, Program.MyScene.Camera.FarT2, new Vector3(1, 1, 1)));
            L.Add(new DebugLine(Program.MyScene.Camera.position, Program.MyScene.Camera.FarT3, new Vector3(1, 1, 1)));
            L.Add(new DebugLine(Program.MyScene.Camera.position, Program.MyScene.Camera.FarT4, new Vector3(1, 1, 1)));

            L.Add(new DebugLine(Program.MyScene.Camera.FarT2, Program.MyScene.Camera.FarT1, new Vector3(1, 1, 1)));
            L.Add(new DebugLine(Program.MyScene.Camera.FarT3, Program.MyScene.Camera.FarT2, new Vector3(1, 1, 1)));
            L.Add(new DebugLine(Program.MyScene.Camera.FarT4, Program.MyScene.Camera.FarT3, new Vector3(1, 1, 1)));
            L.Add(new DebugLine(Program.MyScene.Camera.FarT1, Program.MyScene.Camera.FarT4, new Vector3(1, 1, 1)));
        }
        public float GetStarsSize(byte[] T_Dist, int s_x, int s_y, Vector3 Vec3)
        {
            double Teta = System.Math.Acos(Vec3.Y / System.Math.Sqrt(Vec3.X * Vec3.X + Vec3.Y * Vec3.Y + Vec3.Z * Vec3.Z)) / System.Math.PI;
            double Psi = System.Math.Atan(Vec3.Z / (Vec3.X)) / (2f * System.Math.PI);
            if (Vec3.X < 0) Psi += 0.5f;
            if (Vec3.X >= 0 && Vec3.Z < 0) Psi += 1f;

            Psi += 0.25f;
            if (Psi > 1) Psi -= 1f;

            int x = (int)(Psi * (double)s_x);
            int y = (int)(Teta * (double)s_y);
            return (float)T_Dist[1+4 * (x + y * s_x)] / 255f;
        }
 private static void RecursyKD(Node N, Vector3 Color)
 {
     if (N != null)
     {
         DebugDraw.DrawAABB(N.AA, N.BB, Color);
         if (N.Children != null && N.Children.Count > 0)
         {
             RecursyKD(N.Children[0], Color);
             if (N.Children.Count > 1)
             {
                 RecursyKD(N.Children[1], Color);
             }
         }
     }
 }
        private static int TestVector(Vector3 Vect)
        {
            if (Vect.Length() == 0) return -1;
            Vect.Normalize();
            Vect *= 5f;

            if (PerOtr(new Vector2(), new Vector2(Vect.X, Vect.Z), new Vector2(-1f, -1f), new Vector2(1f, -1f)) && PerOtr(new Vector2(), new Vector2(Vect.Y, Vect.Z), new Vector2(-1f, -1f), new Vector2(1f, -1f)))
                return 0;
            if (PerOtr(new Vector2(), new Vector2(Vect.X, Vect.Z), new Vector2(-1f, 1f), new Vector2(1f, 1f)) && PerOtr(new Vector2(), new Vector2(Vect.Y, Vect.Z), new Vector2(-1f, 1f), new Vector2(1f, 1f)))
                return 1;
            if (PerOtr(new Vector2(), new Vector2(Vect.X, Vect.Y), new Vector2(-1f, -1f), new Vector2(1f, -1f)) && PerOtr(new Vector2(), new Vector2(Vect.Z, Vect.Y), new Vector2(-1f, -1f), new Vector2(1f, -1f)))
                return 2;
            if (PerOtr(new Vector2(), new Vector2(Vect.X, Vect.Y), new Vector2(-1f, 1f), new Vector2(1f, 1f)) && PerOtr(new Vector2(), new Vector2(Vect.Z, Vect.Y), new Vector2(-1f, 1f), new Vector2(1f, 1f)))
                return 3;
            if (PerOtr(new Vector2(), new Vector2(Vect.Z, Vect.X), new Vector2(-1f, 1f), new Vector2(1f, 1f)) && PerOtr(new Vector2(), new Vector2(Vect.Y, Vect.X), new Vector2(-1f, 1f), new Vector2(1f, 1f)))
                return 4;
            if (PerOtr(new Vector2(), new Vector2(Vect.Z, Vect.X), new Vector2(-1f, -1f), new Vector2(1f, -1f)) && PerOtr(new Vector2(), new Vector2(Vect.Y, Vect.X), new Vector2(-1f, -1f), new Vector2(1f, -1f)))
                return 5;
            //0 зад
            //1 перед
            //2 низ
            //3 верх
            //4 лево
            //5 право
            return 0;
        }
        /// <summary>
        /// Обновление камеры
        /// </summary>
        public void Update(Vector3 CamPos, Vector3 Target)
        {
            Quaternion quaternion = Utils.QuaternionFromTwoDirs(new Vector3(0, 0, 1), Target - CamPos);
            position = CamPos;

            Vector3 tmp_vec = new Vector3(0, 1, 0);//Up Vector
            up_vector = Vector3.Transform(tmp_vec, quaternion);
            up_vector = tmp_vec;
            tmp_vec = new Vector3(0, 0, 1);//Front Vector
            direction = Vector3.Transform(tmp_vec, quaternion);

            viewMatrix = Matrix.LookAtLH(position, position + direction, up_vector);

            if (fov < 0.01f) fov = 0.01f;
            if (fov > 3f) fov = 3f;

            projectionMatrix = Matrix.PerspectiveFovLH(fov, aspectRatio, nearClip, farClip);

            viewProjectionMatrix = viewMatrix * projectionMatrix;

            cameraFrustum = new BoundingFrustum(viewProjectionMatrix);

            invertViewMatrix = Matrix.Invert(viewMatrix);

            yFac = (float)System.Math.Tan(fov / 2f);
            xFac = yFac * aspectRatio;
        }