Skip to content

Commit 9664645

Browse files
committed
improving sparse accessor creation
1 parent 2627df8 commit 9664645

File tree

7 files changed

+471
-224
lines changed

7 files changed

+471
-224
lines changed

src/SharpGLTF.Core/Memory/MemoryAccessor.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Numerics;
5+
using System.Reflection;
56

67
using BYTES = System.ArraySegment<System.Byte>;
78

@@ -325,6 +326,14 @@ internal string _GetDebuggerDisplay()
325326

326327
#region constructor
327328

329+
#if NETSTANDARD
330+
public MemoryAccessor(Byte[] data, MemoryAccessInfo info)
331+
{
332+
this._Slicer = info;
333+
this._Data = new ArraySegment<Byte>(data);
334+
}
335+
#endif
336+
328337
public MemoryAccessor(BYTES data, MemoryAccessInfo info)
329338
{
330339
this._Slicer = info;
@@ -477,6 +486,24 @@ public void Update(BYTES data, MemoryAccessInfo encoding)
477486
this._Data = data;
478487
}
479488

489+
public IAccessorArray<T> AsArrayOf<T>()
490+
{
491+
if (typeof(T) == typeof(int)) return AsIntegerArray() as IAccessorArray<T>;
492+
if (typeof(T) == typeof(float)) return AsScalarArray() as IAccessorArray<T>;
493+
if (typeof(T) == typeof(Vector2)) return AsVector2Array() as IAccessorArray<T>;
494+
if (typeof(T) == typeof(Vector3)) return AsVector3Array() as IAccessorArray<T>;
495+
496+
// AsColorArray is able to handle both Vector3 and Vector4 underlaying data
497+
if (typeof(T) == typeof(Vector4)) return AsColorArray() as IAccessorArray<T>;
498+
499+
if (typeof(T) == typeof(Quaternion)) return AsQuaternionArray() as IAccessorArray<T>;
500+
501+
// we should create the equivalent of AsColorArray for Matrices
502+
if (typeof(T) == typeof(Matrix4x4)) return AsMatrix4x4Array() as IAccessorArray<T>;
503+
504+
throw new NotSupportedException(typeof(T).Name);
505+
}
506+
480507
public IntegerArray AsIntegerArray()
481508
{
482509
Guard.IsTrue(_Slicer.IsValidIndexer, nameof(_Slicer));

src/SharpGLTF.Core/Schema2/gltf.AccessorSparse.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,6 @@ public sealed partial class AccessorSparse
1111

1212
internal AccessorSparse() { }
1313

14-
#endregion
15-
16-
#region properties
17-
18-
public int Count => _count;
19-
20-
#endregion
21-
22-
#region API
23-
2414
internal AccessorSparse(BufferView indices, int indicesOffset, IndexEncodingType indicesEncoding, BufferView values, int valuesOffset, int count)
2515
{
2616
Guard.NotNull(indices, nameof(indices));
@@ -32,6 +22,16 @@ internal AccessorSparse(BufferView indices, int indicesOffset, IndexEncodingType
3222
this._values = new AccessorSparseValues(values, valuesOffset);
3323
}
3424

25+
#endregion
26+
27+
#region properties
28+
29+
public int Count => _count;
30+
31+
#endregion
32+
33+
#region API
34+
3535
internal KeyValuePair<Memory.IntegerArray, Memory.MemoryAccessor> _CreateMemoryAccessors(Accessor baseAccessor)
3636
{
3737
var key = this._indices._GetIndicesArray(baseAccessor.LogicalParent, _count);
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Numerics;
5+
6+
using SharpGLTF.Memory;
7+
8+
using VALIDATIONCTX = SharpGLTF.Validation.ValidationContext;
9+
10+
namespace SharpGLTF.Schema2
11+
{
12+
public sealed partial class Accessor
13+
{
14+
#region Data Arrays
15+
16+
public IAccessorArray<Matrix3x2> AsMatrix2x2Array()
17+
{
18+
return _TryGetMemoryAccessor(out var mem)
19+
? mem.AsMatrix2x2Array()
20+
: new ZeroAccessorArray<Matrix3x2>(this._count);
21+
}
22+
23+
public IAccessorArray<Matrix4x4> AsMatrix3x3Array()
24+
{
25+
return _TryGetMemoryAccessor(out var mem)
26+
? mem.AsMatrix3x3Array()
27+
: new ZeroAccessorArray<Matrix4x4>(this._count);
28+
}
29+
30+
public IAccessorArray<Matrix4x4> AsMatrix4x3Array()
31+
{
32+
/*
33+
const int dimsize = 4 * 3;
34+
35+
var view = SourceBufferView;
36+
var stride = Math.Max(dimsize * this.Encoding.ByteLength(), view.ByteStride);
37+
var content = view.Content.Slice(this.ByteOffset, Count * stride);
38+
39+
return new Matrix4x3Array(content, stride, this.Encoding, this.Normalized);
40+
*/
41+
42+
return _TryGetMemoryAccessor(out var mem)
43+
? mem.AsMatrix4x3Array()
44+
: new ZeroAccessorArray<Matrix4x4>(this._count);
45+
}
46+
47+
public IAccessorArray<Matrix4x4> AsMatrix4x4Array()
48+
{
49+
return _TryGetMemoryAccessor(out var mem)
50+
? mem.AsMatrix4x4Array()
51+
: new ZeroAccessorArray<Matrix4x4>(this._count);
52+
}
53+
54+
[Obsolete("Use AsMatrix4x4Array instead", true)]
55+
internal IReadOnlyList<Matrix4x4> AsMatrix4x4ReadOnlyList()
56+
{
57+
return _TryGetMemoryAccessor(out var mem)
58+
? mem.AsMatrix4x4Array()
59+
: new ZeroAccessorArray<Matrix4x4>(this._count);
60+
}
61+
62+
public IAccessorArray<Quaternion> AsQuaternionArray()
63+
{
64+
if (_TryGetMemoryAccessor(out var memory))
65+
{
66+
if (this._sparse == null) return memory.AsQuaternionArray();
67+
68+
throw new NotImplementedException();
69+
}
70+
else
71+
{
72+
if (this._sparse == null) return new ZeroAccessorArray<Quaternion>(this._count);
73+
74+
throw new NotImplementedException();
75+
}
76+
}
77+
78+
public IAccessorArray<Single[]> AsMultiArray(int dimensions)
79+
{
80+
if (_TryGetMemoryAccessor(out var memory))
81+
{
82+
83+
if (this._sparse == null) return memory.AsMultiArray(dimensions);
84+
85+
throw new NotImplementedException();
86+
}
87+
else
88+
{
89+
// if (this._sparse == null) return new ZeroAccessorArray<Single[]>(this._count);
90+
91+
throw new NotImplementedException();
92+
}
93+
}
94+
95+
#endregion
96+
97+
#region Index Buffer Arrays
98+
99+
100+
public IAccessorArray<UInt32> AsIndicesArray()
101+
{
102+
Guard.IsFalse(this.IsSparse, nameof(IsSparse));
103+
Guard.IsTrue(this.Dimensions == DimensionType.SCALAR, nameof(Dimensions));
104+
105+
return _TryGetMemoryAccessor(out var mem)
106+
? new IntegerArray(SourceBufferView.Content, this.ByteOffset, this._count, this.Encoding.ToIndex())
107+
: new ZeroAccessorArray<UInt32>(this._count);
108+
}
109+
110+
#endregion
111+
112+
#region Vertex Buffer Arrays
113+
114+
internal IAccessorArray<T> AsArrayOf<T>()
115+
{
116+
if (typeof(T) == typeof(int)) return AsIndicesArray() as IAccessorArray<T>;
117+
if (typeof(T) == typeof(float)) return AsScalarArray() as IAccessorArray<T>;
118+
if (typeof(T) == typeof(Vector2)) return AsVector2Array() as IAccessorArray<T>;
119+
if (typeof(T) == typeof(Vector3)) return AsVector3Array() as IAccessorArray<T>;
120+
121+
// AsColorArray is able to handle both Vector3 and Vector4 underlaying data
122+
if (typeof(T) == typeof(Vector4)) return AsColorArray() as IAccessorArray<T>;
123+
124+
if (typeof(T) == typeof(Quaternion)) return AsQuaternionArray() as IAccessorArray<T>;
125+
126+
// we should create the equivalent of AsColorArray for Matrices
127+
if (typeof(T) == typeof(Matrix4x4)) return AsMatrix4x4Array() as IAccessorArray<T>;
128+
129+
throw new NotSupportedException(typeof(T).Name);
130+
}
131+
132+
public IAccessorArray<Single> AsScalarArray()
133+
{
134+
if (_TryGetMemoryAccessor(out var memory))
135+
{
136+
if (this._sparse == null) return memory.AsScalarArray();
137+
138+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
139+
return MemoryAccessor.CreateScalarSparseArray(memory, sparseKV.Key, sparseKV.Value);
140+
}
141+
else
142+
{
143+
if (this._sparse == null) return new ZeroAccessorArray<Single>(this._count);
144+
145+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
146+
return MemoryAccessor.CreateScalarSparseArray(this._count, sparseKV.Key, sparseKV.Value);
147+
}
148+
}
149+
150+
public IAccessorArray<Vector2> AsVector2Array()
151+
{
152+
if (_TryGetMemoryAccessor(out var memory))
153+
{
154+
if (this._sparse == null) return memory.AsVector2Array();
155+
156+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
157+
return MemoryAccessor.CreateVector2SparseArray(memory, sparseKV.Key, sparseKV.Value);
158+
}
159+
else
160+
{
161+
if (this._sparse == null) return new ZeroAccessorArray<Vector2>(this._count);
162+
163+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
164+
return MemoryAccessor.CreateVector2SparseArray(this._count, sparseKV.Key, sparseKV.Value);
165+
}
166+
}
167+
168+
public IAccessorArray<Vector3> AsVector3Array()
169+
{
170+
if (_TryGetMemoryAccessor(out var memory))
171+
{
172+
173+
if (this._sparse == null) return memory.AsVector3Array();
174+
175+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
176+
return MemoryAccessor.CreateVector3SparseArray(memory, sparseKV.Key, sparseKV.Value);
177+
}
178+
else
179+
{
180+
if (this._sparse == null) return new ZeroAccessorArray<Vector3>(this._count);
181+
182+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
183+
return MemoryAccessor.CreateVector3SparseArray(this._count, sparseKV.Key, sparseKV.Value);
184+
}
185+
}
186+
187+
public IAccessorArray<Vector4> AsVector4Array()
188+
{
189+
if (_TryGetMemoryAccessor(out var memory))
190+
{
191+
if (this._sparse == null) return memory.AsVector4Array();
192+
193+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
194+
return MemoryAccessor.CreateVector4SparseArray(memory, sparseKV.Key, sparseKV.Value);
195+
}
196+
else
197+
{
198+
if (this._sparse == null) return new ZeroAccessorArray<Vector4>(this._count);
199+
200+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
201+
return MemoryAccessor.CreateVector4SparseArray(this._count, sparseKV.Key, sparseKV.Value);
202+
}
203+
}
204+
205+
public IAccessorArray<Vector4> AsColorArray(Single defaultW = 1)
206+
{
207+
if (_TryGetMemoryAccessor(out var memory))
208+
{
209+
210+
if (this._sparse == null) return memory.AsColorArray(defaultW);
211+
212+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
213+
return MemoryAccessor.CreateColorSparseArray(memory, sparseKV.Key, sparseKV.Value, defaultW);
214+
}
215+
else
216+
{
217+
if (this._sparse == null) return new ZeroAccessorArray<Vector4>(this._count);
218+
219+
var sparseKV = this._sparse._CreateMemoryAccessors(this);
220+
return MemoryAccessor.CreateColorSparseArray(this._count, sparseKV.Key, sparseKV.Value);
221+
}
222+
}
223+
224+
public ArraySegment<Byte> TryGetVertexBytes(int vertexIdx)
225+
{
226+
if (_sparse != null) throw new InvalidOperationException("Can't be used on Acessors with Sparse Data");
227+
228+
if (!this.TryGetBufferView(out var bufferView)) return default;
229+
230+
var itemByteSz = Encoding.ByteLength() * Dimensions.DimCount();
231+
var byteStride = Math.Max(itemByteSz, bufferView.ByteStride);
232+
var byteOffset = vertexIdx * byteStride;
233+
234+
return bufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), itemByteSz);
235+
}
236+
237+
#endregion
238+
}
239+
}

0 commit comments

Comments
 (0)