/// <summary> /// Initialize predefined models<para/> /// Инициализация предзаданных моделей /// </summary> public static void Init() { // Load DAT-defined texture dictionaries // Загрузка предопределенных архивов текстур foreach (string DFF in FileManager.ModelFiles) { string name = Path.GetFileNameWithoutExtension(DFF).ToLower(); string path = PathManager.GetAbsolute(DFF); ModelFile f = new ModelFile(path, true); CachedFiles.TryAdd(name, f); Model m = new Model(f, true, true); Cached.TryAdd(name, m); } // Starting ModelFile thread // Запуск потока чтения ModelFile fileReaderThread = new Thread(FileLoaderProcess); fileReaderThread.IsBackground = true; fileReaderThread.Priority = ThreadPriority.BelowNormal; fileReaderThread.Start(); // Starting model builder thread // Запуск потока постройки Model modelBuilderThread = new Thread(ModelBuilderProcess); modelBuilderThread.IsBackground = true; modelBuilderThread.Priority = ThreadPriority.BelowNormal; modelBuilderThread.Start(); }
/// <summary> /// Create model from model file<para/> /// Создание модели из ModelFile /// </summary> /// <param name="f">Complete model file<para/>Прочитанный файл модели</param> /// <param name="sendNow">Send submeshes to GPU instantly<para/>Сразу же отправить данные меша на видеокарту</param> public Model(ModelFile f, bool important = false, bool sendNow = false) { // Checking completeness of model file // Проверка прочитанности модели if (sendNow && f.State != RenderWareFile.LoadState.Complete) { throw new Exception("[Model] Trying to create model from incomplete ModelFile"); } State = ReadyState.Empty; // Initializing fields // Инициализация полей File = f; Important = important; // Send submeshes // Отправка сабмешей if (sendNow) { BuildSubMeshes(); SendSubMeshes(); } }
/// <summary> /// Setup uniforms for specified surface<para/> /// Установка параметров шейдера для поверхности /// </summary> /// <param name="surf">Surface<para/>Поверхность</param> /// <param name="mat">Material<para/>Материал поверхности</param> public abstract void SetupSurface(Model.SubMesh.Surface surf, Model.Material mat, ModelFile.Geometry geom);
/// <summary> /// Process mesh internals<para/> /// Обработка данных меша /// </summary> public void Process(bool needed) { if (needed) { if (GroupModel != null) { if (GroupTextures != null) { if (GroupModel.State == Model.ReadyState.Complete && GroupTextures.State == TextureDictionary.ReadyState.Complete) { // Surface is ready to render // Поверхность готова к отрисовке Ready = true; Model.SubMesh[] subs = GroupModel.GetAllSubMeshes(); Renderers = new StaticRenderer[subs.Length]; Coords.Position = Coords.Position; for (int i = 0; i < Renderers.Length; i++) { Renderers[i] = new StaticRenderer() { BaseMatrix = Coords.Matrix, SubmeshMatrix = subs[i].Parent.Matrix, SubMesh = subs[i], Textures = GroupTextures, Fading = false, FadingDelta = 1 }; } } else { // Check for model state // Проверка состояния модели if (GroupModel.State != Model.ReadyState.Complete) { if (GroupModel.File.State == Files.RenderWareFile.LoadState.Complete) { if (!ModelManager.IsProcessing(GroupModel)) { ModelManager.ModelProcessQueue.Enqueue(GroupModel); } } } // Check for texture dictionary state // Проверка состояния архива текстур if (GroupTextures.State != TextureDictionary.ReadyState.Complete) { if (GroupTextures.File.State == Files.RenderWareFile.LoadState.Complete) { if (!TextureManager.IsProcessing(GroupTextures)) { TextureManager.TextureProcessQueue.Enqueue(GroupTextures); } } } } } else { // Texture not found - get it // Текстура не найдена - получаем её string tname = ObjectManager.Definitions[Definition.ID].TexDictionary; if (TextureManager.Cached.ContainsKey(tname)) { GroupTextures = TextureManager.Cached[tname]; } else { TextureFile tf = null; if (TextureManager.CachedFiles.ContainsKey(tname)) { tf = TextureManager.CachedFiles[tname]; } else { tf = new TextureFile(ArchiveManager.Get(tname + ".txd"), false); TextureManager.CachedFiles.TryAdd(tname, tf); TextureManager.TextureFileProcessQueue.Enqueue(tf); } GroupTextures = new TextureDictionary(tf); TextureManager.Cached.TryAdd(tname, GroupTextures); } GroupTextures.UseCount++; } } else { // Model not found - get it // Модель не найдена - получаем её string mname = ObjectManager.Definitions[Definition.ID].ModelName; if (ModelManager.Cached.ContainsKey(mname)) { GroupModel = ModelManager.Cached[mname]; } else { ModelFile mf = null; if (ModelManager.CachedFiles.ContainsKey(mname)) { mf = ModelManager.CachedFiles[mname]; } else { mf = new ModelFile(ArchiveManager.Get(mname + ".dff"), false); ModelManager.CachedFiles.TryAdd(mname, mf); ModelManager.ModelFileProcessQueue.Enqueue(mf); } GroupModel = new Model(mf); ModelManager.Cached.TryAdd(mname, GroupModel); } GroupModel.UseCount++; } } else { // Cleaning all the usings // Очистка использований if (GroupModel != null) { if (!GroupModel.Important) { GroupModel.UseCount--; } GroupModel = null; } if (GroupTextures != null) { if (!GroupTextures.Important) { GroupTextures.UseCount--; } GroupTextures = null; } if (Renderers!=null) { Renderers = null; } Ready = false; } }
/// <summary> /// Create copy of texture<para/> /// Создание копии текстуры /// </summary> /// <param name="tx">Existing texture<para/>Существующая текстура</param> public Texture(ModelFile.Texture tx) { AddressU = tx.AddressU; AddressV = tx.AddressV; Filter = tx.Filter; Name = tx.Name; MaskName = tx.MaskName; }
/// <summary> /// Copy existing material<para/> /// Копирование существующего материала /// </summary> /// <param name="mt">Existing material<para/>Существующий материал</param> public Material(ModelFile.Material mt) { Color = mt.Color; Flags = mt.Flags; HasAlpha = mt.HasAlpha; Props = mt.Props; if (mt.Textures!=null) { Textures = new Texture[mt.Textures.Length]; for (int i = 0; i < Textures.Length; i++) { Textures[i] = new Texture(mt.Textures[i]); } } }
/// <summary> /// Create submesh from ModelFile's Geometry entry<para/> /// Создание сабмеша из данных Geometry /// </summary> /// <param name="g">Loaded Geometry<para/>Загруженая Geometry</param> public SubMesh(Branch parent, Model model, ModelFile.Geometry g) { // Setting up the fields // Настройка полей State = ReadyState.Empty; Parent = parent; ParentModel = model; geometry = g; }
/// <summary> /// Setup uniforms for specified surface<para/> /// Установка параметров шейдера для поверхности /// </summary> /// <param name="surf">Surface<para/>Поверхность</param> /// <param name="mat">Material<para/>Материал поверхности</param> public override void SetupSurface(Model.SubMesh.Surface surf, Model.Material mat, ModelFile.Geometry geom) { GL.Uniform1(StaticShader.AppearValue, Fading ? FadingDelta : 1f); GL.Uniform3(StaticShader.AmbientColor, Renderer.SkyState.AmbientStatic); GL.Uniform3(StaticShader.DiffuseColor, Renderer.SkyState.DirectLight); GL.Uniform4(StaticShader.TintColor, new Color4(mat.Color[0], mat.Color[1], mat.Color[2], mat.Color[3])); }