protected AccessorId ExportAccessor(Matrix4x4[] arr, BufferViewId bufferViewId = null) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.MAT4; var byteOffset = _bufferWriter.BaseStream.Position; foreach (var vec in arr) { _bufferWriter.Write(vec.m00); _bufferWriter.Write(vec.m10); _bufferWriter.Write(vec.m20); _bufferWriter.Write(vec.m30); _bufferWriter.Write(vec.m01); _bufferWriter.Write(vec.m11); _bufferWriter.Write(vec.m21); _bufferWriter.Write(vec.m31); _bufferWriter.Write(vec.m02); _bufferWriter.Write(vec.m12); _bufferWriter.Write(vec.m22); _bufferWriter.Write(vec.m32); _bufferWriter.Write(vec.m03); _bufferWriter.Write(vec.m13); _bufferWriter.Write(vec.m23); _bufferWriter.Write(vec.m33); } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
public static AccessorId WriteAccessor(this GLTFRoot root, BufferId bufferId, Matrix4x4[] arr, BufferViewId bufferViewId = null, BinaryWriter writer = null) { var count = arr.Length; if (count == 0) { MyLog.LogError("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.MAT4; var byteOffset = writer.BaseStream.Position; foreach (var vec in arr) { writer.Write(vec.m00); writer.Write(vec.m10); writer.Write(vec.m20); writer.Write(vec.m30); writer.Write(vec.m01); writer.Write(vec.m11); writer.Write(vec.m21); writer.Write(vec.m31); writer.Write(vec.m02); writer.Write(vec.m12); writer.Write(vec.m22); writer.Write(vec.m32); writer.Write(vec.m03); writer.Write(vec.m13); writer.Write(vec.m23); writer.Write(vec.m33); } var byteLength = writer.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = root.WriteBufferView(bufferId, (int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = root.Accessors.Count, Root = root }; root.Accessors.Add(accessor); return(id); }
// a mesh *might* decode to multiple prims if there are submeshes private MeshPrimitive[] ExportPrimitive(UnityEngine.Mesh meshObj, UnityEngine.Material[] materials, Skin skin = null) { MyLog.Log("Mesh属性:"); var skinnedMeshRender = this._target.GetComponent <SkinnedMeshRenderer>(); var root = skinnedMeshRender ? this._target.transform : null; var materialsObj = new List <UnityEngine.Material>(materials); var prims = new MeshPrimitive[meshObj.subMeshCount]; var byteOffset = _bufferWriter.BaseStream.Position; var bufferViewId = this._root.WriteBufferView(this._bufferId, 0, (int)(_bufferWriter.BaseStream.Position - byteOffset)); AccessorId aPosition = null, aNormal = null, aTangent = null, aColor0 = null, aTexcoord0 = null, aTexcoord1 = null, aBlendIndex = null, aBlendWeight = null; aPosition = this._root.WriteAccessor(this._bufferId, SchemaExtensions.ConvertVector3CoordinateSpaceAndCopy(meshObj.vertices, SchemaExtensions.CoordinateSpaceConversionScale), bufferViewId, false, null, this._bufferWriter); MyLog.Log("-------vertices:" + meshObj.vertices.Length); if (meshObj.normals.Length != 0 && (ExportSetting.instance.mesh.normal)) { MyLog.Log("-------normals:" + meshObj.normals.Length); aNormal = this._root.WriteAccessor(this._bufferId, SchemaExtensions.ConvertVector3CoordinateSpaceAndCopy(meshObj.normals, SchemaExtensions.CoordinateSpaceConversionScale), bufferViewId, true, null, this._bufferWriter); } if (meshObj.tangents.Length != 0 && (ExportSetting.instance.mesh.tangent)) { aTangent = this._root.WriteAccessor(this._bufferId, SchemaExtensions.ConvertVector4CoordinateSpaceAndCopy(meshObj.tangents, SchemaExtensions.TangentSpaceConversionScale), bufferViewId, true, this._bufferWriter); } if (meshObj.colors.Length != 0 && (ExportSetting.instance.mesh.color)) { MyLog.Log("-------colors:" + meshObj.colors.Length); aColor0 = this._root.WriteAccessor(this._bufferId, meshObj.colors, bufferViewId, this._bufferWriter); } if (meshObj.uv.Length != 0) { MyLog.Log("-------uv:" + meshObj.uv.Length); aTexcoord0 = this._root.WriteAccessor(this._bufferId, SchemaExtensions.FlipTexCoordArrayVAndCopy(meshObj.uv), bufferViewId, this._bufferWriter); } var meshRender = this._target.GetComponent <MeshRenderer>(); if (meshRender != null && meshRender.lightmapIndex >= 0) { MyLog.Log("-------uv2:" + meshObj.uv2.Length); aTexcoord1 = this._root.WriteAccessor(this._bufferId, SchemaExtensions.FlipTexCoordArrayVAndCopy(meshObj.uv2.Length > 0 ? meshObj.uv2 : meshObj.uv), bufferViewId, this._bufferWriter); // aTexcoord1 = ExportAccessor(ConvertLightMapUVAndCopy(meshObj.uv2.Length > 0 ? meshObj.uv2 : meshObj.uv, meshRender.lightmapScaleOffset), bufferViewId); } else { if (meshObj.uv2.Length != 0 && (ExportSetting.instance.mesh.uv2)) { MyLog.Log("-------uv2:" + meshObj.uv2.Length); aTexcoord1 = this._root.WriteAccessor(this._bufferId, SchemaExtensions.FlipTexCoordArrayVAndCopy(meshObj.uv2), bufferViewId, this._bufferWriter); } } if (meshObj.boneWeights.Length != 0 && (ExportSetting.instance.mesh.bone)) { MyLog.Log("-------bones:" + meshObj.boneWeights.Length); aBlendIndex = this._root.WriteAccessor(this._bufferId, SchemaExtensions.ConvertBlendIndexAndCopy(meshObj.boneWeights), null, false, this._bufferWriter); aBlendWeight = this._root.WriteAccessor(this._bufferId, SchemaExtensions.ConvertBlendWeightAndCopy(meshObj.boneWeights), null, false, this._bufferWriter); if (skin != null) { /*var index = 0; * var renderer = _target.GetComponent<SkinnedMeshRenderer>(); * var bindposes = new Matrix4x4[renderer.bones.Length]; * * foreach (var bone in renderer.bones) * { * for (var i = 0; i < 16; ++i) * { * bindposes[index][i] = bone.worldToLocalMatrix[i]; * } * index++; * } * skin.InverseBindMatrices = ExportAccessor(bindposes);*/ skin.InverseBindMatrices = this._root.WriteAccessor(this._bufferId, meshObj.bindposes, null, this._bufferWriter); } } this._root.BufferViews[bufferViewId.Id].ByteLength = (int)(this._bufferWriter.BaseStream.Position - byteOffset); MaterialId lastMaterialId = null; for (var submesh = 0; submesh < meshObj.subMeshCount; submesh++) { var primitive = new MeshPrimitive(); var triangles = meshObj.GetTriangles(submesh); primitive.Indices = this._root.WriteAccessor(this._bufferId, SchemaExtensions.FlipFacesAndCopy(triangles), true, this._bufferWriter); primitive.Attributes = new Dictionary <string, AccessorId>(); primitive.Attributes.Add(SemanticProperties.POSITION, aPosition); MyLog.Log("-------triangles:" + triangles.Length + " submesh:" + submesh); if (aNormal != null) { primitive.Attributes.Add(SemanticProperties.NORMAL, aNormal); } if (aTangent != null) { primitive.Attributes.Add(SemanticProperties.TANGENT, aTangent); } if (aColor0 != null) { primitive.Attributes.Add(SemanticProperties.Color(0), aColor0); } if (aTexcoord0 != null) { primitive.Attributes.Add(SemanticProperties.TexCoord(0), aTexcoord0); } if (aTexcoord1 != null) { primitive.Attributes.Add(SemanticProperties.TexCoord(1), aTexcoord1); } if (aBlendIndex != null && aBlendWeight != null) { primitive.Attributes.Add(SemanticProperties.Joint(0), aBlendIndex); primitive.Attributes.Add(SemanticProperties.Weight(0), aBlendWeight); } if (submesh < materialsObj.Count) { primitive.Material = new MaterialId { Id = materialsObj.IndexOf(materialsObj[submesh]), Root = _root }; lastMaterialId = primitive.Material; } else { primitive.Material = lastMaterialId; } prims[submesh] = primitive; } return(prims); }
private AccessorId ExportAccessor(Vector3[] arr) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC3; float minX = arr[0].x; float minY = arr[0].y; float minZ = arr[0].z; float maxX = arr[0].x; float maxY = arr[0].y; float maxZ = arr[0].z; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.x < minX) { minX = cur.x; } if (cur.y < minY) { minY = cur.y; } if (cur.z < minZ) { minZ = cur.z; } if (cur.x > maxX) { maxX = cur.x; } if (cur.y > maxY) { maxY = cur.y; } if (cur.z > maxZ) { maxZ = cur.z; } } accessor.Min = new List <double> { minX, minY, minZ }; accessor.Max = new List <double> { maxX, maxY, maxZ }; var byteOffset = _bufferWriter.BaseStream.Position; foreach (var vec in arr) { _bufferWriter.Write(vec.x); _bufferWriter.Write(vec.y); _bufferWriter.Write(vec.z); } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
private AccessorId ExportAccessor(int[] arr, bool isIndices = false) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.SCALAR; int min = arr[0]; int max = arr[0]; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur < min) { min = cur; } if (cur > max) { max = cur; } } var byteOffset = _bufferWriter.BaseStream.Position; if (max <= byte.MaxValue && min >= byte.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedByte; foreach (var v in arr) { _bufferWriter.Write((byte)v); } } else if (max <= sbyte.MaxValue && min >= sbyte.MinValue && !isIndices) { accessor.ComponentType = GLTFComponentType.Byte; foreach (var v in arr) { _bufferWriter.Write((sbyte)v); } } else if (max <= short.MaxValue && min >= short.MinValue && !isIndices) { accessor.ComponentType = GLTFComponentType.Short; foreach (var v in arr) { _bufferWriter.Write((short)v); } } else if (max <= ushort.MaxValue && min >= ushort.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedShort; foreach (var v in arr) { _bufferWriter.Write((ushort)v); } } else if (min >= uint.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedInt; foreach (var v in arr) { _bufferWriter.Write((uint)v); } } else { accessor.ComponentType = GLTFComponentType.Float; foreach (var v in arr) { _bufferWriter.Write((float)v); } } accessor.Min = new List <double> { min }; accessor.Max = new List <double> { max }; var byteLength = _bufferWriter.BaseStream.Position - byteOffset; accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
// a mesh *might* decode to multiple prims if there are submeshes private MeshPrimitive[] ExportPrimitive(GameObject gameObject) { var filter = gameObject.GetComponent <MeshFilter>(); var meshObj = filter.sharedMesh; var renderer = gameObject.GetComponent <MeshRenderer>(); var materialsObj = renderer.sharedMaterials; var prims = new MeshPrimitive[meshObj.subMeshCount]; // don't export any more accessors if this mesh is already exported MeshPrimitive[] primVariations; if (_meshToPrims.TryGetValue(meshObj, out primVariations) && meshObj.subMeshCount == primVariations.Length) { for (var i = 0; i < primVariations.Length; i++) { prims[i] = new MeshPrimitive(primVariations[i], _root) { Material = ExportMaterial(materialsObj[i]) }; } return(prims); } AccessorId aPosition = null, aNormal = null, aTangent = null, aTexcoord0 = null, aTexcoord1 = null, aColor0 = null; aPosition = ExportAccessor(SchemaExtensions.ConvertVector3CoordinateSpaceAndCopy(meshObj.vertices, SchemaExtensions.CoordinateSpaceConversionScale)); if (meshObj.normals.Length != 0) { aNormal = ExportAccessor(SchemaExtensions.ConvertVector3CoordinateSpaceAndCopy(meshObj.normals, SchemaExtensions.CoordinateSpaceConversionScale)); } if (meshObj.tangents.Length != 0) { aTangent = ExportAccessor(SchemaExtensions.ConvertVector4CoordinateSpaceAndCopy(meshObj.tangents, SchemaExtensions.TangentSpaceConversionScale)); } if (meshObj.uv.Length != 0) { aTexcoord0 = ExportAccessor(SchemaExtensions.FlipTexCoordArrayVAndCopy(meshObj.uv)); } if (meshObj.uv2.Length != 0) { aTexcoord1 = ExportAccessor(SchemaExtensions.FlipTexCoordArrayVAndCopy(meshObj.uv2)); } if (meshObj.colors.Length != 0) { aColor0 = ExportAccessor(meshObj.colors); } MaterialId lastMaterialId = null; for (var submesh = 0; submesh < meshObj.subMeshCount; submesh++) { var primitive = new MeshPrimitive(); var triangles = meshObj.GetTriangles(submesh); primitive.Indices = ExportAccessor(SchemaExtensions.FlipFacesAndCopy(triangles), true); primitive.Attributes = new Dictionary <string, AccessorId>(); primitive.Attributes.Add(SemanticProperties.POSITION, aPosition); if (aNormal != null) { primitive.Attributes.Add(SemanticProperties.NORMAL, aNormal); } if (aTangent != null) { primitive.Attributes.Add(SemanticProperties.TANGENT, aTangent); } if (aTexcoord0 != null) { primitive.Attributes.Add(SemanticProperties.TexCoord(0), aTexcoord0); } if (aTexcoord1 != null) { primitive.Attributes.Add(SemanticProperties.TexCoord(1), aTexcoord1); } if (aColor0 != null) { primitive.Attributes.Add(SemanticProperties.Color(0), aColor0); } if (submesh < materialsObj.Length) { primitive.Material = ExportMaterial(materialsObj[submesh]); lastMaterialId = primitive.Material; } else { primitive.Material = lastMaterialId; } prims[submesh] = primitive; } _meshToPrims[meshObj] = prims; return(prims); }
private AccessorId ExportAccessor(UnityEngine.Color[] arr) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC4; float minR = arr[0].r; float minG = arr[0].g; float minB = arr[0].b; float minA = arr[0].a; float maxR = arr[0].r; float maxG = arr[0].g; float maxB = arr[0].b; float maxA = arr[0].a; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.r < minR) { minR = cur.r; } if (cur.g < minG) { minG = cur.g; } if (cur.b < minB) { minB = cur.b; } if (cur.a < minA) { minA = cur.a; } if (cur.r > maxR) { maxR = cur.r; } if (cur.g > maxG) { maxG = cur.g; } if (cur.b > maxB) { maxB = cur.b; } if (cur.a > maxA) { maxA = cur.a; } } accessor.Min = new List <double> { minR, minG, minB, minA }; accessor.Max = new List <double> { maxR, maxG, maxB, maxA }; var byteOffset = _bufferWriter.BaseStream.Position; foreach (var color in arr) { _bufferWriter.Write(color.r); _bufferWriter.Write(color.g); _bufferWriter.Write(color.b); _bufferWriter.Write(color.a); } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
private List<string> BakeAnimationClip(GLTF.Schema.Animation anim, Transform tr, AnimationClip clip) { var needGenerate = !_animClip2Accessors.ContainsKey(clip); Dictionary<string, Dictionary<GLTFAnimationChannelPath, AnimationCurve[]>> curves = null; Dictionary<string, bool> rotationIsEuler = null; if (needGenerate) { curves = new Dictionary<string, Dictionary<GLTFAnimationChannelPath, AnimationCurve[]>>(); rotationIsEuler = new Dictionary<string, bool>(); } List<string> targets = new List<string>(); foreach (var binding in AnimationUtility.GetCurveBindings(clip)) { var path = binding.path; var curve = AnimationUtility.GetEditorCurve(clip, binding); if (!curves.ContainsKey(path)) { targets.Add(path); if (needGenerate) { curves.Add(path, new Dictionary<GLTFAnimationChannelPath, AnimationCurve[]>()); rotationIsEuler.Add(path, false); } } if (!needGenerate) { continue; } var current = curves[path]; if (binding.propertyName.Contains("m_LocalPosition")) { if (!current.ContainsKey(GLTFAnimationChannelPath.translation)) { current.Add(GLTFAnimationChannelPath.translation, new AnimationCurve[3]); } if (binding.propertyName.Contains(".x")) current[GLTFAnimationChannelPath.translation][0] = curve; else if (binding.propertyName.Contains(".y")) current[GLTFAnimationChannelPath.translation][1] = curve; else if (binding.propertyName.Contains(".z")) current[GLTFAnimationChannelPath.translation][2] = curve; } else if (binding.propertyName.Contains("m_LocalScale")) { if (!current.ContainsKey(GLTFAnimationChannelPath.scale)) { current.Add(GLTFAnimationChannelPath.scale, new AnimationCurve[3]); } if (binding.propertyName.Contains(".x")) current[GLTFAnimationChannelPath.scale][0] = curve; else if (binding.propertyName.Contains(".y")) current[GLTFAnimationChannelPath.scale][1] = curve; else if (binding.propertyName.Contains(".z")) current[GLTFAnimationChannelPath.scale][2] = curve; } else if (binding.propertyName.ToLower().Contains("localrotation")) { if (!current.ContainsKey(GLTFAnimationChannelPath.rotation)) { current.Add(GLTFAnimationChannelPath.rotation, new AnimationCurve[4]); } if (binding.propertyName.Contains(".x")) current[GLTFAnimationChannelPath.rotation][0] = curve; else if (binding.propertyName.Contains(".y")) current[GLTFAnimationChannelPath.rotation][1] = curve; else if (binding.propertyName.Contains(".z")) current[GLTFAnimationChannelPath.rotation][2] = curve; else if (binding.propertyName.Contains(".w")) current[GLTFAnimationChannelPath.rotation][3] = curve; } // Takes into account 'localEuler', 'localEulerAnglesBaked' and 'localEulerAnglesRaw' else if (binding.propertyName.ToLower().Contains("localeuler")) { if (!current.ContainsKey(GLTFAnimationChannelPath.rotation)) { current.Add(GLTFAnimationChannelPath.rotation, new AnimationCurve[3]); rotationIsEuler[path] = true; } if (binding.propertyName.Contains(".x")) current[GLTFAnimationChannelPath.rotation][0] = curve; else if (binding.propertyName.Contains(".y")) current[GLTFAnimationChannelPath.rotation][1] = curve; else if (binding.propertyName.Contains(".z")) current[GLTFAnimationChannelPath.rotation][2] = curve; } //todo: weights } if (!needGenerate) { return targets; } var bufferView = CreateStreamBufferView("animation-" + anim.Name); int nbSamples = (int)(clip.length * 30); float deltaTime = clip.length / nbSamples; var accessors = new List<Dictionary<GLTFAnimationChannelPath, AccessorId>>(); _animClip2Accessors.Add(clip, accessors); foreach (var path in curves.Keys) { var accessor = new Dictionary<GLTFAnimationChannelPath, AccessorId>(); accessors.Add(accessor); float[] times = new float[nbSamples]; Vector3[] translations = null; Vector3[] scales = null; Vector4[] rotations = null; foreach (var curve in curves[path]) { if (curve.Key == GLTFAnimationChannelPath.translation) { translations = new Vector3[nbSamples]; } else if (curve.Key == GLTFAnimationChannelPath.scale) { scales = new Vector3[nbSamples]; } else if (curve.Key == GLTFAnimationChannelPath.rotation) { rotations = new Vector4[nbSamples]; } } for (int i = 0; i < nbSamples; i += 1) { var currentTime = i * deltaTime; times[i] = currentTime; if (translations != null) { var curve = curves[path][GLTFAnimationChannelPath.translation]; translations[i] = new Vector3(curve[0].Evaluate(currentTime), curve[1].Evaluate(currentTime), curve[2].Evaluate(currentTime)); } if (scales != null) { var curve = curves[path][GLTFAnimationChannelPath.scale]; scales[i] = new Vector3(curve[0].Evaluate(currentTime), curve[1].Evaluate(currentTime), curve[2].Evaluate(currentTime)); } if (rotations != null) { var curve = curves[path][GLTFAnimationChannelPath.rotation]; if (rotationIsEuler[path]) { var q = Quaternion.Euler(curve[0].Evaluate(currentTime), curve[1].Evaluate(currentTime), curve[2].Evaluate(currentTime)); rotations[i] = new Vector4(q.x, q.y, q.z, q.w); } else { rotations[i] = new Vector4(curve[0].Evaluate(currentTime), curve[1].Evaluate(currentTime), curve[2].Evaluate(currentTime), curve[3].Evaluate(currentTime)); } } } if (!_animClip2TimeAccessor.ContainsKey(clip)) { var timeView = ExporterUtils.PackToBuffer(bufferView.streamBuffer, times, GLTFComponentType.Float); _animClip2TimeAccessor.Add(clip, AccessorToId(timeView, bufferView)); timeView.Name += "-times"; } AccessorId id = null; if (translations != null) { id = AccessorToId(ExporterUtils.PackToBuffer(bufferView.streamBuffer, translations, GLTFComponentType.Float, (Vector3[] data, int i) => { return Utils.ConvertVector3LeftToRightHandedness(ref data[i]); }), bufferView); accessor.Add(GLTFAnimationChannelPath.translation, id); id.Value.Name += "-" + path + "-" + "translation"; } if (scales != null) { id = AccessorToId(ExporterUtils.PackToBuffer(bufferView.streamBuffer, scales, GLTFComponentType.Float), bufferView); accessor.Add(GLTFAnimationChannelPath.scale, id); id.Value.Name += "-" + path + "-" + "scales"; } if (rotations != null) { id = AccessorToId(ExporterUtils.PackToBuffer(bufferView.streamBuffer, rotations, GLTFComponentType.Float, (Vector4[] data, int i) => { return Utils.ConvertVector4LeftToRightHandedness(ref data[i]); }), bufferView); accessor.Add(GLTFAnimationChannelPath.rotation, id); id.Value.Name += "-" + path + "-" + "rotations"; } } return targets; }
public static AccessorId WriteAccessor(this GLTFRoot root, BufferId bufferId, UnityEngine.Color[] arr, BufferViewId bufferViewId = null, BinaryWriter writer = null) { var count = arr.Length; if (count == 0) { MyLog.LogError("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC4; float minR = arr[0].r; float minG = arr[0].g; float minB = arr[0].b; float minA = arr[0].a; float maxR = arr[0].r; float maxG = arr[0].g; float maxB = arr[0].b; float maxA = arr[0].a; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.r < minR) { minR = cur.r; } if (cur.g < minG) { minG = cur.g; } if (cur.b < minB) { minB = cur.b; } if (cur.a < minA) { minA = cur.a; } if (cur.r > maxR) { maxR = cur.r; } if (cur.g > maxG) { maxG = cur.g; } if (cur.b > maxB) { maxB = cur.b; } if (cur.a > maxA) { maxA = cur.a; } } accessor.Normalized = true; accessor.Min = new List <double> { minR, minG, minB, minA }; accessor.Max = new List <double> { maxR, maxG, maxB, maxA }; var byteOffset = writer.BaseStream.Position; foreach (var color in arr) { writer.Write(color.r); writer.Write(color.g); writer.Write(color.b); writer.Write(color.a); } var byteLength = writer.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = root.WriteBufferView(bufferId, (int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = root.Accessors.Count, Root = root }; root.Accessors.Add(accessor); return(id); }
public static AccessorId WriteAccessor(this GLTFRoot root, BufferId bufferId, Vector4[] arr, BufferViewId bufferViewId = null, bool normalized = false, BinaryWriter writer = null) { var count = arr.Length; if (count == 0) { MyLog.LogError("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC4; float minX = arr[0].x; float minY = arr[0].y; float minZ = arr[0].z; float minW = arr[0].w; float maxX = arr[0].x; float maxY = arr[0].y; float maxZ = arr[0].z; float maxW = arr[0].w; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.x < minX) { minX = cur.x; } if (cur.y < minY) { minY = cur.y; } if (cur.z < minZ) { minZ = cur.z; } if (cur.w < minW) { minW = cur.w; } if (cur.x > maxX) { maxX = cur.x; } if (cur.y > maxY) { maxY = cur.y; } if (cur.z > maxZ) { maxZ = cur.z; } if (cur.w > maxW) { maxW = cur.w; } } accessor.Normalized = normalized; accessor.Min = new List <double> { minX, minY, minZ, minW }; accessor.Max = new List <double> { maxX, maxY, maxZ, maxW }; var byteOffset = writer.BaseStream.Position; foreach (var vec in arr) { writer.Write(vec.x); writer.Write(vec.y); writer.Write(vec.z); writer.Write(vec.w); } var byteLength = writer.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = root.WriteBufferView(bufferId, (int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = root.Accessors.Count, Root = root }; root.Accessors.Add(accessor); return(id); }
public static AccessorId WriteAccessor(this GLTFRoot root, BufferId bufferId, Vector3[] arr, BufferViewId bufferViewId = null, bool normalized = false, Transform rootNode = null, BinaryWriter writer = null) { var count = arr.Length; if (count == 0) { MyLog.LogError("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC3; /*float minX = arr[0].x; * float minY = arr[0].y; * float minZ = arr[0].z; * float maxX = arr[0].x; * float maxY = arr[0].y; * float maxZ = arr[0].z; * * for (var i = 1; i < count; i++) * { * var cur = arr[i]; * * if (cur.x < minX) * { * minX = cur.x; * } * if (cur.y < minY) * { * minY = cur.y; * } * if (cur.z < minZ) * { * minZ = cur.z; * } * if (cur.x > maxX) * { * maxX = cur.x; * } * if (cur.y > maxY) * { * maxY = cur.y; * } * if (cur.z > maxZ) * { * maxZ = cur.z; * } * }*/ accessor.Normalized = normalized; //accessor.Min = new List<double> { minX, minY, minZ }; //accessor.Max = new List<double> { maxX, maxY, maxZ }; var byteOffset = writer.BaseStream.Position; Matrix4x4 mA = rootNode != null ? rootNode.localToWorldMatrix : new Matrix4x4(); Matrix4x4 mB = rootNode != null ? rootNode.parent.worldToLocalMatrix : new Matrix4x4(); foreach (var vec in arr) { writer.Write(vec.x); writer.Write(vec.y); writer.Write(vec.z); } var byteLength = writer.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = root.WriteBufferView(bufferId, (int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = root.Accessors.Count, Root = root }; root.Accessors.Add(accessor); return(id); }
public static AccessorId WriteAccessor(this GLTFRoot root, BufferId bufferId, int[] arr, bool isIndices = false, BinaryWriter writer = null) { var count = arr.Length; if (count == 0) { MyLog.LogError("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.SCALAR; int min = arr[0]; int max = arr[0]; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur < min) { min = cur; } if (cur > max) { max = cur; } } var byteOffset = writer.BaseStream.Position; if (max <= byte.MaxValue && min >= byte.MinValue && !isIndices) { accessor.ComponentType = GLTFComponentType.UnsignedByte; foreach (var v in arr) { writer.Write((byte)v); } } else if (max <= sbyte.MaxValue && min >= sbyte.MinValue && !isIndices) { accessor.ComponentType = GLTFComponentType.Byte; foreach (var v in arr) { writer.Write((sbyte)v); } } else if (max <= short.MaxValue && min >= short.MinValue && !isIndices) { accessor.ComponentType = GLTFComponentType.Short; foreach (var v in arr) { writer.Write((short)v); } } else if (max <= ushort.MaxValue && min >= ushort.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedShort; foreach (var v in arr) { writer.Write((ushort)v); } } else if (min >= uint.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedInt; foreach (var v in arr) { writer.Write((uint)v); } } else { accessor.ComponentType = GLTFComponentType.Float; foreach (var v in arr) { writer.Write((float)v); } } accessor.Min = new List <double> { min }; accessor.Max = new List <double> { max }; var byteLength = writer.BaseStream.Position - byteOffset; accessor.BufferView = root.WriteBufferView(bufferId, (int)byteOffset, (int)byteLength); var id = new AccessorId { Id = root.Accessors.Count, Root = root }; root.Accessors.Add(accessor); return(id); }
protected AccessorId ExportAccessor(Vector4[] arr, BufferViewId bufferViewId = null, bool normalized = false) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC4; float minX = arr[0].x; float minY = arr[0].y; float minZ = arr[0].z; float minW = arr[0].w; float maxX = arr[0].x; float maxY = arr[0].y; float maxZ = arr[0].z; float maxW = arr[0].w; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.x < minX) { minX = cur.x; } if (cur.y < minY) { minY = cur.y; } if (cur.z < minZ) { minZ = cur.z; } if (cur.w < minW) { minW = cur.w; } if (cur.x > maxX) { maxX = cur.x; } if (cur.y > maxY) { maxY = cur.y; } if (cur.z > maxZ) { maxZ = cur.z; } if (cur.w > maxW) { maxW = cur.w; } } accessor.Normalized = normalized; accessor.Min = new List <double> { minX, minY, minZ, minW }; accessor.Max = new List <double> { maxX, maxY, maxZ, maxW }; var byteOffset = _bufferWriter.BaseStream.Position; foreach (var vec in arr) { _bufferWriter.Write(vec.x); _bufferWriter.Write(vec.y); _bufferWriter.Write(vec.z); _bufferWriter.Write(vec.w); } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
protected AccessorId ExportAccessor(Vector3[] arr, BufferViewId bufferViewId = null, bool normalized = false, Transform root = null) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC3; /*float minX = arr[0].x; * float minY = arr[0].y; * float minZ = arr[0].z; * float maxX = arr[0].x; * float maxY = arr[0].y; * float maxZ = arr[0].z; * * for (var i = 1; i < count; i++) * { * var cur = arr[i]; * * if (cur.x < minX) * { * minX = cur.x; * } * if (cur.y < minY) * { * minY = cur.y; * } * if (cur.z < minZ) * { * minZ = cur.z; * } * if (cur.x > maxX) * { * maxX = cur.x; * } * if (cur.y > maxY) * { * maxY = cur.y; * } * if (cur.z > maxZ) * { * maxZ = cur.z; * } * }*/ accessor.Normalized = normalized; //accessor.Min = new List<double> { minX, minY, minZ }; //accessor.Max = new List<double> { maxX, maxY, maxZ }; var byteOffset = _bufferWriter.BaseStream.Position; Matrix4x4 mA = root != null ? root.localToWorldMatrix : new Matrix4x4(); Matrix4x4 mB = root != null ? root.parent.worldToLocalMatrix : new Matrix4x4(); foreach (var vec in arr) { if (root != null) { if (normalized) { var v = mB.MultiplyVector(mA.MultiplyVector(vec)); _bufferWriter.Write(v.x); _bufferWriter.Write(v.y); _bufferWriter.Write(v.z); } else { var v = mB.MultiplyPoint(mA.MultiplyPoint(vec)); _bufferWriter.Write(v.x); _bufferWriter.Write(v.y); _bufferWriter.Write(v.z); } } else { _bufferWriter.Write(vec.x); _bufferWriter.Write(vec.y); _bufferWriter.Write(vec.z); } } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; if (bufferViewId != null) { accessor.BufferView = bufferViewId; accessor.ByteOffset = (int)byteOffset; } else { accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); } var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }