Ejemplo n.º 1
0
        //--------------------//

        #region Apply
        /// <summary>
        /// Applies the shader to the content in the render delegate.
        /// </summary>
        /// <param name="render">The render delegate (is called once for every shader pass).</param>
        /// <param name="material">The material to be used by this shader; <c>null</c> for device texture.</param>
        /// <param name="camera">The camera for transformation information.</param>
        /// <param name="lights">An array of all lights this shader should consider; should be <c>null</c>.</param>
        public override void Apply(Action render, XMaterial material, Camera camera, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (camera == null)
            {
                throw new ArgumentNullException(nameof(camera));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            // Always reset the textures since they might change their memory address at a device reset
            Effect.SetTexture(_normalTextureHandle, _normalTexture);
            if (_refractionView != null)
            {
                Effect.SetTexture(_refractionMapHandle, _refractionView.GetRenderTarget());
            }
            if (_waterTexture == null)
            {
                Effect.SetTexture(_reflectionMapHandle, _reflectionView.GetRenderTarget());
            }
            else
            {
                Effect.SetTexture(_reflectionMapHandle, _waterTexture);
            }

            base.Apply(render, material, camera, lights);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Runs the actual shader passes
        /// </summary>
        /// <param name="render">The render delegate (is called once for every shader pass)</param>
        /// <param name="material">The material to be used by this shader; <c>null</c> for device texture</param>
        /// <param name="lights">An array of all lights this shader should consider; <c>null</c> for no lighting</param>
        protected virtual void RunPasses(Action render, XMaterial material, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            int passCount = Effect.Begin(FX.None);
            IList <SasScriptCommand> techniqueScript;
            if (Techniques.TryGetValue(Effect.Technique, out techniqueScript))
            {
                ExecuteScript(techniqueScript, render);
            }
            else
            {
                for (int i = 0; i < passCount; i++)
                {
                    Effect.BeginPass(i);
                    render();
                    Effect.EndPass();
                }
            }

            Effect.End();
        }
Ejemplo n.º 3
0
        protected void RenderSubset(int i, Camera camera, LightSource[] lights)
        {
            using (new ProfilerEvent(() => "Subset " + i))
            {
                // Load the subset-material (default to first one, if the subset has no own)
                XMaterial currentMaterial = i < Materials.Length ? Materials[i] : Materials[0];

                RenderHelper(() => Mesh.DrawSubset(i), currentMaterial, camera, lights);
            }
        }
        private void RenderFixedFunction(Action render, XMaterial material)
        {
            using (new ProfilerEvent("Surface effect: Fixed-function"))
            {
                Engine.Device.Material   = material.D3DMaterial;
                Engine.State.FfpLighting = true;

                render();
            }
        }
Ejemplo n.º 5
0
        //--------------------//

        #region Apply
        /// <summary>
        /// Applies the shader to the content in the render delegate.
        /// </summary>
        /// <param name="render">The render delegate (is called once for every shader pass).</param>
        /// <param name="material">The material to be used by this shader; <c>null</c> for device texture.</param>
        /// <param name="camera">The camera for transformation information.</param>
        /// <param name="lights">An array of all lights this shader should consider. Mustn't be <c>null</c>!</param>
        public override void Apply(Action render, XMaterial material, Camera camera, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (camera == null)
            {
                throw new ArgumentNullException(nameof(camera));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            #region Auto-select technique
            if (lights.Length == 0 && _lighting)
            {
                Effect.Technique = _lighting ? _lightBlack : _simpleBlack;
            }
            else
            {
                if (Engine.Effects.DoubleSampling && _lighting)
                {
                    if (Engine.Capabilities.MaxShaderModel >= new Version(2, 0, 2))
                    {
                        Effect.Technique = _light2B;
                    }
                    else if (Engine.Capabilities.MaxShaderModel == new Version(2, 0, 1))
                    {
                        Effect.Technique = _light2A;
                    }
                }
                else if (Engine.Capabilities.MaxShaderModel >= new Version(2, 0))
                {
                    Effect.Technique = _lighting ? _light20 : _simple20;
                }
                else
                {
                    Effect.Technique = _lighting ? _light14 : _simple14;
                }
            }
            #endregion

            if (_lighting)
            {
                base.Apply(render, material, camera, lights);
            }
            else
            {
                base.Apply(render, material, camera);
            }
        }
        private void SetEngineState(XMaterial material)
        {
            // Set texture
            Engine.State.SetTexture(material.DiffuseMaps[0]);

            // Fall back to fixed-function pipeline if no shader was set for this body
            if (SurfaceEffect == SurfaceEffect.Shader && SurfaceShader == null)
            {
                SurfaceEffect = SurfaceEffect.FixedFunction;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Transfer lighting data from a <see cref="DirectionalLight"/> to the shader
        /// </summary>
        /// <param name="light">The <see cref="DirectionalLight"/> to get the information from</param>
        /// <param name="index">The light index in the shader to set</param>
        /// <param name="material">The currently active material</param>
        protected void SetupLight(DirectionalLight light, int index, XMaterial material)
        {
            #region Sanity checks
            if (light == null)
            {
                throw new ArgumentNullException(nameof(light));
            }
            #endregion

            SetupLightHelper(light, index, material);
            Effect.SetValue(_lightDirectionHandles[index], new Vector4(light.Direction, 0));
        }
        private void RenderShader(Action render, XMaterial material, Camera camera, LightSource[] lights)
        {
            using (new ProfilerEvent("Surface effect: Shader"))
            {
                Engine.State.FfpLighting = false;

                if (SurfaceShader != null)
                {
                    using (new ProfilerEvent(() => "Apply " + SurfaceShader))
                        SurfaceShader.Apply(render, material, camera, lights);
                }
            }
        }
        private void RenderGlow(Action render, XMaterial material)
        {
            using (new ProfilerEvent("Surface effect: Glow"))
            {
                Engine.State.SetTexture(material.EmissiveMap);
                var emissiveMaterial = new Material {
                    Emissive = material.Emissive
                };

                // Use simple DirectX lighting
                Engine.Device.Material   = emissiveMaterial;
                Engine.State.FfpLighting = true;

                render();
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Creates a new colored vertex group
        /// </summary>
        /// <param name="primitiveType">The type of primitives to generate from the vertexes</param>
        /// <param name="vertexes">An array for vertexes with position and color information</param>
        /// <param name="indexes">An array of indexes for the index buffer; <c>null</c> for no indexes</param>
        public VertexGroup(PrimitiveType primitiveType, PositionColored[] vertexes, short[] indexes = null)
        {
            #region Sanity checks
            if (vertexes == null)
            {
                throw new ArgumentNullException(nameof(vertexes));
            }
            #endregion

            _primitiveType = primitiveType;
            _vertexCount   = vertexes.Length;

            _material = XMaterial.DefaultMaterial;

            _buildVertexBuffer = () => BufferHelper.CreateVertexBuffer(Engine.Device, vertexes, PositionColored.Format);
            Initialize(indexes);
        }
Ejemplo n.º 11
0
        private static XData _Export(string n, params GameObject[] go)
        {
            XData            d    = new XData(n, FileType.Unity);
            List <Material>  mats = new List <Material>();
            List <Texture2D> texs = new List <Texture2D>();

            for (int i = 0; i < go.Length; i++)
            {
                d.Objects.Add(CreateElement(go[i], mats));
            }
            for (int i = 0; i < mats.Count; i++)
            {
                Material  m  = mats[i];
                XMaterial xm = new XMaterial();
                xm.Color = m.GetColor(_ColorId).ToXColor();
                Texture2D t = m.GetTexture(_MainTexId) as Texture2D;
                if (t != null)
                {
                    XMapping xp = new XMapping();
                    xp.ID = texs.IndexOf(t);
                    if (xp.ID < 0)
                    {
                        xp.ID = texs.Count;
                        texs.Add(t);
                    }
                    xp.Type   = TextureType.Diffuse;
                    xp.Offset = m.GetTextureOffset(_MainTexId).ToXVec2();
                    xp.Scale  = m.GetTextureScale(_MainTexId).ToXVec2();
                    xm.Maps.Add(xp);
                }
                d.Materials.Add(xm);
            }
            for (int i = 0; i < texs.Count; i++)
            {
                Texture2D t  = texs[i];
                Texture2D _t = new Texture2D(t.width, t.height);
                _t.SetPixels(t.GetPixels());
                XTexture xt = new XTexture();
                xt.Data = _t.EncodeToPNG();
                d.Textures.Add(xt);
            }
            return(d);
        }
Ejemplo n.º 12
0
        private void RenderSubset(int i, Camera camera, GetLights lights)
        {
            // Frustum culling with the bouding box
            if (_subsetWorldBoundingBoxes != null && !camera.InFrustum(_subsetWorldBoundingBoxes[i]))
            {
                return;
            }

            using (new ProfilerEvent(() => "Subset " + i))
            {
                Action renderSubset = () => Mesh.DrawSubset(i);

                if (SurfaceEffect >= SurfaceEffect.Glow)
                {
                    // The terrain will always appear completely black on the glow/shadow map
                    using (new ProfilerEvent(() => "Apply black " + _subsetShaders[i]))
                        _subsetShaders[i].Apply(renderSubset, XMaterial.DefaultMaterial, camera);
                }
                else
                {
                    // Apply the normal terrain shader
                    if (_subsetShaders[i] != null)
                    {
                        SurfaceShader = _subsetShaders[i];
                    }
                    XMaterial currentMaterial = i < Materials.Length ? Materials[i] : Materials[0];

                    // Handle lights for fixed-function or shader rendering
                    Vector3 boxCenter = (_subsetBoundingBoxes == null ? new Vector3() : _subsetBoundingBoxes[i].Minimum + (_subsetBoundingBoxes[i].Maximum - _subsetBoundingBoxes[i].Minimum) * 0.5f);

                    var effectiveLights = (SurfaceEffect == SurfaceEffect.Plain)
                        ? new LightSource[0]
                        : lights(Position + boxCenter, _blockSize * StretchH * (float)(Math.Sqrt(2) / 2));
                    RenderHelper(renderSubset, currentMaterial, camera, effectiveLights);
                }
            }

            // Only allow the visualization of bounding bodies in normal view
            if (DrawBoundingBox && _subsetWorldBoundingBoxes != null && SurfaceEffect < SurfaceEffect.Glow)
            {
                Engine.DrawBoundingBox(_subsetWorldBoundingBoxes[i]);
            }
        }
Ejemplo n.º 13
0
        //--------------------//

        #region Light helper
        /// <summary>
        /// Transfer lighting data from a <see cref="LightSource"/> to the shader
        /// </summary>
        /// <param name="light">The <see cref="LightSource"/> to get the information from</param>
        /// <param name="index">The light index in the shader to set</param>
        /// <param name="material">The currently active material</param>
        private void SetupLightHelper(LightSource light, int index, XMaterial material)
        {
            if (index < _lightDiffuseHandles.Count)
            {
                Effect.SetValue(_lightDiffuseHandles[index], Color4.Modulate(light.Diffuse, material.Diffuse));
            }
            if (index < _lightAmbientHandles.Count)
            {
                Effect.SetValue(_lightAmbientHandles[index], Color4.Modulate(light.Ambient, material.Ambient));
            }
            if (index < _lightSpecularHandles.Count)
            {
                Effect.SetValue(_lightSpecularHandles[index], Color4.Modulate(light.Specular, material.Specular));
            }
            if (index < _lightSpecularPowerHandles.Count)
            {
                Effect.SetValue(_lightSpecularPowerHandles[index], material.SpecularPower);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Creates a new textured vertex group
        /// </summary>
        /// <param name="primitiveType">The type of primitives to generate from the vertexes</param>
        /// <param name="vertexes">An array for vertexes with position and texture information</param>
        /// <param name="indexes">An array of indexes for the index buffer; <c>null</c> for no indexes</param>
        /// <param name="material">The material to use for rendering</param>
        public VertexGroup(PrimitiveType primitiveType, PositionTextured[] vertexes,
                           short[] indexes, XMaterial material)
        {
            #region Sanity checks
            if (vertexes == null)
            {
                throw new ArgumentNullException(nameof(vertexes));
            }
            #endregion

            _primitiveType = primitiveType;
            _vertexCount   = vertexes.Length;

            _material = material;
            // ReSharper disable once ImpureMethodCallOnReadonlyValueField
            _material.HoldReference();

            _buildVertexBuffer = () => BufferHelper.CreateVertexBuffer(Engine.Device, vertexes, PositionTextured.Format);
            Initialize(indexes);
        }
        private void RenderPlain(Action render, XMaterial material)
        {
            using (new ProfilerEvent("Surface effect: None"))
            {
                if (material.Diffuse == Color.White)
                { // A plain white surface needs no lighting at all
                    Engine.State.FfpLighting = false;
                }
                else
                { // Simulate a plain colored surface by using emissive lighting
                    Engine.State.FfpLighting = true;
                    var emissiveMaterial = new Material {
                        Emissive = material.Diffuse
                    };
                    Engine.Device.Material = emissiveMaterial;
                }

                render();
            }
        }
        /// <summary>
        /// Provides an automatic rendering framework that handles things like setting textures, materials, lighting and shaders.
        /// </summary>
        /// <param name="render">A delegate that will be called once per rendering pass to display the actual content.</param>
        /// <param name="material">The material to apply to everything rendered.</param>
        /// <param name="camera">The currently effective <see cref="Camera"/>.</param>
        /// <param name="lights">The currently effective <see cref="LightSource"/>s.</param>
        protected void RenderHelper(Action render, XMaterial material, Camera camera, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (camera == null)
            {
                throw new ArgumentNullException(nameof(camera));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            SetEngineState(material);
            SetEngineState(camera);

            switch (SurfaceEffect)
            {
            case SurfaceEffect.Plain:
                RenderPlain(render, material);
                break;

            case SurfaceEffect.Glow:
                RenderGlow(render, material);
                break;

            case SurfaceEffect.FixedFunction:
                RenderFixedFunction(render, material);
                break;

            case SurfaceEffect.Shader:
                RenderShader(render, material, camera, lights);
                break;
            }

            Engine.State.UserClipPlane = default(Plane);
        }
Ejemplo n.º 17
0
        //--------------------//

        #region Texture helper
        /// <summary>
        /// Loads the textures for the <see cref="CpuParticle"/> sprites
        /// </summary>
        private void UpdateSpriteTextures()
        {
            // Release previous textures
            _material1.ReleaseReference();
            _material2.ReleaseReference();

            #region First-life material
            // Start with empty material
            _material1 = XMaterial.DefaultMaterial;
            if (!string.IsNullOrEmpty(Preset.Particle1Texture))
            {
                // Get texture path
                string texture = Path.Combine("Particles", Preset.Particle1Texture);

                // Check if texture path is valid
                if (ContentManager.FileExists("Textures", texture))
                {
                    _material1 = new XMaterial(XTexture.Get(Engine, texture));
                    _material1.HoldReference();
                }
            }
            #endregion

            #region Second-life material
            _material2 = XMaterial.DefaultMaterial;
            if (!string.IsNullOrEmpty(Preset.Particle2Texture))
            {
                // Get texture path
                string texture = Path.Combine("Particles", Preset.Particle2Texture);

                // Check if texture path is valid
                if (ContentManager.FileExists("Textures", texture))
                {
                    _material2 = new XMaterial(XTexture.Get(Engine, texture));
                    _material2.HoldReference();
                }
            }
            #endregion

            Preset.TexturesDirty = false;
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Internal helper constructor
        /// </summary>
        /// <param name="mesh">The mesh use for rendering</param>
        /// <param name="material">The material to use for rendering the terrain</param>
        /// <param name="lighting">Use/support lighting when rendering this terrain?</param>
        protected Terrain(Mesh mesh, XMaterial material, bool lighting) : base(mesh, material)
        {
            #region Sanity checks
            if (mesh == null)
            {
                throw new ArgumentNullException(nameof(mesh));
            }
            #endregion

            SurfaceEffect = SurfaceEffect.Shader;

            Lighting = lighting;

            #region Copy index and vertex buffer content
            // Copy buffers to RAM for fast position lookups
            using (new TimedLogEvent("Copy index and vertex buffer content"))
            {
                _indexBuffer = BufferHelper.ReadIndexBuffer(mesh);

                // Get the vertex positions from the VertexBuffer
                if (lighting) // Different vertex formats
                {
                    var verts = BufferHelper.ReadVertexBuffer <PositionNormalMultiTextured>(mesh);
                    _vertexBuffer = new Vector3[verts.Length];
                    for (int i = 0; i < verts.Length; i++)
                    {
                        _vertexBuffer[i] = verts[i].Position;
                    }
                }
                else
                {
                    var verts = BufferHelper.ReadVertexBuffer <PositionMultiTextured>(mesh);
                    _vertexBuffer = new Vector3[verts.Length];
                    for (int i = 0; i < verts.Length; i++)
                    {
                        _vertexBuffer[i] = verts[i].Position;
                    }
                }
            }
            #endregion
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Transfer lighting data from a <see cref="PointLight"/> to the shader
        /// </summary>
        /// <param name="light">The <see cref="PointLight"/> to get the information from</param>
        /// <param name="index">The light index in the shader to set</param>
        /// <param name="material">The currently active material</param>
        protected void SetupLight(PointLight light, int index, XMaterial material)
        {
            #region Sanity checks
            if (light == null)
            {
                throw new ArgumentNullException(nameof(light));
            }
            #endregion

            SetupLightHelper(light, index, material);

            if (index < _lightPositionHandles.Count)
            {
                Effect.SetValue(_lightPositionHandles[index],
                                new Vector4(((IPositionableOffset)light).EffectivePosition, 1));
            }
            if (index < _lightAttenuationHandles.Count)
            {
                Effect.SetValue(_lightAttenuationHandles[index], (Vector4)light.Attenuation);
            }
        }
Ejemplo n.º 20
0
        //--------------------//

        #region Apply
        /// <summary>
        /// Applies the shader to the content in the render delegate.
        /// </summary>
        /// <param name="render">The render delegate (is called once for every shader pass).</param>
        /// <param name="material">The material to be used by this shader; <c>null</c> for device texture.</param>
        /// <param name="camera">The camera for transformation information.</param>
        /// <param name="lights">An array of all lights this shader should consider; should be <c>null</c>.</param>
        public override void Apply(Action render, XMaterial material, Camera camera, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (camera == null)
            {
                throw new ArgumentNullException(nameof(camera));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            // Always reset the texture since it might change its memory address at a device reset
            Effect.SetTexture(_particleTextureHandle, ParticleTexture?.Texture);

            base.Apply(render, material, camera, lights);
        }
Ejemplo n.º 21
0
        //--------------------//

        #region Passes
        /// <inheritdoc/>
        protected override void RunPasses(Action render, XMaterial material, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            // Note: Manual control of shader logic (no SAS scripting)

            Effect.Begin(FX.None);

            // If this shader supports light-less shading, it will have to do that with its first pass
            if (lights.Length == 0)
            {
                #region Render pass
                using (new ProfilerEvent("Pass 0"))
                {
                    Effect.BeginPass(0);
                    render();
                    Effect.EndPass();
                }
                #endregion
            }
            else
            {
                for (int i = 0; i < lights.Length; i++)
                {
                    var pass = ShaderPasses.None;

                    // ReSharper disable AccessToModifiedClosure
                    var dirLight = lights[i] as DirectionalLight;
                    if (dirLight != null)
                    {
                        if (i == 0 && dirLight.Diffuse == Color.Black && dirLight.Specular == Color.Black)
                        {
                            #region Ambient light
                            using (new ProfilerEvent(() => "Setup light " + i + " as ambient"))
                                SetupLight(dirLight, 0, material);
                            pass = ShaderPasses.AmbientLight;
                            #endregion
                        }
                        else
                        {
                            #region Directional lights
                            using (new ProfilerEvent(() => "Setup light " + i + " as directional"))
                                SetupLight(dirLight, 0, material);
                            pass = (i == 0) ? ShaderPasses.OneDirLight : ShaderPasses.OneDirLightAdd;

                            // Try to handle the next light at the same time
                            if (i + 1 < lights.Length)
                            {
                                var nextDirLight = lights[i + 1] as DirectionalLight;
                                if (nextDirLight != null)
                                {
                                    using (new ProfilerEvent(() => "Setup light " + i + 1 + " as directional")) SetupLight(nextDirLight, 1, material);
                                    pass = (i == 0) ? ShaderPasses.TwoDirLights : ShaderPasses.TwoDirLightsAdd;

                                    // Handled two lights at once, so bump up counter
                                    i++;
                                }
                            }
                            #endregion
                        }
                    }
                    else
                    {
                        var pointLight = lights[i] as PointLight;
                        if (pointLight != null)
                        {
                            #region Point lights
                            using (new ProfilerEvent(() => "Setup light " + i + " as point"))
                                SetupLight(pointLight, 0, material);
                            pass = (i == 0) ? ShaderPasses.OnePointLight : ShaderPasses.OnePointLightAdd;
                            #endregion
                        }
                    }
                    // ReSharper restore AccessToModifiedClosure

                    if (pass == ShaderPasses.None)
                    {
                        continue;
                    }

                    #region Render pass
                    using (new ProfilerEvent(() => "Pass " + pass))
                    {
                        Effect.BeginPass((int)pass);
                        render();
                        Effect.EndPass();
                    }
                    #endregion

                    // Only apply one pass if fog is turned on, since it would mess up additive blending
                    if (Engine.State.Fog)
                    {
                        break;
                    }
                }
            }

            Effect.End();
        }
Ejemplo n.º 22
0
        private static GameObject _Import(XData d)
        {
            GameObject g = new GameObject(d.Name);

            List <Texture2D> t = new List <Texture2D>();

            for (int i = 0; i < d.Textures.Count; i++)
            {
                XTexture  t0 = d.Textures[i];
                Texture2D t1 = new Texture2D(0, 0);
                t1.name = t0.Name;
                if (t1.LoadImage(t0.Data))
                {
                    t.Add(t1);
                }
                else
                {
                    Debug.LogError("XRobject Texture Load Error!");
                }
            }
            List <Material> m = new List <Material>();

            for (int i = 0; i < d.Materials.Count; i++)
            {
                XMaterial xm = d.Materials[i];
                Material  _m;
                if (xm.Color.a > 0.0 && xm.Color.a < 1.0)
                {
                    _m = new Material(mat_transparent);
                }
                else
                {
                    _m = new Material(mat_diffuse);
                }
                _m.name  = xm.Name;
                _m.color = new Color(xm.Color.r, xm.Color.g, xm.Color.b, xm.Color.a);
                //mat.SetColor("_SpecColor", m.Specular.ToColor());
                //mat.SetFloat("_Shininess", m.Shininess);
                foreach (XMapping xp in xm.Maps)
                {
                    string ts = null;
                    switch (xp.Type)
                    {
                    case TextureType.Diffuse:
                        ts = "_MainTex";
                        break;

                    case TextureType.Normal:
                        ts = "_BumpMap";
                        break;

                    case TextureType.Reflection:
                        break;
                    }
                    _m.SetTexture(ts, t[xp.ID]);
                    _m.SetTextureScale(ts, xp.Scale.ToVector2());
                    _m.SetTextureOffset(ts, xp.Offset.ToVector2());
                }
                m.Add(_m);
            }
            Vector3 min = Vector3.one * float.MaxValue;
            Vector3 max = Vector3.one * float.MinValue;

            CreateGameObject(d.Type, d.Objects, g.transform, m.ToArray(), ref min, ref max);

            switch (d.Type)
            {
            case FileType.Maya:
            case FileType.Unity:
                break;

            case FileType.D3Max:
            case FileType.Revit:
                g.transform.localScale  = new Vector3(-1f, 1f, 1f);
                g.transform.eulerAngles = new Vector3(-90f, 0.0f, 0.0f);
                break;
            }
            BoxCollider b = g.AddComponent <BoxCollider>();

            b.size   = max - min;
            b.center = (max + min) * 0.5f;
            return(g);
        }
Ejemplo n.º 23
0
        //--------------------//

        #region Apply
        /// <inheritdoc/>
        public override void Apply(Action render, XMaterial material, Camera camera, params LightSource[] lights)
        {
            #region Sanity checks
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (camera == null)
            {
                throw new ArgumentNullException(nameof(camera));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            #region Auto-select technique
            if (lights.Length == 0)
            { // Only emissive lighting
                if (Engine.Effects.PerPixelLighting && material.EmissiveMap != null)
                {
                    Effect.Technique = _texturedEmissiveMapOnly;
                }
                else
                {
                    Effect.Technique = (material.DiffuseMaps[0] == null) ? _coloredEmissiveOnly : _texturedEmissiveOnly;
                }
            }
            else
            {
                if (Engine.Effects.PerPixelLighting)
                { // Normal per-pixel lighting
                    if (material.DiffuseMaps[0] == null)
                    {
                        Effect.Technique = _coloredPerPixel;
                    }
                    else
                    {
                        #region Flags
                        bool normal   = material.NormalMap != null && Engine.Effects.NormalMapping;
                        bool specular = material.SpecularMap != null;
                        bool emissive = material.EmissiveMap != null;
                        #endregion

                        if (normal && specular && emissive)
                        {
                            Effect.Technique = _texturedPerPixelNormalSpecularEmissiveMap;
                        }
                        else if (normal && emissive)
                        {
                            Effect.Technique = _texturedPerPixelNormalEmissiveMap;
                        }
                        else if (emissive)
                        {
                            Effect.Technique = _texturedPerPixelEmissiveMap;
                        }
                        else if (normal && specular)
                        {
                            Effect.Technique = _texturedPerPixelNormalSpecularMap;
                        }
                        else if (specular)
                        {
                            Effect.Technique = _texturedPerPixelSpecularMap;
                        }
                        else if (normal)
                        {
                            Effect.Technique = _texturedPerPixelNormalMap;
                        }
                        else
                        {
                            Effect.Technique = _texturedPerPixel;
                        }
                    }
                }
                else
                { // Normal per-vertex lighting
                    Effect.Technique = (material.DiffuseMaps[0] == null) ? _coloredPerVertex : _texturedPerVertex;
                }
            }
            #endregion

            base.Apply(render, material, camera, lights);
        }
Ejemplo n.º 24
0
        public virtual void Apply(Action render, XMaterial material, Camera camera, params LightSource[] lights)
        {
            #region Sanity checks
            if (IsDisposed)
            {
                throw new ObjectDisposedException(ToString());
            }
            if (render == null)
            {
                throw new ArgumentNullException(nameof(render));
            }
            if (camera == null)
            {
                throw new ArgumentNullException(nameof(camera));
            }
            if (lights == null)
            {
                throw new ArgumentNullException(nameof(lights));
            }
            #endregion

            #region Values
            using (new ProfilerEvent("Set shader parameters"))
            {
                byte diffuseMapCount = 0;
                foreach (ParameterInfo info in ParameterInfos)
                {
                    switch (info.Type)
                    {
                    case ParameterType.Int:
                        switch (info.SemanticID)
                        {
                            #region Texture filtering
                        case SemanticID.FilterMode:
                            const int linearFiltering = 2, anisotropicFiltering = 3;
                            Effect.SetValue(info.Handle, Engine.Anisotropic ? anisotropicFiltering : linearFiltering);
                            break;
                            #endregion
                        }
                        break;

                    case ParameterType.Float:
                        switch (info.SemanticID)
                        {
                            #region Camera
                        case SemanticID.CameraPosition:
                            Effect.SetValue(info.Handle, camera.Position.ApplyOffset(camera.PositionBase));
                            break;
                            #endregion

                            #region Normal transformations
                        case SemanticID.World:
                            Effect.SetValue(info.Handle, Engine.State.WorldTransform);
                            break;

                        case SemanticID.WorldInverse:
                            Effect.SetValue(info.Handle, Matrix.Invert(Engine.State.WorldTransform));
                            break;

                        case SemanticID.WorldTranspose:
                            Effect.SetValue(info.Handle, Matrix.Transpose(Engine.State.WorldTransform));
                            break;

                        case SemanticID.WorldInverseTranspose:
                            Effect.SetValue(info.Handle, Matrix.Transpose(Matrix.Invert(Engine.State.WorldTransform)));
                            break;

                        case SemanticID.View:
                            Effect.SetValue(info.Handle, camera.View);
                            break;

                        case SemanticID.ViewInverse:
                            Effect.SetValue(info.Handle, camera.ViewInverse);
                            break;

                        case SemanticID.ViewTranspose:
                            Effect.SetValue(info.Handle, camera.ViewTranspose);
                            break;

                        case SemanticID.ViewInverseTranspose:
                            Effect.SetValue(info.Handle, camera.ViewInverseTranspose);
                            break;

                        case SemanticID.Projection:
                            Effect.SetValue(info.Handle, camera.Projection);
                            break;

                        case SemanticID.ProjectionInverse:
                            Effect.SetValue(info.Handle, camera.ProjectionInverse);
                            break;

                        case SemanticID.ProjectionTranspose:
                            Effect.SetValue(info.Handle, camera.ProjectionTranspose);
                            break;

                        case SemanticID.ProjectionInverseTranspose:
                            Effect.SetValue(info.Handle, camera.ProjectionInverseTranspose);
                            break;
                            #endregion

                            #region Composite transformations
                        case SemanticID.WorldView:
                            Effect.SetValue(info.Handle, Engine.State.WorldTransform * camera.View);
                            break;

                        case SemanticID.WorldViewInverse:
                            Effect.SetValue(info.Handle, Matrix.Invert(Engine.State.WorldTransform * camera.View));
                            break;

                        case SemanticID.WorldViewTranspose:
                            Effect.SetValue(info.Handle, Matrix.Transpose(Engine.State.WorldTransform * camera.View));
                            break;

                        case SemanticID.WorldViewInverseTranspose:
                            Effect.SetValue(info.Handle, Matrix.Transpose(Matrix.Invert(Engine.State.WorldTransform * camera.View)));
                            break;

                        case SemanticID.ViewProjection:
                            Effect.SetValue(info.Handle, camera.ViewProjection);
                            break;

                        case SemanticID.ViewProjectionInverse:
                            Effect.SetValue(info.Handle, camera.ViewProjectionInverse);
                            break;

                        case SemanticID.ViewProjectionTranspose:
                            Effect.SetValue(info.Handle, camera.ViewProjectionTranspose);
                            break;

                        case SemanticID.ViewProjectionInverseTranspose:
                            Effect.SetValue(info.Handle, camera.ViewProjectionInverseTranspose);
                            break;

                        case SemanticID.WorldViewProjection:
                            Effect.SetValue(info.Handle, Engine.State.WorldTransform * camera.ViewProjection);
                            break;

                        case SemanticID.WorldViewProjectionInverse:
                            Effect.SetValue(info.Handle, Matrix.Invert(Engine.State.WorldTransform * camera.ViewProjection));
                            break;

                        case SemanticID.WorldViewProjectionTranspose:
                            Effect.SetValue(info.Handle, Matrix.Transpose(Engine.State.WorldTransform * camera.ViewProjection));
                            break;

                        case SemanticID.WorldViewProjectionInverseTranspose:
                            Effect.SetValue(info.Handle, Matrix.Transpose(Matrix.Invert(Engine.State.WorldTransform * camera.ViewProjection)));
                            break;
                            #endregion

                            #region Lighting
                        case SemanticID.Emissive:
                            Effect.SetValue(info.Handle, new Color4(material.Emissive));
                            break;

                        case SemanticID.Position:
                            if (!_lightParametersHandled)
                            {
                                _lightPositionHandles.Add(info.Handle);
                            }
                            break;

                        case SemanticID.Direction:
                            if (!_lightParametersHandled)
                            {
                                _lightDirectionHandles.Add(info.Handle);
                            }
                            break;

                        case SemanticID.Attenuation:
                            if (!_lightParametersHandled)
                            {
                                _lightAttenuationHandles.Add(info.Handle);
                            }
                            break;

                        case SemanticID.Color:
                        case SemanticID.Diffuse:
                            if (!_lightParametersHandled)
                            {
                                _lightDiffuseHandles.Add(info.Handle);
                            }
                            break;

                        case SemanticID.Ambient:
                            if (!_lightParametersHandled)
                            {
                                _lightAmbientHandles.Add(info.Handle);
                            }
                            break;

                        case SemanticID.Specular:
                            if (!_lightParametersHandled)
                            {
                                _lightSpecularHandles.Add(info.Handle);
                            }
                            break;

                        case SemanticID.SpecularPower:
                            if (!_lightParametersHandled)
                            {
                                _lightSpecularPowerHandles.Add(info.Handle);
                            }
                            break;
                            #endregion

                            #region Timer
                        case SemanticID.Time:
                            Effect.SetValue(info.Handle, (float)Engine.TotalGameTime);
                            break;

                        case SemanticID.ElapsedTime:
                            Effect.SetValue(info.Handle, (float)Engine.LastFrameGameTime);
                            break;
                            #endregion
                        }
                        break;

                    case ParameterType.Texture:
                        switch (info.SemanticID)
                        {
                            #region Texture maps
                        case SemanticID.Diffuse:
                        case SemanticID.DiffuseMap:
                            if (diffuseMapCount < material.DiffuseMaps.Length && material.DiffuseMaps[diffuseMapCount] != null)
                            {
                                Effect.SetTexture(info.Handle, material.DiffuseMaps[diffuseMapCount].Texture);
                            }
                            else
                            {
                                Effect.SetTexture(info.Handle, null);
                            }

                            // Increment counter for possible next reference in this shader to a (different) diffuse map
                            diffuseMapCount++;
                            break;

                        case SemanticID.Normal:
                        case SemanticID.NormalMap:
                            Effect.SetTexture(info.Handle, material.NormalMap?.Texture);
                            break;

                        case SemanticID.Height:
                        case SemanticID.HeightMap:
                            Effect.SetTexture(info.Handle, material.HeightMap?.Texture);
                            break;

                        case SemanticID.Specular:
                        case SemanticID.SpecularMap:
                            Effect.SetTexture(info.Handle, material.SpecularMap?.Texture);
                            break;

                        case SemanticID.Emissive:
                            Effect.SetTexture(info.Handle, material.EmissiveMap?.Texture);
                            break;
                            #endregion
                        }
                        break;
                    }
                }
            }
            #endregion

            _lightParametersHandled = true;

            RunPasses(render, material, lights);
        }
Ejemplo n.º 25
0
 public void OnMaterial(MaterialNode node)
 {
     matid = node.MaterialId.IntegerValue;
     if (!matLink.ContainsKey(matid))
     {
         StringBuilder log = new StringBuilder();
         XMaterial     mat = new XMaterial();
         Element       e   = Documents.Peek().GetElement(node.MaterialId);
         if (e is Material)
         {
             Material m = e as Material;
             mat.Name = m.Name;
             if (m.UseRenderAppearanceForShading)
             {
                 mat.Color = new XColor(1.0f, 1.0f, 1.0f, 1 - (float)node.Transparency);
             }
             else
             {
                 mat.Color = new XColor(m.Color.Red / 255f, m.Color.Green / 255f, m.Color.Blue / 255f, 1 - (float)node.Transparency);
             }
             mat.Specular  = XColor.white * (m.Smoothness / 100f);
             mat.Shininess = m.Shininess / 100f;
             Element _e = Documents.Peek().GetElement(m.AppearanceAssetId);
             if (EnableLog)
             {
                 log.Append("Material:" + m.Name + "\n");
                 log.Append("AppearanceAssetElement:" + (_e is AppearanceAssetElement).ToString() + "\n");
             }
             if (_e is AppearanceAssetElement)
             {
                 AppearanceAssetElement aae = _e as AppearanceAssetElement;
                 Asset a = aae.GetRenderingAsset();
                 if (EnableLog)
                 {
                     log.Append("Asset.Size:" + a.Size.ToString() + "\n");
                 }
                 if (a.Size > 0)
                 {
                     for (int i = 0; i < a.Size; i++)
                     {
                         if (EnableLog)
                         {
                             LogMaterial(a[i], log);
                         }
                         XMapping t = ReadTexture(a[i]);
                         if (t != null)
                         {
                             mat.Maps.Add(t);
                         }
                     }
                 }
             }
         }
         else
         {
             mat.Name      = node.NodeName;
             mat.Color     = new XColor(node.Color.Red / 255f, node.Color.Green / 255f, node.Color.Blue / 255f, 1 - (float)node.Transparency);
             mat.Specular  = new XColor(0, 0, 0, 1);
             mat.Shininess = 0f;
         }
         matLog.Add(log.ToString());
         matLink.Add(matid, XData.Materials.Count);
         XData.Materials.Add(mat);
     }
 }
Ejemplo n.º 26
0
    static int i = 0; // общий "указатель" строк

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

    public static void Main()
    {
        SearchOption SOAD = SearchOption.AllDirectories;

        string[] filesName = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.XAF", SOAD);
        System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

        foreach (var file in filesName)
        {
            List <XMaterial> Materials = new List <XMaterial>();
            List <Frame>     Frames    = new List <Frame>();
            List <Mesh>      Meshes    = new List <Mesh>();

            readText = File.ReadAllLines(file); // для прохода по строкам и поиска "шаблонов"

            //  создаём список в котором будет искать фреймы и удалять лишние строки
            //  создаём именно здесь, потому что далее содержимое readText будет изменяться

            foreach (var o in readText)
            {
                if (o.Contains("animation_set {"))
                {
                    break;                                // отбрасываем лишние строки с Анимацией
                }
                newlist.Add(o);
            }

            XAnimationSet animset = new XAnimationSet(); //  этот блок вроде он всегда один

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

            for (i = 0; i < readText.Length; i++)   // Ищем материалы
            {
                // Материалы // лучше искать отдельно для каждого файла

                if (readText[i].Contains("material \"") && readText[i].EndsWith("\" {"))
                {
                    XMaterial xmat = new XMaterial();              // СОЗДАЁМ НОВЫЙ ОБЪЕКТ
                    xmat.Name = Regex.Split(readText[i], "\"")[1]; // первая строка - это всегда имя материала

                    for (int iii = 1; iii < 4; iii++)              // цикл по 3 следущим строкам
                    {
                        if (readText[i + iii].Contains("texture"))
                        {
                            xmat.Filename = Regex.Split(readText[i + iii], "\"")[1]; // имя текстуры
                        }
                        if (readText[i + iii].Contains("colour"))                    // colour { float, float, float, float }
                        {
                            MatchCollection floats = Regex.Matches(readText[i + iii], @"(-?\d+(?:\.\d+)?)");
                            xmat.FaceColor.R = float.Parse(floats[0].Value);
                            xmat.FaceColor.G = float.Parse(floats[1].Value);
                            xmat.FaceColor.B = float.Parse(floats[2].Value);
                            xmat.FaceColor.A = float.Parse(floats[3].Value);
                        }

                        if (readText[i + iii].Contains("specular")) // specular { float, float }
                        {
                            MatchCollection floats = Regex.Matches(readText[i + iii], @"(-?\d+(?:\.\d+)?)");
                            xmat.Intensity = float.Parse(floats[0].Value);
                            xmat.Power     = float.Parse(floats[1].Value);
                        }
                    }
                    Materials.Add(xmat);   // ДОБАВЛЯЕМ МАТЕРИАЛ В СПИСОК
                }
            }

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

            for (i = 0; i < readText.Length; i++)
            {
                // Фреймы //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

                if ((readText[i].Contains("object")) && (readText[i].Contains("{")))
                {
                    Frame frame = new Frame();
                    frame.FrameName            = "Frame " + Regex.Split(readText[i], "\"")[1] + " { //начало фрейма";
                    frame.FrameTransformMatrix = ReadMatrix(i + 1);
                    frame.FrameMeshName        = "{ " + frame.FrameName + " }";
                    Frames.Add(frame);
                }
            }

            // Меши //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

            for (i = 0; i < readText.Length; i++)
            {
                if (readText[i].Contains("mesh {")) //
                {
                    Mesh mesh = new Mesh();
                    mesh.MeshName = Regex.Split(readText[i - 7], "\"")[1];

                    for (;;)
                    {
                        i++; // в цикле опускаемся каждый раз на строку ниже от "mesh {"
                        // пока не достигнем двух идущих подряд строк содержащих "}" означающую конец МЕШа

                        if (readText[i].Contains("}") && readText[i + 1].Contains("}"))
                        {
                            break;
                        }
                        if (readText[i].Contains("}") && readText[i + 1].Contains("object \""))
                        {
                            break;                                                                   // -_- долго искал этот косяк -_-
                        }
                        if (readText[i].Contains("vertices {"))
                        {
                            mesh.MeshVertices = ReadVector2or3(i);
                        }
                        if (readText[i].Contains("normals {"))
                        {
                            mesh.MeshNormals = ReadVector2or3(i);
                        }
                        if (readText[i].Contains("texture_coordinates {"))
                        {
                            mesh.MeshTextureCoords = ReadVector2or3(i);
                        }

                        if (readText[i].Contains("faces {"))
                        {
                            List <string> findex, nordex;
                            ReadFaces(i, out findex, out nordex);
                            mesh.FacesIndices   = findex;
                            mesh.NormalsIndices = nordex;
                        }

                        if (readText[i].Contains("face_materials {"))
                        {
                            int offset = i;
                            for (;;)
                            {
                                offset++; // шагаем по строкам
                                if (readText[offset].Contains("}"))
                                {
                                    break;
                                }
                                mesh.face_materials.Add(Regex.Split(readText[offset], "\"")[1]);
                            }
                        }

                        if (readText[i].Contains("material \"") && readText[i].EndsWith("\""))
                        {
                            mesh.MeshMaterial = "{ " + Regex.Split(readText[i], "\"")[1] + " }"; // имя материала
                        }
                    }
                    Meshes.Add(mesh);
                } // if
            }

            // анимация //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

            for (i = 0; i < readText.Length; i++)
            {
                if (readText[i].Contains("animation_set {")) // найден набор анимаций
                {
                    int ii = 0;                              // счётчик

                    for (;;)                                 // цикл по всем следующим строкам
                    {
                        if (readText[i + ii].Contains("animation ") && readText[i + ii].EndsWith(" {"))
                        {
                            XAnimation anima = new XAnimation();
                            anima.Name = " Animation " + Regex.Split(readText[i + ii], "\"")[1] + " {"; // имя анимации
                            anima.Keys = new List <XAnimationKey>();

                            for (;;)
                            {
                                if (readText[i + ii].Contains("object_name "))                                     // object_name "dummy"
                                {
                                    anima.FrameReference = "  { " + Regex.Split(readText[i + ii], "\"")[1] + " }"; // имя ссылки на фрейм
                                }

                                if (readText[i + ii].Contains("rotate_keys {"))
                                {
                                    int           iii         = 1;
                                    XAnimationKey rotate_keys = new XAnimationKey();
                                    rotate_keys.Name = "rotate_keys";

                                    for (;;)
                                    {
                                        string[] numbers = readText[i + ii + iii].Split(new char[] { ',' },
                                                                                        StringSplitOptions.RemoveEmptyEntries);

                                        foreach (var f in numbers)
                                        {
                                            rotate_keys.KeysF.Add(float.Parse(f));
                                        }

                                        rotate_keys.KeysS.Add(numbers[0] + ";4;" + numbers[1] + "," + numbers[2] + "," + numbers[3] + "," + numbers[4] + ";;,");

                                        iii++;
                                        if (readText[i + ii + iii].Contains("}"))
                                        {
                                            break;
                                        }
                                    }
                                    rotate_keys.KeysS.Insert(0, "  AnimationKey rot {");
                                    rotate_keys.KeysS.Insert(1, "  0;");
                                    rotate_keys.KeysS.Insert(2, "  " + (rotate_keys.KeysS.Count - 2) + ";");
                                    rotate_keys.KeysS[rotate_keys.KeysS.Count - 1] = rotate_keys.KeysS[rotate_keys.KeysS.Count - 1].Replace(";;,", ";;;");
                                    rotate_keys.KeysS.Add("  }");

                                    anima.Keys.Add(rotate_keys);
                                }

                                if (readText[i + ii].Contains("scale_keys {"))
                                {
                                    int           iii        = 1;
                                    XAnimationKey scale_keys = new XAnimationKey();
                                    scale_keys.Name = "scale_keys";

                                    for (;;)
                                    {
                                        string[] numbers = readText[i + ii + iii].Split(new char[] { ',' },
                                                                                        StringSplitOptions.RemoveEmptyEntries);

                                        foreach (var f in numbers)
                                        {
                                            scale_keys.KeysF.Add(float.Parse(f));
                                        }

                                        scale_keys.KeysS.Add(numbers[0] + ";3;" + numbers[1] + "," + numbers[2] + "," + numbers[3] + ";;,");

                                        iii++;
                                        if (readText[i + ii + iii].Contains("}"))
                                        {
                                            break;
                                        }
                                    }
                                    scale_keys.KeysS.Insert(0, "  AnimationKey scale {");
                                    scale_keys.KeysS.Insert(1, "  1;");
                                    scale_keys.KeysS.Insert(2, "  " + (scale_keys.KeysS.Count - 2) + ";");
                                    scale_keys.KeysS[scale_keys.KeysS.Count - 1] = scale_keys.KeysS[scale_keys.KeysS.Count - 1].Replace(";;,", ";;;");
                                    scale_keys.KeysS.Add("  }");

                                    anima.Keys.Add(scale_keys);
                                }

                                if (readText[i + ii].Contains("position_keys {"))
                                {
                                    int           iii           = 1;
                                    XAnimationKey position_keys = new XAnimationKey();
                                    position_keys.Name = "position_keys";

                                    for (;;)
                                    {
                                        string[] numbers = readText[i + ii + iii].Split(new char[] { ',' },
                                                                                        StringSplitOptions.RemoveEmptyEntries);

                                        foreach (var f in numbers)
                                        {
                                            position_keys.KeysF.Add(float.Parse(f));
                                        }

                                        position_keys.KeysS.Add(numbers[0] + ";3;" + numbers[1] + "," + numbers[2] + "," + numbers[3] + ";;,");

                                        iii++;
                                        if (readText[i + ii + iii].Contains("}"))
                                        {
                                            break;
                                        }
                                    }
                                    position_keys.KeysS.Insert(0, "  AnimationKey pos {");
                                    position_keys.KeysS.Insert(1, "  2;");
                                    position_keys.KeysS.Insert(2, "  " + (position_keys.KeysS.Count - 2) + ";");
                                    position_keys.KeysS[position_keys.KeysS.Count - 1] = position_keys.KeysS[position_keys.KeysS.Count - 1].Replace(";;,", ";;;");
                                    position_keys.KeysS.Add("  }");

                                    anima.Keys.Add(position_keys);
                                }

                                if (readText[i + ii].Contains("}") && readText[i + ii + 1].Contains("}"))
                                {
                                    break;
                                }

                                ii++;
                            }
                            ii++;
                            animset.Animations.Add(anima);  //  добавляем анимации с ключами в набор
                        }

                        i++;

                        if ((i + ii) - readText.Length == 0) // конец файла
                        {
                            break;                           //  это выход для [animation_set]
                        }
                    } //for
                } //if анимация
            }     // for // чтение всех строк

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

// СУПЕР КОСТЫЛЬ ОСТАВЛЯЮЩИЙ ФРЕЙМЫ И УБИРАЮЩИЙ ВСЁ ЛИШНЕЕ
// иначе нужно юзать реккурсию и список дочерних фреймов для "Объектов"

            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains(","))
                {
                    newlist[i] = "";
                }
            }                                                         // удаляем все строки содержащие запятые
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str)); // каждый раз удаляем образовавшиеся пустые строки
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("faces {"))
                {
                    newlist[i + 0] = ""; newlist[i + 1] = ""; newlist[i + 2] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("matrix {"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("texture \""))
                {
                    newlist[i] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("normals {"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("texture_coordinates {"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("vertices {"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("material \"") && newlist[i].EndsWith("\""))
                {
                    newlist[i] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("mesh {"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("material") && newlist[i].Contains("{"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));
            for (i = 0; i < newlist.Count; i++)
            {
                if (newlist[i].Contains("face_materials"))
                {
                    newlist[i] = ""; newlist[i + 1] = "";
                }
            }
            newlist.RemoveAll(str => String.IsNullOrWhiteSpace(str));

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

            using (StreamWriter new_xaf = new StreamWriter(file + ".x")) new_xaf.Write("xof 0303txt 0032\n\n"); //   HEADER

//  можно записывать всё в одном блоке using

            using (StreamWriter new_xaf = File.AppendText(file + ".x"))
            {
//  ЗАПИСЫВАЕМ  МАТЕРИАЛЫ  В  ФАЙЛ

                if (Materials.Count > 0)
                {
                    for (int mati = 0; mati < Materials.Count; mati++)
                    {
                        new_xaf.WriteLine("Material " + Materials[mati].Name + " {");
                        new_xaf.WriteLine(Materials[mati].FaceColor);
                        new_xaf.WriteLine(Materials[mati].Power + ";");
                        new_xaf.WriteLine("0.000000;0.000000;0.000000;;");
                        new_xaf.WriteLine("0.000000;0.000000;0.000000;;");

                        if (Materials[mati].Filename == "" || Materials[mati].Filename == " " ||
                            Materials[mati].Filename == String.Empty || Materials[mati].Filename == null)
                        {
                            new_xaf.WriteLine("}");
                        }
                        else
                        {
                            new_xaf.WriteLine("TextureFilename { \"" + Materials[mati].Filename + "\"; } }\n");
                        }
                    }
                    Materials.Clear();
                }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ЗАПИСЫВАЕМ  Фреймы  И  МЕШИ  В  ФАЙЛ

// теперь надо пробежаться по newlist списку
// чтобы запихнуть после его матрицы - тело соответствующего меша
// таким образом нужные скобки сдвинуться

// лучше заюзаю новый список // или юзай метод отсюда https://stackoverflow.com/questions/9462518/short-way-to-add-item-after-item-in-list

                int co = 0;

                List <string> NewNewList = new List <string>();

                foreach (var o in newlist) // идём по строкам в новом списке
                {
                    //if (newlist.Contains("Frame ")) // если встретился объект

                    if (o.Contains("object") /*&& o.Contains("{")*/)
                    {
                        NewNewList.Add(Frames[co].FrameName);
                        NewNewList.Add(Frames[co].FrameTransformMatrix);
                        NewNewList.Add(Meshes[co].ToString());
                        co++; // переходим к следущему фрейму и его мешу
                    }
                    if (o.Contains("}"))
                    {
                        NewNewList.Add(o + " // конец фрейма"); // ставим закрывающую скобку
                    }

                    // if ( co > ( Frames.Count - 1 ) ) break;
                    // и если нет больше фреймов с мешами - выходим
                    // эта строчка тоже вызывала ошибку
                    // не добавляла последнюю скобку закрывающую фрейм
                }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ЗАПИСЫВАЕМ  Фреймы  И  МЕШИ  В  ФАЙЛ

                foreach (var str in NewNewList)
                {
                    new_xaf.WriteLine(str);
                }

                Frames.Clear();
                Meshes.Clear();

                NewNewList.Clear();
                newlist.Clear();

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

//  ЗАПИСЫВАЕМ  АНИМАЦИИ  В  ФАЙЛ

                if (animset.Animations.Count > 0)
                {
                    new_xaf.WriteLine("\nAnimationSet {\n");

                    foreach (var o in animset.Animations)
                    {
                        new_xaf.WriteLine(o.Name + "\n" + o.FrameReference);
                        new_xaf.WriteLine("  AnimationOptions { 1; 0; } \n");

                        foreach (var oo in o.Keys)
                        {
                            foreach (var ooo in oo.KeysS)
                            {
                                new_xaf.WriteLine(ooo);
                            }
                        }

                        new_xaf.WriteLine(" }"); //  для каждого блока Animation
                    }
                    new_xaf.WriteLine("}");      //  для блока AnimationSet

                    animset.Animations.Clear();
                }
            } // запись в файл

            animset.Animations.Clear();
            animset = null;

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
        } // foreach (var file in filesName)

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
    } // public static void Main()