//--------------------// #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); }
/// <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(); }
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(); } }
//--------------------// #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; } }
/// <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(); } }
/// <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); }
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); }
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]); } }
//--------------------// #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); } }
/// <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); }
//--------------------// #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; }
/// <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 }
/// <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); } }
//--------------------// #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); }
//--------------------// #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(); }
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); }
//--------------------// #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); }
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); }
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); } }
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()