static Memory <byte> GetAccessorBytes(Gltf gltf, GltfAccessor accessor, Memory <byte> bin) { var view = gltf.bufferViews[accessor.bufferView]; var byteSize = accessor.componentType.ByteSize() * accessor.type.TypeCount() * accessor.count; return(bin.Slice(view.byteOffset, view.byteLength).Slice(accessor.byteOffset, byteSize)); }
private IEnumerable <Polygon> readIndices(GltfAccessor accessor, GltfMeshPrimitive.ModeEnum mode) { if (!accessor.BufferView.HasValue) { return(new List <Polygon>()); } StreamIO stream = getBufferStream(accessor); switch (mode) { case GltfMeshPrimitive.ModeEnum.TRIANGLES: return(readAccessor <Triangle>(stream, accessor.ComponentType, accessor.Count / 3, 3)); case GltfMeshPrimitive.ModeEnum.POINTS: case GltfMeshPrimitive.ModeEnum.LINES: //Works with the 3d lines, like polylines and lines case GltfMeshPrimitive.ModeEnum.LINE_LOOP: case GltfMeshPrimitive.ModeEnum.LINE_STRIP: case GltfMeshPrimitive.ModeEnum.TRIANGLE_STRIP: case GltfMeshPrimitive.ModeEnum.TRIANGLE_FAN: return(new List <Polygon>()); default: throw new NotImplementedException(); } }
public static async Task <Vector4[]> GetVector4Array(this GltfAccessor accessor, bool convert = true) { if (accessor.type != "VEC4" || accessor.componentType == GltfComponentType.UnsignedInt) { return(null); } if (Application.isPlaying) { await BackgroundThread; } var array = new Vector4[accessor.count]; GetTypeDetails(accessor.componentType, out int componentSize, out float maxValue); var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize * 4; var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } if (accessor.normalized) { maxValue = 1; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i].x = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 0); array[i].y = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 1); array[i].z = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 2); array[i].w = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 3); } else { array[i].x = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 0, accessor.componentType) / maxValue; array[i].y = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 1, accessor.componentType) / maxValue; array[i].z = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 2, accessor.componentType) / maxValue; array[i].w = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 3, accessor.componentType) / maxValue; } if (convert) { array[i].x *= TangentSpaceConversionScale.x; array[i].y *= TangentSpaceConversionScale.y; array[i].z *= TangentSpaceConversionScale.z; array[i].w *= TangentSpaceConversionScale.w; } } if (Application.isPlaying) { await Update; } return(array); }
private StreamIO getBufferStream(GltfAccessor accessor) { GltfBufferView bufferView = _root.BufferViews[accessor.BufferView.Value]; GltfBuffer buffer = _root.Buffers[bufferView.Buffer]; StreamIO stream = new StreamIO(_chunk.GetBytes(0, buffer.ByteLength)); stream.Position = bufferView.ByteOffset + accessor.ByteOffset; return(stream); }
private GltfAccessor[] ExtractAccessors(Gltf model) { var noOfItems = model.Accessors != null ? model.Accessors.Length : 0; var output = new GltfAccessor[noOfItems]; for (var i = 0; i < noOfItems; i += 1) { output[i] = new GltfAccessor(model.Accessors[i]); } return(output); }
public static Vector3[] GetVector3Array(this GltfAccessor accessor, bool convert = true) { if (accessor.type != "VEC3" || accessor.componentType == GltfComponentType.UnsignedInt) { return(null); } var array = new Vector3[accessor.count]; int componentSize; float maxValue; GetTypeDetails(accessor.componentType, out componentSize, out maxValue); var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize * 3; var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } if (accessor.normalized) { maxValue = 1; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i].x = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 0); array[i].y = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 1); array[i].z = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 2); } else { array[i].x = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 0, accessor.componentType) / maxValue; array[i].y = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 1, accessor.componentType) / maxValue; array[i].z = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 2, accessor.componentType) / maxValue; } if (convert) { array[i].x *= CoordinateSpaceConversionScale.x; array[i].y *= CoordinateSpaceConversionScale.y; array[i].z *= CoordinateSpaceConversionScale.z; } } return(array); }
public static async Task <int[]> GetIntArray(this GltfAccessor accessor, bool flipFaces = true) { if (accessor.type != "SCALAR") { return(null); } if (Application.isPlaying) { await BackgroundThread; } var array = new int[accessor.count]; GetTypeDetails(accessor.componentType, out int componentSize, out float maxValue); var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize; var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i] = (int)Mathf.Floor(BitConverter.ToSingle(bufferData, byteOffset + i * stride)); } else { array[i] = (int)GetDiscreteUnsignedElement(bufferData, byteOffset + i * stride, accessor.componentType); } } if (flipFaces) { for (int i = 0; i < array.Length; i += 3) { var temp = array[i]; array[i] = array[i + 2]; array[i + 2] = temp; } } if (Application.isPlaying) { await Update; } return(array); }
protected List <XYZ> readXYZ(GltfAccessor accessor) { if (!accessor.BufferView.HasValue) { return(new List <XYZ>()); } if (accessor.Type != GltfAccessor.TypeEnum.VEC3) { throw new Exception(); } return(readAccessor <XYZ>(getBufferStream(accessor), accessor.ComponentType, accessor.Count, 3)); }
public static async Task <Color[]> GetColorArray(this GltfAccessor accessor) { if (accessor.type != "VEC3" && accessor.type != "VEC4" || accessor.componentType == GltfComponentType.UnsignedInt) { return(null); } if (Application.isPlaying) { await BackgroundThread; } var array = new Color[accessor.count]; GetTypeDetails(accessor.componentType, out int componentSize, out float maxValue); bool hasAlpha = accessor.type == "VEC4"; var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize * (hasAlpha ? 4 : 3); var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i].r = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 0); array[i].g = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 1); array[i].b = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 2); array[i].a = hasAlpha ? BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 3) : 1f; } else { array[i].r = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 0, accessor.componentType) / maxValue; array[i].g = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 1, accessor.componentType) / maxValue; array[i].b = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 2, accessor.componentType) / maxValue; array[i].a = hasAlpha ? GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 3, accessor.componentType) / maxValue : 1f; } } if (Application.isPlaying) { await Update; } return(array); }
public static async Task <Vector2[]> GetVector2Array(this GltfAccessor accessor, bool flip = true) { if (accessor.type != "VEC2" || accessor.componentType == GltfComponentType.UnsignedInt) { return(null); } await BackgroundThread; var array = new Vector2[accessor.count]; GetTypeDetails(accessor.componentType, out int componentSize, out float maxValue); var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize * 2; var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } if (accessor.normalized) { maxValue = 1; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i].x = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 0); array[i].y = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 1); } else { array[i].x = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 0, accessor.componentType) / maxValue; array[i].y = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 1, accessor.componentType) / maxValue; } if (flip) { array[i].y = 1.0f - array[i].y; } } await Update; return(array); }
/// <summary> /// Get Int array from accessor /// </summary> public static int[] GetIntArray(this GltfAccessor accessor, bool flipFaces = true) { if (accessor.type != scalar) { return(null); } var array = new int[accessor.count]; GetTypeDetails(accessor.componentType, out int componentSize, out float _); var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize; var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i] = (int)Mathf.Floor(BitConverter.ToSingle(bufferData, byteOffset + i * stride)); } else { array[i] = (int)GetDiscreteUnsignedElement(bufferData, byteOffset + i * stride, accessor.componentType); } } if (flipFaces) { for (int i = 0; i < array.Length; i += 3) { var temp = array[i]; array[i] = array[i + 2]; array[i + 2] = temp; } } return(array); }
internal static Color[] GetColorArray(this GltfAccessor accessor) { if (accessor.type != vec3 && accessor.type != vec4 || accessor.componentType == GltfComponentType.UnsignedInt) { return(null); } var array = new Color[accessor.count]; GetTypeDetails(accessor.componentType, out int componentSize, out float maxValue); bool hasAlpha = accessor.type == vec4; var stride = accessor.BufferView.byteStride > 0 ? accessor.BufferView.byteStride : componentSize * (hasAlpha ? 4 : 3); var byteOffset = accessor.BufferView.byteOffset; var bufferData = accessor.BufferView.Buffer.BufferData; if (accessor.byteOffset >= 0) { byteOffset += accessor.byteOffset; } for (int i = 0; i < accessor.count; i++) { if (accessor.componentType == GltfComponentType.Float) { array[i].r = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 0); array[i].g = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 1); array[i].b = BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 2); array[i].a = hasAlpha ? BitConverter.ToSingle(bufferData, byteOffset + i * stride + componentSize * 3) : 1f; } else { array[i].r = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 0, accessor.componentType) / maxValue; array[i].g = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 1, accessor.componentType) / maxValue; array[i].b = GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 2, accessor.componentType) / maxValue; array[i].a = hasAlpha ? GetDiscreteElement(bufferData, byteOffset + i * stride + componentSize * 3, accessor.componentType) / maxValue : 1f; } } return(array); }
static Int32[] GetAccessorAsIntArray(Gltf gltf, GltfAccessor a, Memory <byte> bytes) { if (a.componentType == GltfComponentType.UNSIGNED_INT) { return(MemoryMarshal.Cast <byte, int>(GetAccessorBytes(gltf, a, bytes).Span).ToArray()); } else if (a.componentType == GltfComponentType.UNSIGNED_SHORT || a.componentType == GltfComponentType.SHORT) { var span = MemoryMarshal.Cast <byte, ushort>(GetAccessorBytes(gltf, a, bytes).Span); var array = new int[span.Length]; for (int i = 0; i < span.Length; ++i) { array[i] = span[i]; } return(array); } else { throw new Exception(); } }
public IEnumerator TestGltfCustomAttributesData() { // Load glTF string path = AssetDatabase.GUIDToAssetPath(CubeCustomAttrGuid); var task = GltfUtility.ImportGltfObjectFromPathAsync(path); yield return(WaitForTask(task)); GltfObject gltfObject = task.Result; yield return(null); // Check for custom vertex data is a list of 10s gltfObject.meshes[0].primitives[0].Attributes.TryGetValue("_CUSTOM_ATTR", out var customAttrIdx); GltfAccessor accessor = gltfObject.GetAccessor(customAttrIdx); var intArray = accessor.GetIntArray(false); foreach (var item in intArray) { Assert.AreEqual(10, item); } }
private static GltfInterleavedOperation CreateCopyOp(List <GltfInterleavedOperation> destination, GltfAccessor selected, GltfBufferView[] bufferViews) { if (!selected.BufferView.HasValue) { throw new InvalidOperationException("unable to locate bufferview"); } var view = bufferViews[selected.BufferView.Value]; var op = new GltfInterleavedOperation { BufferIndex = view.BufferIndex, Count = selected.ElementCount, SrcOffset = (ulong)(view.BufferOffset + selected.ViewOffset), TotalSize = (uint)(selected.ElementCount * selected.NoOfComponents * selected.ElementByteSize), }; op.ByteStride = (view.ByteStride.HasValue) ? (uint)view.ByteStride.Value : selected.NoOfComponents * selected.ElementByteSize; destination.Add(op); return(op); }
private static async Task <Mesh> ConstructMeshPrimitiveAsync(GltfObject gltfObject, GltfMeshPrimitive meshPrimitive) { if (Application.isPlaying) { await BackgroundThread; } GltfAccessor positionAccessor = null; GltfAccessor normalsAccessor = null; GltfAccessor textCoord0Accessor = null; GltfAccessor textCoord1Accessor = null; GltfAccessor textCoord2Accessor = null; GltfAccessor textCoord3Accessor = null; GltfAccessor colorAccessor = null; GltfAccessor indicesAccessor = null; GltfAccessor tangentAccessor = null; GltfAccessor weight0Accessor = null; GltfAccessor joint0Accessor = null; int vertexCount = 0; if (meshPrimitive.Attributes.POSITION >= 0) { positionAccessor = gltfObject.accessors[meshPrimitive.Attributes.POSITION]; positionAccessor.BufferView = gltfObject.bufferViews[positionAccessor.bufferView]; positionAccessor.BufferView.Buffer = gltfObject.buffers[positionAccessor.BufferView.buffer]; vertexCount = positionAccessor.count; } if (meshPrimitive.Attributes.NORMAL >= 0) { normalsAccessor = gltfObject.accessors[meshPrimitive.Attributes.NORMAL]; normalsAccessor.BufferView = gltfObject.bufferViews[normalsAccessor.bufferView]; normalsAccessor.BufferView.Buffer = gltfObject.buffers[normalsAccessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_0 >= 0) { textCoord0Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_0]; textCoord0Accessor.BufferView = gltfObject.bufferViews[textCoord0Accessor.bufferView]; textCoord0Accessor.BufferView.Buffer = gltfObject.buffers[textCoord0Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_1 >= 0) { textCoord1Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_1]; textCoord1Accessor.BufferView = gltfObject.bufferViews[textCoord1Accessor.bufferView]; textCoord1Accessor.BufferView.Buffer = gltfObject.buffers[textCoord1Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_2 >= 0) { textCoord2Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_2]; textCoord2Accessor.BufferView = gltfObject.bufferViews[textCoord2Accessor.bufferView]; textCoord2Accessor.BufferView.Buffer = gltfObject.buffers[textCoord2Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_3 >= 0) { textCoord3Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_3]; textCoord3Accessor.BufferView = gltfObject.bufferViews[textCoord3Accessor.bufferView]; textCoord3Accessor.BufferView.Buffer = gltfObject.buffers[textCoord3Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.COLOR_0 >= 0) { colorAccessor = gltfObject.accessors[meshPrimitive.Attributes.COLOR_0]; colorAccessor.BufferView = gltfObject.bufferViews[colorAccessor.bufferView]; colorAccessor.BufferView.Buffer = gltfObject.buffers[colorAccessor.BufferView.buffer]; } if (meshPrimitive.indices >= 0) { indicesAccessor = gltfObject.accessors[meshPrimitive.indices]; indicesAccessor.BufferView = gltfObject.bufferViews[indicesAccessor.bufferView]; indicesAccessor.BufferView.Buffer = gltfObject.buffers[indicesAccessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TANGENT >= 0) { tangentAccessor = gltfObject.accessors[meshPrimitive.Attributes.TANGENT]; tangentAccessor.BufferView = gltfObject.bufferViews[tangentAccessor.bufferView]; tangentAccessor.BufferView.Buffer = gltfObject.buffers[tangentAccessor.BufferView.buffer]; } if (meshPrimitive.Attributes.WEIGHTS_0 >= 0) { weight0Accessor = gltfObject.accessors[meshPrimitive.Attributes.WEIGHTS_0]; weight0Accessor.BufferView = gltfObject.bufferViews[weight0Accessor.bufferView]; weight0Accessor.BufferView.Buffer = gltfObject.buffers[weight0Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.JOINTS_0 >= 0) { joint0Accessor = gltfObject.accessors[meshPrimitive.Attributes.JOINTS_0]; joint0Accessor.BufferView = gltfObject.bufferViews[joint0Accessor.bufferView]; joint0Accessor.BufferView.Buffer = gltfObject.buffers[joint0Accessor.BufferView.buffer]; } if (Application.isPlaying) { await Update; } var mesh = new Mesh { indexFormat = vertexCount > 65535 ? IndexFormat.UInt32 : IndexFormat.UInt16, }; if (positionAccessor != null) { mesh.vertices = await positionAccessor.GetVector3Array(); } if (normalsAccessor != null) { mesh.normals = await normalsAccessor.GetVector3Array(); } if (textCoord0Accessor != null) { mesh.uv = await textCoord0Accessor.GetVector2Array(); } if (textCoord1Accessor != null) { mesh.uv2 = await textCoord1Accessor.GetVector2Array(); } if (textCoord2Accessor != null) { mesh.uv3 = await textCoord2Accessor.GetVector2Array(); } if (textCoord3Accessor != null) { mesh.uv4 = await textCoord3Accessor.GetVector2Array(); } if (colorAccessor != null) { mesh.colors = await colorAccessor.GetColorArray(); } if (indicesAccessor != null) { mesh.triangles = await indicesAccessor.GetIntArray(); } if (tangentAccessor != null) { mesh.tangents = await tangentAccessor.GetVector4Array(); } if (weight0Accessor != null && joint0Accessor != null) { mesh.boneWeights = CreateBoneWeightArray(await joint0Accessor.GetVector4Array(false), await weight0Accessor.GetVector4Array(false), vertexCount); } mesh.RecalculateBounds(); meshPrimitive.SubMesh = mesh; return(mesh); }
private static async Task <Mesh> ConstructMeshPrimitiveAsync(GltfObject gltfObject, GltfMeshPrimitive meshPrimitive) { if (gltfObject.UseBackgroundThread) { await BackgroundThread; } GltfAccessor positionAccessor = null; GltfAccessor normalsAccessor = null; GltfAccessor textCoord0Accessor = null; GltfAccessor textCoord1Accessor = null; GltfAccessor textCoord2Accessor = null; GltfAccessor textCoord3Accessor = null; GltfAccessor colorAccessor = null; GltfAccessor indicesAccessor = null; GltfAccessor tangentAccessor = null; GltfAccessor weight0Accessor = null; GltfAccessor joint0Accessor = null; int vertexCount = 0; positionAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.POSITION); if (positionAccessor != null) { vertexCount = positionAccessor.count; } normalsAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.NORMAL); textCoord0Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_0); textCoord1Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_1); textCoord2Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_2); textCoord3Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TEXCOORD_3); colorAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.COLOR_0); indicesAccessor = gltfObject.GetAccessor(meshPrimitive.indices); tangentAccessor = gltfObject.GetAccessor(meshPrimitive.Attributes.TANGENT); weight0Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.WEIGHTS_0); joint0Accessor = gltfObject.GetAccessor(meshPrimitive.Attributes.JOINTS_0); if (gltfObject.UseBackgroundThread) { await Update; } var mesh = new Mesh { indexFormat = vertexCount > UInt16.MaxValue ? IndexFormat.UInt32 : IndexFormat.UInt16, }; if (positionAccessor != null) { mesh.vertices = positionAccessor.GetVector3Array(); } if (normalsAccessor != null) { mesh.normals = normalsAccessor.GetVector3Array(); } if (textCoord0Accessor != null) { mesh.uv = textCoord0Accessor.GetVector2Array(); } if (textCoord1Accessor != null) { mesh.uv2 = textCoord1Accessor.GetVector2Array(); } if (textCoord2Accessor != null) { mesh.uv3 = textCoord2Accessor.GetVector2Array(); } if (textCoord3Accessor != null) { mesh.uv4 = textCoord3Accessor.GetVector2Array(); } if (colorAccessor != null) { mesh.colors = colorAccessor.GetColorArray(); } if (indicesAccessor != null) { mesh.triangles = indicesAccessor.GetIntArray(); } if (tangentAccessor != null) { mesh.tangents = tangentAccessor.GetVector4Array(); } if (weight0Accessor != null && joint0Accessor != null) { mesh.boneWeights = CreateBoneWeightArray(joint0Accessor.GetVector4Array(false), weight0Accessor.GetVector4Array(false), vertexCount); } mesh.RecalculateBounds(); meshPrimitive.SubMesh = mesh; return(mesh); }
private static Mesh ConstructMeshPrimitive(GltfObject gltfObject, GltfMeshPrimitive meshPrimitive) { GltfAccessor positionAccessor = null; GltfAccessor normalsAccessor = null; GltfAccessor textCoord0Accessor = null; GltfAccessor textCoord1Accessor = null; GltfAccessor textCoord2Accessor = null; GltfAccessor textCoord3Accessor = null; GltfAccessor colorAccessor = null; GltfAccessor indicesAccessor = null; GltfAccessor tangentAccessor = null; GltfAccessor weight0Accessor = null; GltfAccessor joint0Accessor = null; int vertexCount = 0; if (meshPrimitive.Attributes.POSITION >= 0) { positionAccessor = gltfObject.accessors[meshPrimitive.Attributes.POSITION]; positionAccessor.BufferView = gltfObject.bufferViews[positionAccessor.bufferView]; positionAccessor.BufferView.Buffer = gltfObject.buffers[positionAccessor.BufferView.buffer]; vertexCount = positionAccessor.count; } if (meshPrimitive.Attributes.NORMAL >= 0) { normalsAccessor = gltfObject.accessors[meshPrimitive.Attributes.NORMAL]; normalsAccessor.BufferView = gltfObject.bufferViews[normalsAccessor.bufferView]; normalsAccessor.BufferView.Buffer = gltfObject.buffers[normalsAccessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_0 >= 0) { textCoord0Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_0]; textCoord0Accessor.BufferView = gltfObject.bufferViews[textCoord0Accessor.bufferView]; textCoord0Accessor.BufferView.Buffer = gltfObject.buffers[textCoord0Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_1 >= 0) { textCoord1Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_1]; textCoord1Accessor.BufferView = gltfObject.bufferViews[textCoord1Accessor.bufferView]; textCoord1Accessor.BufferView.Buffer = gltfObject.buffers[textCoord1Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_2 >= 0) { textCoord2Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_2]; textCoord2Accessor.BufferView = gltfObject.bufferViews[textCoord2Accessor.bufferView]; textCoord2Accessor.BufferView.Buffer = gltfObject.buffers[textCoord2Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TEXCOORD_3 >= 0) { textCoord3Accessor = gltfObject.accessors[meshPrimitive.Attributes.TEXCOORD_3]; textCoord3Accessor.BufferView = gltfObject.bufferViews[textCoord3Accessor.bufferView]; textCoord3Accessor.BufferView.Buffer = gltfObject.buffers[textCoord3Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.COLOR_0 >= 0) { colorAccessor = gltfObject.accessors[meshPrimitive.Attributes.COLOR_0]; colorAccessor.BufferView = gltfObject.bufferViews[colorAccessor.bufferView]; colorAccessor.BufferView.Buffer = gltfObject.buffers[colorAccessor.BufferView.buffer]; } if (meshPrimitive.indices >= 0) { indicesAccessor = gltfObject.accessors[meshPrimitive.indices]; indicesAccessor.BufferView = gltfObject.bufferViews[indicesAccessor.bufferView]; indicesAccessor.BufferView.Buffer = gltfObject.buffers[indicesAccessor.BufferView.buffer]; } if (meshPrimitive.Attributes.TANGENT >= 0) { tangentAccessor = gltfObject.accessors[meshPrimitive.Attributes.TANGENT]; tangentAccessor.BufferView = gltfObject.bufferViews[tangentAccessor.bufferView]; tangentAccessor.BufferView.Buffer = gltfObject.buffers[tangentAccessor.BufferView.buffer]; } if (meshPrimitive.Attributes.WEIGHTS_0 >= 0) { weight0Accessor = gltfObject.accessors[meshPrimitive.Attributes.WEIGHTS_0]; weight0Accessor.BufferView = gltfObject.bufferViews[weight0Accessor.bufferView]; weight0Accessor.BufferView.Buffer = gltfObject.buffers[weight0Accessor.BufferView.buffer]; } if (meshPrimitive.Attributes.JOINTS_0 >= 0) { joint0Accessor = gltfObject.accessors[meshPrimitive.Attributes.JOINTS_0]; joint0Accessor.BufferView = gltfObject.bufferViews[joint0Accessor.bufferView]; joint0Accessor.BufferView.Buffer = gltfObject.buffers[joint0Accessor.BufferView.buffer]; } var mesh = new Mesh { indexFormat = vertexCount > 65535 ? IndexFormat.UInt32 : IndexFormat.UInt16, vertices = positionAccessor?.GetVector3Array(), normals = normalsAccessor?.GetVector3Array(), uv = textCoord0Accessor?.GetVector2Array(), uv2 = textCoord1Accessor?.GetVector2Array(), uv3 = textCoord2Accessor?.GetVector2Array(), uv4 = textCoord3Accessor?.GetVector2Array(), colors = colorAccessor?.GetColorArray(), triangles = indicesAccessor?.GetIntArray(), tangents = tangentAccessor?.GetVector4Array() }; if (weight0Accessor != null && joint0Accessor != null) { mesh.boneWeights = CreateBoneWeightArray(joint0Accessor.GetVector4Array(false), weight0Accessor.GetVector4Array(false), vertexCount); } mesh.RecalculateBounds(); return(mesh); }