• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MeltyPlayer / MeltyTool / 22551907903

01 Mar 2026 08:26PM UTC coverage: 41.595% (+0.06%) from 41.54%
22551907903

push

github

MeltyPlayer
Set up a little project for loading Mario Kart 3d tracks.

6988 of 18904 branches covered (36.97%)

Branch coverage included in aggregate %.

0 of 52 new or added lines in 4 files covered. (0.0%)

726 existing lines in 36 files now uncovered.

29926 of 69843 relevant lines covered (42.85%)

62490.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.98
/FinModelUtility/Libraries/GameMaker/GameMaker/src/api/D3dModelImporter.cs
1
using System.Numerics;
2

3
using fin.animation.keyframes;
4
using fin.image;
5
using fin.io;
6
using fin.io.bundles;
7
using fin.math.transform;
8
using fin.model;
9
using fin.model.impl;
10
using fin.model.io;
11
using fin.model.io.importers;
12
using fin.model.util;
13
using fin.util.sets;
14

15
using gm.schema.d3d;
16

17

18
namespace gm.api;
19

20
public sealed class D3dModelFileBundle : IModelFileBundle {
21
  public required IReadOnlyTreeFile D3dFile { get; init; }
×
22

UNCOV
23
  public IReadOnlyTreeFile? TextureFile { get; init; }
×
24

25
  public (IReadOnlyTreeFile gifFile, float frameRate)? AnimatedTextureFile {
26
    get;
×
27
    init;
×
28
  }
29

30
  public IReadOnlyTreeFile MainFile => this.D3dFile;
×
UNCOV
31
  public bool FlipNormals { get; init; }
×
32
  public WrapMode TextureWrapMode { get; init; }
×
33
}
34

35
public sealed class D3dModelImporter : IModelImporter<D3dModelFileBundle> {
36
  public IModel Import(D3dModelFileBundle modelFileBundle) {
×
UNCOV
37
    var d3dFile = modelFileBundle.D3dFile;
×
38
    var d3d = d3dFile.ReadNewFromText<D3d>();
×
39

40
    var (finModel, finRootBone)
×
41
        = CreateModel((modelFileBundle, d3dFile.AsFileSet()));
×
42

UNCOV
43
    ITextureMaterial? material = null;
×
44
    if (modelFileBundle.TextureFile is { } textureFile) {
×
45
      (material, var texture) =
×
UNCOV
46
          finModel.MaterialManager.AddSimpleTextureMaterialFromFile(
×
UNCOV
47
              textureFile);
×
UNCOV
48
      texture.WrapModeU = texture.WrapModeV = modelFileBundle.TextureWrapMode;
×
UNCOV
49
    } else if (modelFileBundle.AnimatedTextureFile is { } gifFileAndFrameRate) {
×
UNCOV
50
      var (gifFile, frameRate) = gifFileAndFrameRate;
×
51

UNCOV
52
      var frameImages = FinImage.FromGifFile(gifFile);
×
UNCOV
53
      var name = gifFile.NameWithoutExtension.ToString();
×
54

UNCOV
55
      var finMaterialManager = finModel.MaterialManager;
×
UNCOV
56
      var frameTextures
×
UNCOV
57
          = frameImages
×
UNCOV
58
            .Select((frameImage, i) => {
×
UNCOV
59
              var frameTexture = finMaterialManager.CreateTexture(
×
UNCOV
60
                  frameImage.RemoveTopLeftBackgroundColor());
×
UNCOV
61
              frameTexture.Name =
×
UNCOV
62
                  frameImages.Length > 0 ? $"{name}_{i}" : name;
×
UNCOV
63
              frameTexture.WrapModeU = frameTexture.WrapModeV =
×
UNCOV
64
                  modelFileBundle.TextureWrapMode;
×
UNCOV
65
              return frameTexture;
×
UNCOV
66
            })
×
UNCOV
67
            .ToArray();
×
68

UNCOV
69
      var baseTexture = frameTextures[0];
×
70

UNCOV
71
      material = finMaterialManager.AddTextureMaterial(baseTexture);
×
UNCOV
72
      material.Name = "diffuse";
×
73

UNCOV
74
      var animation = finModel.AnimationManager.AddAnimation();
×
UNCOV
75
      animation.Name = name;
×
UNCOV
76
      animation.FrameCount = frameImages.Length;
×
UNCOV
77
      animation.FrameRate = frameRate;
×
78

UNCOV
79
      var textureTracks = animation.AddTextureTracks(baseTexture);
×
UNCOV
80
      var flipbookSwapKeyframes
×
UNCOV
81
          = textureTracks.UseFlipbookSwapKeyframes(frameTextures.Length);
×
UNCOV
82
      for (var f = 0; f < frameTextures.Length; ++f) {
×
UNCOV
83
        flipbookSwapKeyframes.Add(
×
UNCOV
84
            new Keyframe<IReadOnlyTexture?>(f, frameTextures[f]));
×
UNCOV
85
      }
×
UNCOV
86
    }
×
87

UNCOV
88
    AddToModel(d3d, finModel, finRootBone, out _, material);
×
89

UNCOV
90
    if (modelFileBundle.FlipNormals) {
×
UNCOV
91
      finModel.FlipAllNormals();
×
UNCOV
92
    }
×
93

UNCOV
94
    return finModel;
×
UNCOV
95
  }
×
96

97
  public static (IModel<ISkin<Normal1Color1UvVertexImpl>>, IBone) CreateModel(
98
      (IFileBundle fileBundle, IReadOnlySet<IReadOnlyGenericFile> files)?
99
          modelMetadata = null) {
1✔
100
    var finModel =
1!
101
        new ModelImpl<Normal1Color1UvVertexImpl>((index, position)
1✔
102
                                                     => new
4,791✔
103
                                                         Normal1Color1UvVertexImpl(
4,791✔
104
                                                             index,
4,791✔
105
                                                             position)) {
4,791✔
106
            FileBundle = modelMetadata?.fileBundle!,
1✔
107
            Files = modelMetadata?.files!
1✔
108
        };
1✔
109
    var finRootBone = CreateAdjustedRootBone(finModel);
1✔
110
    return (finModel, finRootBone);
1✔
111
  }
1✔
112

113
  public static IBone CreateAdjustedRootBone(IModel finModel) {
1✔
114
    var finSkeleton = finModel.Skeleton;
1✔
115
    var bone = finSkeleton.Root.AddRoot(0, 0, 0);
1✔
116
    bone.Transform.SetRotationDegrees(-90, 180, 0);
1✔
117
    bone.Transform.SetScale(-1, 1, 1);
1✔
118
    return bone;
1✔
119
  }
1✔
120

121
  public static void AddToModel(D3d d3d,
122
                                IModel<ISkin<Normal1Color1UvVertexImpl>>
123
                                    finModel,
124
                                IReadOnlyBone bone,
125
                                out IMesh finMesh,
126
                                IMaterial? material = null) {
13✔
127
    var finSkin = finModel.Skin;
13✔
128
    finMesh = finSkin.AddMesh();
13✔
129

130
    var boneWeights = finSkin.GetOrCreateBoneWeights(
13✔
131
        VertexSpace.RELATIVE_TO_BONE,
13✔
132
        bone);
13✔
133

134
    D3dPrimitiveType d3dPrimitiveType = default;
13✔
135
    var finVertices = new LinkedList<IVertex>();
13✔
136
    foreach (var d3dCommand in d3d.Commands) {
14,508✔
137
      switch (d3dCommand.CommandType) {
4,823!
138
        case D3dCommandType.BEGIN: {
16✔
139
          d3dPrimitiveType = (D3dPrimitiveType) d3dCommand.Parameters[0];
16✔
140
          break;
16✔
141
        }
142
        case D3dCommandType.END: {
16✔
143
          switch (d3dPrimitiveType) {
16!
UNCOV
144
            case D3dPrimitiveType.TRIANGLE_FAN: {
×
UNCOV
145
              finMesh.AddTriangleFan(finVertices.ToArray())
×
UNCOV
146
                     .SetMaterial(material);
×
UNCOV
147
              break;
×
148
            }
149
            case D3dPrimitiveType.TRIANGLE_LIST: {
16✔
150
              finMesh.AddTriangles(finVertices.ToArray())
16✔
151
                     .SetMaterial(material);
16✔
152
              break;
16✔
153
            }
UNCOV
154
            case D3dPrimitiveType.TRIANGLE_STRIP: {
×
UNCOV
155
              finMesh.AddTriangleStrip(finVertices.ToArray())
×
UNCOV
156
                     .SetMaterial(material);
×
UNCOV
157
              break;
×
158
            }
UNCOV
159
            default: throw new NotImplementedException();
×
160
          }
161

162
          finVertices.Clear();
16✔
163
          break;
16✔
164
        }
165
        case D3dCommandType.VERTEX_NORMAL_TEXTURE: {
4,791✔
166
          var d3dParams = d3dCommand.Parameters.AsSpan();
4,791✔
167

168
          var finVertex = finSkin.AddVertex(new Vector3(d3dParams[..3]));
4,791✔
169
          finVertex.SetLocalNormal(-new Vector3(d3dParams.Slice(3, 3)));
4,791✔
170
          finVertex.SetUv(new Vector2(d3dParams.Slice(6, 2)));
4,791✔
171
          finVertex.SetBoneWeights(boneWeights);
4,791✔
172

173
          finVertices.AddLast(finVertex);
4,791✔
174
          break;
4,791✔
175
        }
UNCOV
176
        case D3dCommandType.VERTEX_TEXTURE: {
×
UNCOV
177
          var d3dParams = d3dCommand.Parameters.AsSpan();
×
178

UNCOV
179
          var finVertex = finSkin.AddVertex(new Vector3(d3dParams[..3]));
×
UNCOV
180
          finVertex.SetUv(new Vector2(d3dParams.Slice(3, 2)));
×
UNCOV
181
          finVertex.SetBoneWeights(boneWeights);
×
182

UNCOV
183
          finVertices.AddLast(finVertex);
×
UNCOV
184
          break;
×
185
        }
UNCOV
186
        case D3dCommandType.VERTEX_TEXTURE_COLOR: {
×
UNCOV
187
          var d3dParams = d3dCommand.Parameters.AsSpan();
×
188

UNCOV
189
          var finVertex = finSkin.AddVertex(new Vector3(d3dParams[..3]));
×
UNCOV
190
          finVertex.SetUv(new Vector2(d3dParams.Slice(3, 2)));
×
UNCOV
191
          finVertex.SetColor(new Vector3(d3dParams.Slice(5, 3)) / 255f);
×
UNCOV
192
          finVertex.SetBoneWeights(boneWeights);
×
193

UNCOV
194
          finVertices.AddLast(finVertex);
×
UNCOV
195
          break;
×
196
        }
UNCOV
197
        default: throw new ArgumentOutOfRangeException();
×
198
      }
199
    }
4,823✔
200
  }
13✔
201
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc