Skip to content

Commit

Permalink
Optimized the GLTF mesh building by only including the attributes tha…
Browse files Browse the repository at this point in the history
…t are needed in each mesh.
  • Loading branch information
MeltyPlayer committed Feb 19, 2024
1 parent e71ce8c commit b7d49e2
Show file tree
Hide file tree
Showing 93 changed files with 513 additions and 339 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using fin.data;
using fin.math;
using fin.math.matrix.four;
using fin.model;
using fin.model.accessor;
using fin.ui.rendering.gl.model;
using fin.util.enumerables;
using fin.util.linq;
Expand Down
113 changes: 23 additions & 90 deletions FinModelUtility/Fin/Fin/src/data/indexable/IndexableDictionary.cs
Original file line number Diff line number Diff line change
@@ -1,111 +1,49 @@
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace fin.data.indexable {
public interface IReadOnlyIndexableDictionary<TIndexable, TValue>
: IEnumerable<TValue>
where TIndexable : IIndexable {
int Length { get; }

TValue this[int index] { get; }
TValue this[TIndexable key] { get; }

bool TryGetValue(int index, out TValue value);
bool TryGetValue(TIndexable key, out TValue value);
}

public interface IIndexableDictionary<TIndexable, TValue> :
IReadOnlyIndexableDictionary<TIndexable, TValue>
public interface IIndexableDictionary<TIndexable, TValue>
: IReadOnlyIndexableDictionary<TIndexable, TValue>
where TIndexable : IIndexable {
void Clear();
new TValue this[int index] { get; set; }
new TValue this[TIndexable key] { get; set; }
}

public class IndexableDictionary<TIndexable, TValue>
: IIndexableDictionary<TIndexable, TValue> where TIndexable : IIndexable {
private static readonly ArrayPool<bool> boolPool_ = ArrayPool<bool>.Shared;
private static readonly ArrayPool<TValue> pool_ = ArrayPool<TValue>.Shared;

private bool[] hasKeys_ = Array.Empty<bool>();
private TValue[] impl_ = Array.Empty<TValue>();
public class IndexableDictionary<TIndexable, TValue>(int capacity)
: IIndexableDictionary<TIndexable, TValue>
where TIndexable : IIndexable {
private readonly List<(bool, TValue)> impl_ = new(capacity);

public IndexableDictionary() : this(0) { }

public IndexableDictionary(int length) => this.ResizeLength_(length);

public int Length { get; private set; }

public void Clear() {
for (var i = 0; i < this.Length; i++) {
hasKeys_[i] = false;
this.impl_[i] = default;
}

boolPool_.Return(this.hasKeys_);
this.hasKeys_ = Array.Empty<bool>();

pool_.Return(this.impl_);
this.impl_ = Array.Empty<TValue>();

this.Length = 0;
}

private void ResizeLength_(int newLength) {
var oldCount = this.Length;
if (oldCount < newLength) {
this.Length = newLength;

{
var oldImpl = this.hasKeys_;
this.hasKeys_ = boolPool_.Rent(newLength);

for (var i = 0; i < oldCount; i++) {
this.hasKeys_[i] = oldImpl[i];
}

for (var i = oldCount; i < this.hasKeys_.Length; i++) {
this.hasKeys_[i] = false;
}

if (oldImpl != null) {
boolPool_.Return(oldImpl);
}
}

{
var oldImpl = this.impl_;
this.impl_ = pool_.Rent(newLength);

for (var i = 0; i < oldCount; i++) {
this.impl_[i] = oldImpl[i];
}

for (var i = oldCount; i < this.impl_.Length; i++) {
this.impl_[i] = default;
}

if (oldImpl != null) {
pool_.Return(oldImpl);
}
}
} else if (oldCount > newLength) {
throw new NotSupportedException();
}
}
public void Clear() => this.impl_.Clear();

public TValue this[int index] {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => impl_[index];
get => this.impl_[index].Item2;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set {
ResizeLength_(Math.Max(this.Length, index + 1));
this.impl_.EnsureCapacity(index);

while (this.impl_.Count <= index) {
this.impl_.Add((false, default));
}

this.impl_[index] = value;
this.hasKeys_[index] = true;
this.impl_[index] = (true, value);
}
}

Expand All @@ -117,29 +55,24 @@ public TValue this[TIndexable key] {
}

public bool TryGetValue(int index, out TValue value) {
if (index >= this.Length) {
if (index >= this.impl_.Count) {
value = default!;
return false;
}

value = this.impl_[index];
return this.hasKeys_[index];
(var hasValue, value) = this.impl_[index];
return hasValue;
}

public bool TryGetValue(TIndexable key, out TValue value)
=> TryGetValue(key.Index, out value);
=> this.TryGetValue(key.Index, out value);


IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

public IEnumerator<TValue> GetEnumerator() {
if (this.impl_ != null) {
for (var i = 0; i < this.Length; i++) {
if (this.hasKeys_[i]) {
yield return this.impl_[i];
}
}
}
}
public IEnumerator<TValue> GetEnumerator()
=> this.impl_.Where(pair => pair.Item1)
.Select(pair => pair.Item2)
.GetEnumerator();
}
}
1 change: 1 addition & 0 deletions FinModelUtility/Fin/Fin/src/math/BoneTransformManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using fin.math.matrix.four;
using fin.math.rotations;
using fin.model;
using fin.model.accessor;
using fin.ui;

namespace fin.math {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,7 @@

using fin.color;

namespace fin.model {
public interface IVertexTargeter {
void Target(IReadOnlyVertex vertex);
}

public interface IVertexAccessor
: IVertexNormalAccessor,
IVertexTangentAccessor,
IVertexColorAccessor,
IVertexUvAccessor { }

public interface IVertexNormalAccessor : IVertexTargeter,
IReadOnlyNormalVertex { }

public interface IVertexTangentAccessor : IVertexTargeter,
IReadOnlyTangentVertex { }

public interface IVertexColorAccessor : IVertexTargeter,
IReadOnlySingleColorVertex,
IReadOnlyMultiColorVertex { }

public interface IVertexUvAccessor : IVertexTargeter,
IReadOnlySingleUvVertex,
IReadOnlyMultiUvVertex { }


namespace fin.model.accessor {
/// <summary>
/// Assumes all vertices are the same, consistent type.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using fin.color;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class MultiColorAccessor : BAccessor, IVertexColorAccessor {
private IReadOnlyMultiColorVertex colorVertex_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using fin.color;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class NullColorAccessor
: BAccessor, IVertexColorAccessor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using fin.color;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class SingleColorAccessor : BAccessor, IVertexColorAccessor {
private IReadOnlySingleColorVertex colorVertex_;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class NormalAccessor : BAccessor, IVertexNormalAccessor {
private IReadOnlyNormalVertex normalVertex_;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class NullNormalAccessor : BAccessor, IVertexNormalAccessor {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class NullTangentAccessor
: BAccessor, IVertexTangentAccessor {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class TangentAccessor : BAccessor, IVertexTangentAccessor {
private IReadOnlyTangentVertex tangentVertex_;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class MultiUvAccessor : BAccessor, IVertexUvAccessor {
private IReadOnlyMultiUvVertex uvVertex_;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Runtime.CompilerServices;

namespace fin.model {
public partial class ConsistentVertexAccessor : IVertexAccessor {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class NullUvAccessor
: BAccessor, IVertexUvAccessor {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;

namespace fin.model {
namespace fin.model.accessor {
public partial class ConsistentVertexAccessor {
private sealed class SingleUvAccessor : BAccessor, IVertexUvAccessor {
private IReadOnlySingleUvVertex uvVertex_;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Runtime.CompilerServices;

using fin.color;

namespace fin.model.accessor {
public class MaximalVertexAccessor : IVertexAccessor {
private IReadOnlyVertex currentVertex_;

public static IVertexAccessor GetAccessorForModel(IModel model)
=> new MaximalVertexAccessor();

private MaximalVertexAccessor() { }

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Target(IReadOnlyVertex vertex) {
this.currentVertex_ = vertex;
}

public int Index => this.currentVertex_.Index;

public IBoneWeights? BoneWeights => this.currentVertex_.BoneWeights;
public Position LocalPosition => this.currentVertex_.LocalPosition;

public Normal? LocalNormal
=> (this.currentVertex_ as IReadOnlyNormalVertex)?.LocalNormal;

public Tangent? LocalTangent
=> (this.currentVertex_ as IReadOnlyTangentVertex)?.LocalTangent;

public int ColorCount
=> (this.currentVertex_ as IReadOnlyMultiColorVertex)?.ColorCount ??
(this.currentVertex_ is IReadOnlySingleColorVertex ? 1 : 0);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IColor? GetColor()
=> (this.currentVertex_ as IReadOnlyMultiColorVertex)?.GetColor(0) ??
(this.currentVertex_ as IReadOnlySingleColorVertex)?.GetColor();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IColor? GetColor(int colorIndex)
=> (this.currentVertex_ as IReadOnlyMultiColorVertex)?.GetColor(
colorIndex) ??
(this.currentVertex_ as IReadOnlySingleColorVertex)?.GetColor();

public int UvCount
=> (this.currentVertex_ as IReadOnlyMultiUvVertex)?.UvCount ??
(this.currentVertex_ is IReadOnlySingleUvVertex ? 1 : 0);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TexCoord? GetUv()
=> (this.currentVertex_ as IReadOnlyMultiUvVertex)?.GetUv(0) ??
(this.currentVertex_ as IReadOnlySingleUvVertex)?.GetUv();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TexCoord? GetUv(int uvIndex)
=> (this.currentVertex_ as IReadOnlyMultiUvVertex)?.GetUv(uvIndex) ??
(this.currentVertex_ as IReadOnlySingleUvVertex)?.GetUv();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace fin.model.accessor {
public interface IVertexTargeter {
void Target(IReadOnlyVertex vertex);
}

public interface IVertexAccessor
: IVertexNormalAccessor,
IVertexTangentAccessor,
IVertexColorAccessor,
IVertexUvAccessor {
static abstract IVertexAccessor GetAccessorForModel(IModel model);
}

public interface IVertexNormalAccessor : IVertexTargeter,
IReadOnlyNormalVertex { }

public interface IVertexTangentAccessor : IVertexTargeter,
IReadOnlyTangentVertex { }

public interface IVertexColorAccessor : IVertexTargeter,
IReadOnlySingleColorVertex,
IReadOnlyMultiColorVertex { }

public interface IVertexUvAccessor : IVertexTargeter,
IReadOnlySingleUvVertex,
IReadOnlyMultiUvVertex { }

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Assimp;

using fin.color;
using fin.model.accessor;

namespace fin.model.io.exporters.assimp.indirect {
public class AssimpIndirectUvFixer {
Expand Down
Loading

0 comments on commit b7d49e2

Please sign in to comment.