|
62 | 62 | using SixLabors.ImageSharp.Formats;
|
63 | 63 | using Image = SixLabors.ImageSharp.Image;
|
64 | 64 | using System.Diagnostics.CodeAnalysis;
|
| 65 | +using HelixToolkit.SharpDX.Core.Animations; |
65 | 66 |
|
66 | 67 | namespace xivModdingFramework.Models.FileTypes
|
67 | 68 | {
|
@@ -2376,6 +2377,16 @@ public static async Task<byte[]> MakeUncompressedMdlFile(TTModel model, string t
|
2376 | 2377 | // but vertex buffers larger than 2^23 will overflow and wrap around in game.
|
2377 | 2378 | public const int _MaxVertexBufferSize = 8388608;
|
2378 | 2379 |
|
| 2380 | + private static void AddVertexHeader(List<VertexDataStruct> source, VertexDataStruct newData) |
| 2381 | + { |
| 2382 | + var elem = source.FirstOrDefault(x => x.DataUsage == newData.DataUsage && x.Count == newData.Count); |
| 2383 | + if (elem != null) |
| 2384 | + { |
| 2385 | + elem.DataType = newData.DataType; |
| 2386 | + } |
| 2387 | + |
| 2388 | + source.Add(newData); |
| 2389 | + } |
2379 | 2390 |
|
2380 | 2391 | /// <summary>
|
2381 | 2392 | /// Creates a new Uncompressed MDL file from the given information.
|
@@ -2421,9 +2432,15 @@ public static byte[] MakeUncompressedMdlFile(TTModel ttModel, XivMdl ogMdl, Acti
|
2421 | 2432 | {
|
2422 | 2433 | vertexSize += 8;
|
2423 | 2434 | }
|
2424 |
| - if (usageInfo.UsesUv2) |
| 2435 | + if (usageInfo.MaxUv > 1) |
2425 | 2436 | {
|
2426 |
| - vertexSize += 8; |
| 2437 | + if (usageInfo.MaxUv == 2) |
| 2438 | + { |
| 2439 | + vertexSize += 8; |
| 2440 | + } else if(usageInfo.MaxUv >= 3) |
| 2441 | + { |
| 2442 | + vertexSize += 16; |
| 2443 | + } |
2427 | 2444 | }
|
2428 | 2445 | if (usageInfo.UsesVColor2)
|
2429 | 2446 | {
|
@@ -2506,181 +2523,115 @@ public static byte[] MakeUncompressedMdlFile(TTModel ttModel, XivMdl ogMdl, Acti
|
2506 | 2523 | var ttMeshGroup = ttModel.MeshGroups.Count > meshNum ? ttModel.MeshGroups[meshNum] : null;
|
2507 | 2524 |
|
2508 | 2525 |
|
2509 |
| - List<VertexDataStruct> source; |
2510 |
| - if (ogGroup == null) |
| 2526 | + // Vertex Header Writing |
| 2527 | + List<VertexDataStruct> source = new List<VertexDataStruct>(); |
| 2528 | + |
| 2529 | + // Standard elements |
| 2530 | + AddVertexHeader(source, new VertexDataStruct() |
2511 | 2531 | {
|
2512 |
| - // New Group, copy data over. |
2513 |
| - source = lod.MeshDataList[0].VertexDataStructList; |
2514 |
| - } |
2515 |
| - else |
| 2532 | + DataBlock = 0, |
| 2533 | + DataType = upgradePrecision ? VertexDataType.Float3 : VertexDataType.Half4, |
| 2534 | + DataUsage = VertexUsageType.Position, |
| 2535 | + }); |
| 2536 | + |
| 2537 | + if (ttModel.HasWeights) |
2516 | 2538 | {
|
2517 |
| - source = ogGroup.VertexDataStructList; |
| 2539 | + AddVertexHeader(source, new VertexDataStruct() |
| 2540 | + { |
| 2541 | + DataBlock = 0, |
| 2542 | + DataType = usageInfo.NeedsEightWeights ? VertexDataType.UByte8 : VertexDataType.Ubyte4n, |
| 2543 | + DataUsage = VertexUsageType.BoneWeight |
| 2544 | + }); |
| 2545 | + AddVertexHeader(source, new VertexDataStruct() |
| 2546 | + { |
| 2547 | + DataBlock = 0, |
| 2548 | + DataType = usageInfo.NeedsEightWeights ? VertexDataType.UByte8 : VertexDataType.Ubyte4, |
| 2549 | + DataUsage = VertexUsageType.BoneIndex |
| 2550 | + }); |
2518 | 2551 | }
|
2519 | 2552 |
|
2520 |
| - // Vertex Header Writing |
2521 |
| - var runningOffsets = new List<int>() { 0, 0, 0 }; |
2522 |
| - source.OrderBy(x => (x.DataBlock * -1000) + x.DataOffset); |
2523 |
| - vertexStreamCounts.Add(source.Max(x => x.DataBlock) + 1); |
| 2553 | + AddVertexHeader(source, new VertexDataStruct() |
| 2554 | + { |
| 2555 | + DataBlock = 1, |
| 2556 | + DataType = upgradePrecision ? VertexDataType.Float3 : VertexDataType.Half4, |
| 2557 | + DataUsage = VertexUsageType.Normal |
| 2558 | + }); |
2524 | 2559 |
|
2525 |
| - if(upgradePrecision) |
| 2560 | + AddVertexHeader(source, new VertexDataStruct() |
2526 | 2561 | {
|
2527 |
| - // Add precomputed tangent data. |
2528 |
| - var tangentCount = source.Count(x => x.DataUsage == VertexUsageType.Tangent); |
2529 |
| - var binormalIdx = source.FindIndex(x => x.DataUsage == VertexUsageType.Binormal); |
2530 |
| - if(binormalIdx >= 0 && tangentCount <= 0 && false) |
2531 |
| - { |
2532 |
| - // Goes in after Binormal |
2533 |
| - source.Insert(binormalIdx + 1, new VertexDataStruct() |
2534 |
| - { |
2535 |
| - DataBlock = 1, |
2536 |
| - DataOffset = 0, // Offset doesn't matter since we recalculate it anyways. |
2537 |
| - DataType = VertexDataType.Ubyte4n, |
2538 |
| - DataUsage = VertexUsageType.Tangent |
2539 |
| - }); |
2540 |
| - } |
2541 |
| - } else |
| 2562 | + DataBlock = 1, |
| 2563 | + DataType = VertexDataType.Ubyte4n, |
| 2564 | + DataUsage = VertexUsageType.Binormal |
| 2565 | + }); |
| 2566 | + |
| 2567 | + // Optional/Situational Elements |
| 2568 | + if (upgradePrecision) |
2542 | 2569 | {
|
2543 |
| - source.RemoveAll(x => x.DataUsage == VertexUsageType.Tangent); |
| 2570 | + AddVertexHeader(source, new VertexDataStruct() |
| 2571 | + { |
| 2572 | + DataBlock = 1, |
| 2573 | + DataType = VertexDataType.Ubyte4n, |
| 2574 | + DataUsage = VertexUsageType.Tangent |
| 2575 | + }); |
2544 | 2576 | }
|
2545 | 2577 |
|
| 2578 | + AddVertexHeader(source, new VertexDataStruct() |
| 2579 | + { |
| 2580 | + DataBlock = 1, |
| 2581 | + DataType = VertexDataType.Ubyte4n, |
| 2582 | + DataUsage = VertexUsageType.Color |
| 2583 | + }); |
| 2584 | + |
2546 | 2585 | if (usageInfo.UsesVColor2)
|
2547 | 2586 | {
|
2548 |
| - // Add 2nd color channel for faux-wind simulation. |
2549 |
| - var colorCounts = source.Count(x => x.DataUsage == VertexUsageType.Color); |
2550 |
| - var colorIdx = source.FindIndex(x => x.DataUsage == VertexUsageType.Color); |
2551 |
| - if (colorCounts == 1) |
| 2587 | + AddVertexHeader(source, new VertexDataStruct() |
2552 | 2588 | {
|
2553 |
| - source.Insert(colorIdx + 1, new VertexDataStruct() |
2554 |
| - { |
2555 |
| - DataBlock = 1, |
2556 |
| - DataOffset = 0, // Offset doesn't matter since we recalculate it anyways. |
2557 |
| - DataType = VertexDataType.Ubyte4n, |
2558 |
| - DataUsage = VertexUsageType.Color |
2559 |
| - }); |
2560 |
| - } |
2561 |
| - } else |
2562 |
| - { |
2563 |
| - source.RemoveAll(x => x.DataUsage == VertexUsageType.Color && x.Count == 1); |
| 2589 | + DataBlock = 1, |
| 2590 | + DataType = VertexDataType.Ubyte4n, |
| 2591 | + DataUsage = VertexUsageType.Color, |
| 2592 | + Count = 1 |
| 2593 | + }); |
2564 | 2594 | }
|
2565 | 2595 |
|
2566 |
| - if (ttModel.HasWeights) |
| 2596 | + if (usageInfo.MaxUv == 1) |
2567 | 2597 | {
|
2568 |
| - // Ensure we have bone vertex structs if we need them. |
2569 |
| - var bone = source.FirstOrDefault(x => x.DataUsage == VertexUsageType.BoneWeight); |
2570 |
| - if (bone == null) |
| 2598 | + AddVertexHeader(source, new VertexDataStruct() |
2571 | 2599 | {
|
2572 |
| - source.Add(new VertexDataStruct() |
2573 |
| - { |
2574 |
| - DataBlock = 0, |
2575 |
| - DataOffset = 0, |
2576 |
| - DataType = VertexDataType.Ubyte4, |
2577 |
| - DataUsage = VertexUsageType.BoneWeight |
2578 |
| - }); |
2579 |
| - } |
2580 |
| - bone = source.FirstOrDefault(x => x.DataUsage == VertexUsageType.BoneIndex); |
2581 |
| - if (bone == null) |
2582 |
| - { |
2583 |
| - source.Add(new VertexDataStruct() |
2584 |
| - { |
2585 |
| - DataBlock = 0, |
2586 |
| - DataOffset = 0, |
2587 |
| - DataType = VertexDataType.Ubyte4, |
2588 |
| - DataUsage = VertexUsageType.BoneIndex |
2589 |
| - }); |
2590 |
| - } |
| 2600 | + DataBlock = 1, |
| 2601 | + DataType = upgradePrecision ? VertexDataType.Float2 : VertexDataType.Half2, |
| 2602 | + DataUsage = VertexUsageType.TextureCoordinate, |
| 2603 | + }); |
2591 | 2604 | } else
|
2592 | 2605 | {
|
2593 |
| - // Remove bone vertex structs if they're not used. |
2594 |
| - source.RemoveAll(x => x.DataUsage == VertexUsageType.BoneWeight); |
2595 |
| - source.RemoveAll(x => x.DataUsage == VertexUsageType.BoneIndex); |
| 2606 | + AddVertexHeader(source, new VertexDataStruct() |
| 2607 | + { |
| 2608 | + DataBlock = 1, |
| 2609 | + DataType = upgradePrecision ? VertexDataType.Float4 : VertexDataType.Half4, |
| 2610 | + DataUsage = VertexUsageType.TextureCoordinate, |
| 2611 | + }); |
| 2612 | + } |
| 2613 | + |
| 2614 | + if (usageInfo.MaxUv > 2) |
| 2615 | + { |
| 2616 | + AddVertexHeader(source, new VertexDataStruct() |
| 2617 | + { |
| 2618 | + DataBlock = 1, |
| 2619 | + DataType = upgradePrecision ? VertexDataType.Float2 : VertexDataType.Half2, |
| 2620 | + DataUsage = VertexUsageType.TextureCoordinate, |
| 2621 | + Count = 1 |
| 2622 | + }); |
2596 | 2623 | }
|
2597 | 2624 |
|
| 2625 | + var runningOffsets = new List<int>() { 0, 0, 0 }; |
| 2626 | + vertexStreamCounts.Add(source.Max(x => x.DataBlock) + 1); |
| 2627 | + |
2598 | 2628 | foreach (var vds in source)
|
2599 | 2629 | {
|
2600 | 2630 | var dataBlock = vds.DataBlock;
|
2601 | 2631 | var dataOffset = vds.DataOffset;
|
2602 | 2632 | var dataType = vds.DataType;
|
2603 | 2633 | var dataUsage = vds.DataUsage;
|
2604 |
| - |
2605 |
| - // Model version 5 doesn't allow double color channel information. |
2606 |
| - if (vdsDictionary.ContainsKey(dataUsage) && mdlVersion == 5) |
2607 |
| - { |
2608 |
| - continue; |
2609 |
| - } |
2610 |
| - |
2611 |
| - // Perform precision updates if requested, and adjustments for MDL version. |
2612 |
| - if (dataUsage == VertexUsageType.Position) |
2613 |
| - { |
2614 |
| - if (upgradePrecision) |
2615 |
| - { |
2616 |
| - dataType = VertexDataType.Float3; |
2617 |
| - } |
2618 |
| - else |
2619 |
| - { |
2620 |
| - dataType = VertexDataType.Half4; |
2621 |
| - } |
2622 |
| - } |
2623 |
| - |
2624 |
| - if (dataUsage == VertexUsageType.BoneWeight) |
2625 |
| - { |
2626 |
| - if (usageInfo.NeedsEightWeights) |
2627 |
| - { |
2628 |
| - dataType = VertexDataType.UByte8; |
2629 |
| - } |
2630 |
| - else |
2631 |
| - { |
2632 |
| - dataType = VertexDataType.Ubyte4n; |
2633 |
| - } |
2634 |
| - } |
2635 |
| - |
2636 |
| - if (dataUsage == VertexUsageType.BoneIndex) |
2637 |
| - { |
2638 |
| - if (usageInfo.NeedsEightWeights) |
2639 |
| - { |
2640 |
| - dataType = VertexDataType.UByte8; |
2641 |
| - } |
2642 |
| - else |
2643 |
| - { |
2644 |
| - dataType = VertexDataType.Ubyte4; |
2645 |
| - } |
2646 |
| - } |
2647 |
| - |
2648 |
| - if (dataUsage == VertexUsageType.Normal) |
2649 |
| - { |
2650 |
| - if (upgradePrecision) |
2651 |
| - { |
2652 |
| - dataType = VertexDataType.Float3; |
2653 |
| - } |
2654 |
| - else |
2655 |
| - { |
2656 |
| - dataType = VertexDataType.Half4; |
2657 |
| - } |
2658 |
| - } |
2659 |
| - |
2660 |
| - if (dataUsage == VertexUsageType.TextureCoordinate) |
2661 |
| - { |
2662 |
| - if (upgradePrecision) |
2663 |
| - { |
2664 |
| - if (usageInfo.UsesUv2) |
2665 |
| - { |
2666 |
| - dataType = VertexDataType.Float4; |
2667 |
| - } |
2668 |
| - else |
2669 |
| - { |
2670 |
| - dataType = VertexDataType.Float2; |
2671 |
| - } |
2672 |
| - } |
2673 |
| - else |
2674 |
| - { |
2675 |
| - if (usageInfo.UsesUv2) |
2676 |
| - { |
2677 |
| - dataType = VertexDataType.Half4; |
2678 |
| - } else |
2679 |
| - { |
2680 |
| - dataType = VertexDataType.Half2; |
2681 |
| - } |
2682 |
| - } |
2683 |
| - } |
| 2634 | + var ct = vds.Count; |
2684 | 2635 |
|
2685 | 2636 | var count = 0;
|
2686 | 2637 | if (!vdsDictionary.ContainsKey(dataUsage))
|
@@ -4106,6 +4057,21 @@ private static int WriteVertex(VertexByteData importData, Dictionary<VertexUsage
|
4106 | 4057 | }
|
4107 | 4058 | }
|
4108 | 4059 | }
|
| 4060 | + if(vertexInfoList.ContainsKey(VertexUsageType.TextureCoordinate) && vertexInfoList[VertexUsageType.TextureCoordinate].Count > 1) |
| 4061 | + { |
| 4062 | + var texCoordDataType = vertexInfoList[VertexUsageType.TextureCoordinate][1]; |
| 4063 | + if (texCoordDataType == VertexDataType.Float2) |
| 4064 | + { |
| 4065 | + importData.VertexData1.AddRange(BitConverter.GetBytes(v.UV3[0])); |
| 4066 | + importData.VertexData1.AddRange(BitConverter.GetBytes(v.UV3[1])); |
| 4067 | + |
| 4068 | + } |
| 4069 | + else if (texCoordDataType == VertexDataType.Half2) |
| 4070 | + { |
| 4071 | + importData.VertexData1.AddRange(BitConverter.GetBytes(((Half)v.UV3[0]).RawValue)); |
| 4072 | + importData.VertexData1.AddRange(BitConverter.GetBytes(((Half)v.UV3[1]).RawValue)); |
| 4073 | + } |
| 4074 | + } |
4109 | 4075 |
|
4110 | 4076 |
|
4111 | 4077 | var size0 = importData.VertexData0.Count - start0;
|
|
0 commit comments