示例#1
0
        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);
        }
示例#3
0
        // 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);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }