Beispiel #1
0
 public static CarDescription FromKn5(IKn5 kn5)
 {
     return(new CarDescription(kn5.OriginalFilename)
     {
         Kn5Loaded = kn5
     });
 }
Beispiel #2
0
        public static void RemoveUnusedMaterials(this IKn5 kn5)
        {
            var materialsToKeep = new List <uint>();

            foreach (var node in kn5.Nodes.Where(x => x.NodeClass != Kn5NodeClass.Base))
            {
                if (!materialsToKeep.Contains(node.MaterialId))
                {
                    materialsToKeep.Add(node.MaterialId);
                }
            }

            var newMaterials = kn5.Materials.Values
                               .Where((x, i) => materialsToKeep.Contains((uint)i))
                               .ToDictionary(x => x.Name, x => x);

            foreach (var node in kn5.Nodes.Where(x => x.NodeClass != Kn5NodeClass.Base))
            {
                var id = newMaterials.Values.IndexOf(kn5.Materials.Values.ElementAt((int)node.MaterialId));
                if (id == -1)
                {
                    throw new Exception("Unexpected conflict");
                }
                node.MaterialId = (uint)id;
            }
            kn5.Materials = newMaterials;
        }
Beispiel #3
0
 private static void FixFrensel(IKn5 kn5)
 {
     foreach (var property in GetFresnelProperties(kn5).Where(x => x.ValueA <= 0.4))
     {
         property.ValueA *= 2f;
     }
 }
Beispiel #4
0
 public static CarDescription FromKn5(IKn5 kn5, string carDirectory, DataWrapper data = null)
 {
     return(new CarDescription(kn5.OriginalFilename, carDirectory, data)
     {
         Kn5Loaded = kn5
     });
 }
Beispiel #5
0
 public Kn5RenderableDriver(IKn5 kn5, Matrix matrix, string overridesDirectory, bool asyncTexturesLoading = true,
                            bool asyncOverrideTexturesLoading = false, IKn5ToRenderableConverter converter = null)
     : base(kn5, matrix, overridesDirectory, asyncTexturesLoading, asyncOverrideTexturesLoading, converter)
 {
     /*foreach (var dummy in this.GetAllChildren().OfType<RenderableList>()) {
      *  dummy.HighlightBoundingBoxes = true;
      * }*/
 }
Beispiel #6
0
        private static PaintableItem FindQuery([NotNull] IKn5 kn5, Func <string, PaintableItem> prepare, params string[] query)
        {
            var texture = query.Select(x => RegexFromQuery.IsQuery(x)
                    ? kn5.Textures.Keys.FirstOrDefault(RegexFromQuery.Create(x, StringMatchMode.CompleteMatch, false).IsMatch)
                    : kn5.Textures.Keys.Contains(x) ? x : null).FirstOrDefault(x => x != null);

            return(texture != null?prepare(texture) : null);
        }
Beispiel #7
0
 private static IEnumerable <PaintableItem> GuessPaintableItems([CanBeNull] IKn5 kn5)
 {
     foreach (var item in GuessPaintableItemsInner(kn5).NonNull())
     {
         item.Guessed = true;
         yield return(item);
     }
 }
Beispiel #8
0
 private static IEnumerable <Kn5Material.ShaderProperty> GetFresnelProperties(IKn5 kn5)
 {
     return(kn5.Materials.Values
            .Where(value => value.ShaderName.Contains(@"MultiMap") &&
                   value.GetPropertyByName("sunSpecular")?.ValueA > 0.5f &&
                   value.GetPropertyByName("useDetail")?.ValueA >= 1f)
            .Select(x => x.GetPropertyByName("fresnelMaxLevel"))
            .Where(x => x != null && x.ValueA >= 0.2));
 }
Beispiel #9
0
        private ContentRepairSuggestion TestSuspensionNodes(CarObject car, IKn5 kn5)
        {
            if (SuspensionNodes.All(name => kn5.FirstByName(name) != null))
            {
                return(null);
            }

            return(new ContentObsoleteSuggestion("Suspension nodes missing",
                                                 "Might cause crashes, especially in showroom.",
                                                 (p, c) => FixAsync(car, FixSuspensionNodes, p, c)));
        }
Beispiel #10
0
 public static byte[] ToArray(this IKn5 kn5, bool includeTextures = true)
 {
     using (var memory = new MemoryStream()) {
         if (!includeTextures)
         {
             kn5.Textures.Clear();
             kn5.TexturesData.Clear();
         }
         kn5.Save(memory);
         return(memory.ToArray());
     }
 }
Beispiel #11
0
        private async Task <IKn5> GenerateLodAsync(string preparedFbx, IKn5 originalKn5, CarLodGeneratorStageParams stage, string modelChecksum,
                                                   IProgress <double?> progress, CancellationToken cancellationToken)
        {
            var temporaryOutputFilename = await _service.GenerateLodAsync(stage.Id, preparedFbx, modelChecksum,
                                                                          progress.SubrangeDouble(0d, 0.98), cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();
            var result = await Task.Run(() => LodFbxToKn5(originalKn5, temporaryOutputFilename, stage)).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();
            progress.Report(0.99);
            return(result);
        }
Beispiel #12
0
        public Kn5RenderableCollider(IKn5 kn5, Matrix matrix, bool asyncTexturesLoading = true, IKn5ToRenderableConverter converter = null)
            : base(kn5, matrix, asyncTexturesLoading, converter)
        {
            foreach (var mesh in Dummies)
            {
                mesh.LocalMatrix = Matrix.Identity;
            }

            foreach (var mesh in Meshes)
            {
                mesh.SetTransparent(true);
            }
        }
Beispiel #13
0
        private static void FixSuspensionNodes(IKn5 kn5)
        {
            foreach (var name in SuspensionNodes.Where(name => kn5.FirstByName(name) == null))
            {
                var node  = Kn5Node.CreateBaseNode(name);
                var wheel = kn5.FirstByName(name.Replace("SUSP", "WHEEL"))?.Transform;
                if (wheel.HasValue)
                {
                    node.Transform = wheel.Value;
                }

                kn5.RootNode.Children.Add(node);
            }
        }
Beispiel #14
0
        public int GroupOrder(IKn5 kn5, IEnumerable <Tuple <Kn5Node, double, Mat4x4> > node, Dictionary <Kn5Node, int> nodeIndices)
        {
            var isTransparent = false;
            var isBlending    = false;
            var maxIndex      = 0;

            foreach (var n in node)
            {
                isTransparent |= n.Item1.IsTransparent;
                isBlending     = kn5.GetMaterial(n.Item1.MaterialId)?.BlendMode == Kn5MaterialBlendMode.AlphaBlend;
                maxIndex       = Math.Max(maxIndex, nodeIndices[n.Item1]);
            }
            return((isTransparent ? 1 << 31 : 0) | (isBlending ? 1 << 30 : 0) | maxIndex);
        }
Beispiel #15
0
        private static IEnumerable <Kn5Node> FilterNodes(IKn5 kn5, IFilter <string> filter, Kn5Node node)
        {
            if (node.NodeClass == Kn5NodeClass.Base)
            {
                return(node.Children.SelectMany(x => FilterNodes(kn5, filter, x)));
            }

            if (!filter.Test(node.Name) ||
                kn5.GetMaterial(node.MaterialId)?.TextureMappings.Any(x => x.Name == "txNormal" || x.Name == "txNormalDetail") != false)
            {
                return(new Kn5Node[0]);
            }

            return(new[] { node });
        }
Beispiel #16
0
        public Kn5NodeFilterContext([NotNull] JObject definitions, [NotNull] Dictionary <string, string> userDefined,
                                    [NotNull] string carDirectory, [NotNull] DataWrapper carData, [NotNull] IKn5 kn5)
        {
            _definitions  = definitions;
            _userDefined  = userDefined;
            _carDirectory = carDirectory;
            _carData      = carData;
            _kn5          = kn5;

            _filterParams = new FilterParams {
                CustomTestEntryFactory = str => {
                    if (str.StartsWith("$"))
                    {
                        var definition = GetDefinition(str);
                        if (definition != null)
                        {
                            return(new DefinitionTestEntry(Filter.Create(this, definition, _filterParams)));
                        }
                    }
                    if (str.StartsWith("@:"))
                    {
                        return(ResolveQuery(str));
                    }
                    return(null);
                },
                CustomValueParser = (string str, ref int pos) => {
                    if (pos < str.Length - 1 && str[pos] == '@' && str[pos + 1] == ':')
                    {
                        var start = pos;
                        for (var bracket = 0; pos < str.Length && (bracket > 0 || !IsValueTerminatingCharacter(str[pos])); pos++)
                        {
                            bracket += str[pos] == '[' ? 1 : str[pos] == ']' ? -1 : 0;
                        }
                        return(str.Substring(start, pos - start));
                    }
                    return(null);
                },
                ValueSplitter = new ValueSplitter(s => {
                    var m = Regex.Match(s, @"^([a-zA-Z]+)([:<>≤≥])");
                    return(!m.Success ? null : new FilterPropertyValue(m.Groups[1].Value,
                                                                       FilterComparingOperations.Parse(m.Groups[2].Value), s.Substring(m.Length).TrimStart()));
                }, ':', '<', '>', '≤', '≥'),
                CaseInvariant            = false,
                TreatSpacesAsAndOperands = false,
                StringMatchMode          = StringMatchMode.CompleteMatch
            };
        }
Beispiel #17
0
        public void FinalizeKn5(IKn5 kn5)
        {
            var materialAdded = false;

            foreach (var node in kn5.Nodes)
            {
                if (node.NodeClass != Kn5NodeClass.Base && node.MaterialId == uint.MaxValue)
                {
                    if (!materialAdded)
                    {
                        materialAdded = true;
                        if (!kn5.Materials.ContainsKey("__LodGenBlack"))
                        {
                            kn5.Materials["__LodGenBlack"] = Kn5MaterialUtils.Create("__LodGenBlack");
                        }
                    }
                    node.MaterialId = (uint)kn5.Materials.FindIndex(m => m.Key == "__LodGenBlack");
                }
            }
        }
Beispiel #18
0
        private ContentRepairSuggestion TestFrensel(CarObject car, IKn5 kn5)
        {
            var any = false;

            foreach (var property in GetFresnelProperties(kn5))
            {
                any = true;
                if (property.ValueA > 0.4)
                {
                    return(null);
                }
            }

            if (!any)
            {
                return(null);
            }
            return(new ContentObsoleteSuggestion("Car paint might be not reflective enough",
                                                 "In one of updates, Kunos changed behavior of some shaders, and so now you need to set fresnelMaxLevel to be about two times bigger.",
                                                 (p, c) => FixAsync(car, FixFrensel, p, c)));
        }
Beispiel #19
0
        public static async Task UpdateKn5(this IKn5 kn5, BaseRenderer renderer = null, CarSkinObject skin = null)
        {
            if (!kn5.IsEditable)
            {
                throw new Exception("Can’t save KN5 loaded unusually");
            }

            var backup = kn5.OriginalFilename + ".backup";

            try {
                if (!File.Exists(backup))
                {
                    FileUtils.HardLinkOrCopy(kn5.OriginalFilename, backup);
                }
            } catch (Exception e) {
                Logging.Warning(e);
            }

            await Task.Run(() => {
                using (var f = FileUtils.RecycleOriginal(kn5.OriginalFilename)) {
                    try {
                        kn5.Save(f.Filename);
                    } catch {
                        FileUtils.TryToDelete(f.Filename);
                        throw;
                    }
                }
            });

            if (renderer != null)
            {
                var car  = skin == null ? null : CarsManager.Instance.GetById(skin.CarId);
                var slot = (renderer as ToolsKn5ObjectRenderer)?.MainSlot;
                if (car != null && slot != null)
                {
                    slot.SetCar(CarDescription.FromKn5(kn5, car.Location, car.AcdData));
                    slot.SelectSkin(skin.Id);
                }
            }
        }
Beispiel #20
0
        protected static IEnumerable <IKn5RenderableObject> Flatten(IKn5 kn5, IEnumerable <IRenderableObject> root, [CanBeNull] string textureName,
                                                                    [CanBeNull] string objectPath)
        {
            var split = Lazier.Create(() => objectPath?.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries));

            bool TestObjectPath(IKn5RenderableObject obj)
            {
                var s = split.Value;

                if (s == null || s.Length < 1)
                {
                    return(true);
                }
                if (s[s.Length - 1] != obj.OriginalNode.Name)
                {
                    return(false);
                }
                return(kn5.GetObjectPath(obj.OriginalNode) == objectPath);
            }

            return(Flatten(root, x => {
                if (!(x is IKn5RenderableObject k))
                {
                    return true;
                }
                if (!TestObjectPath(k))
                {
                    return false;
                }
                if (textureName == null)
                {
                    return true;
                }
                var material = kn5.GetMaterial(k.OriginalNode.MaterialId);
                return material != null && material.TextureMappings.Where(y => y.Name != "txDetail" && y.Name != "txNormalDetail")
                .Any(m => m.Texture == textureName);
            }));
Beispiel #21
0
 public Kn5SharedMaterials(IDeviceContextHolder holder, IKn5 kn5) : base(holder.Get <IMaterialsFactory>())
 {
     _kn5 = kn5;
 }
Beispiel #22
0
 public TrackMapPreparationRenderer(IKn5 kn5) : base(kn5)
 {
     Camera = new CameraOrtho();
 }
Beispiel #23
0
 public AlphaTexturesProvider(IKn5 kn5)
 {
     _kn5 = kn5;
 }
Beispiel #24
0
 public static bool HasCockpitHr(this IKn5 kn5)
 {
     return(kn5.FirstByName("COCKPIT_HR") != null);
 }
Beispiel #25
0
        public static List <string> FindBodyMaterials(this IKn5 kn5)
        {
            var list = kn5.Materials.Values.Where(x => x.ShaderName == "ksPerPixelMultiMap_damage_dirt").Select(x => x.Name).ToList();

            return(list.Count > 0 ? list : null);
        }
 public Kn5OverrideableTexturesProvider([NotNull] IKn5 kn5, bool asyncLoading, bool asyncOverride) : base(kn5, asyncLoading)
 {
     _asyncOverride = asyncOverride;
 }
 public Kn5SkinnableTexturesProvider([NotNull] IKn5 kn5, bool asyncLoading, bool asyncOverride) : base(kn5, asyncLoading, asyncOverride)
 {
 }
 public BakeryMaterialsFactory(IKn5 kn5)
 {
     _kn5 = kn5;
 }
Beispiel #29
0
 protected ShadowsRendererBase([NotNull] IKn5 kn5, [CanBeNull] DataWrapper carData)
 {
     Kn5     = kn5;
     Scene   = new RenderableList();
     CarData = carData == null ? null : new CarData(carData);
 }
Beispiel #30
0
 public AmbientShadowRenderer([NotNull] IKn5 kn5, [CanBeNull] DataWrapper carData) : base(kn5, carData)
 {
     Iterations = 2000;
 }