// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes int ExportIndices(int[] indices) { // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#primitiveindices indices = CoordUtils.FlipIndices(indices).ToArray(); // Scalar | UNSIGNED_BYTE // | UNSIGNED_SHORT // | UNSIGNED_INT! (TODO: optimize kind...) byte[] buffer = PrimitiveExporter.Marshal(indices); var viewIndex = BufferBuilder.AddView( new ArraySegment <byte>(buffer), null, Types.BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER); var viewComponentType = Types.Accessor.ComponentTypeEnum.UNSIGNED_INT; var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = viewComponentType, Count = indices.Length, Type = Types.Accessor.TypeEnum.Scalar, }; return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }
int ExportPositions(Vector3[] vec3, int[] indices = null) { Types.Accessor.ComponentTypeEnum viewComponentType; var viewIndex = ExportPositionsBuffer(ref vec3, out viewComponentType); var sparseIndexType = default(Types.Accessor.SparseType.IndicesType.ComponentTypeEnum); int?sparseViewIndex = null; if (indices != null) { Debug.Assert(indices.Length == vec3.Length); sparseViewIndex = ExportSparseIndicesBuffer(ref indices, out sparseIndexType); } // position MUST have min/max var min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); var max = new Vector3(float.MinValue, float.MinValue, float.MinValue); foreach (var v in vec3) { min = new Vector3(Mathf.Min(v.x, min.x), Mathf.Min(v.y, min.y), Mathf.Min(v.z, min.z)); max = new Vector3(Mathf.Max(v.x, max.x), Mathf.Max(v.y, max.y), Mathf.Max(v.z, max.z)); } var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = viewComponentType, Count = vec3.Length, Type = Types.Accessor.TypeEnum.Vec3, Min = new float[] { min.x, min.y, min.z }, Max = new float[] { max.x, max.y, max.z }, }; if (sparseViewIndex != null) { accessor.Sparse = new Types.Accessor.SparseType { Count = vec3.Length, Indices = new Types.Accessor.SparseType.IndicesType { BufferView = sparseViewIndex.Value, ByteOffset = 0, ComponentType = sparseIndexType, }, Values = new Types.Accessor.SparseType.ValuesType { BufferView = accessor.BufferView.Value, ByteOffset = accessor.ByteOffset, }, }; accessor.BufferView = null; } return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skin int ExportInverseBindMatrices(Matrix4x4[] matrices) { matrices = matrices.Select(CoordUtils.ConvertSpace).ToArray(); // MAT4! | FLOAT! byte[] buffer = PrimitiveExporter.Marshal(matrices); var viewIndex = BufferBuilder.AddView(new ArraySegment <byte>(buffer)); var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = Types.Accessor.ComponentTypeEnum.FLOAT, Count = matrices.Length, Type = Types.Accessor.TypeEnum.Mat4, }; return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }
int ExportWeights(Vector4[] weights) { // VEC4! | FLOAT! // | UNSIGNED_BYTE (normalized) // | UNSIGNED_SHORT (normalized) byte[] buffer = PrimitiveExporter.Marshal(weights); var viewIndex = BufferBuilder.AddView(new ArraySegment <byte>(buffer)); var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = Types.Accessor.ComponentTypeEnum.FLOAT, Count = weights.Length, Type = Types.Accessor.TypeEnum.Vec4, }; return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }
int ExportTangents(Vector4[] vec4) { vec4 = vec4.Select(CoordUtils.ConvertSpace).ToArray(); // VEC4! | FLOAT! byte[] buffer = PrimitiveExporter.Marshal(vec4); var viewIndex = BufferBuilder.AddView(new ArraySegment <byte>(buffer)); var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = Types.Accessor.ComponentTypeEnum.FLOAT, Count = vec4.Length, Type = Types.Accessor.TypeEnum.Vec4, }; return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }
int ExportUV(Vector2[] uv) { uv = uv.Select(CoordUtils.ConvertUV).ToArray(); // VEC2! | FLOAT! // | UNSIGNED_BYTE (normalized) // | UNSIGNED_SHORT (normalized) byte[] buffer = PrimitiveExporter.Marshal(uv); var viewIndex = BufferBuilder.AddView(new ArraySegment <byte>(buffer)); var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = Types.Accessor.ComponentTypeEnum.FLOAT, Count = uv.Length, Type = Types.Accessor.TypeEnum.Vec2, }; return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }
int ExportJoints(Vec4 <int>[] joints) { // VEC4! | UNSIGNED_BYTE // | UNSIGNED_SHORT! byte[] buffer = PrimitiveExporter.Marshal( joints .Select(v => new Vec4 <ushort>((ushort)v.x, (ushort)v.y, (ushort)v.z, (ushort)v.w)) .ToArray() ); var viewIndex = BufferBuilder.AddView(new ArraySegment <byte>(buffer)); var accessor = new Types.Accessor { BufferView = viewIndex, ByteOffset = 0, ComponentType = Types.Accessor.ComponentTypeEnum.UNSIGNED_SHORT, Count = joints.Length, Type = Types.Accessor.TypeEnum.Vec4, }; return(Types.GltfExtensions.AddAccessor(Gltf, accessor)); }