Populate() public method

public Populate ( Vector2 v2s ) : void
v2s Vector2
return void
Esempio n. 1
0
    public void Populate(TiltBrush.GeometryPool pool)
    {
        positionAccessor.Populate(pool.m_Vertices, flipY: false, calculateMinMax: true);
        if (normalAccessor != null)
        {
            normalAccessor.Populate(pool.m_Normals, flipY: false, calculateMinMax: false);
        }
        if (colorAccessor != null)
        {
            colorAccessor.Populate(pool.m_Colors);
        }
        if (tangentAccessor != null)
        {
            tangentAccessor.Populate(pool.m_Tangents, flipY: false, calculateMinMax: false);
        }

        // UVs may be 1, 2, 3 or 4 element tuples, which the following helper method resolves.
        // In the case of zero UVs, the texCoord accessor will be null and will not be populated.
        Debug.Assert(TiltBrush.GeometryPool.kNumTexcoords == 3);
        Debug.Assert(texCoord3Accessor == null);
        var layout = pool.Layout;

        PopulateUv(0, pool, texCoord0Accessor, layout.texcoord0.semantic);
        PopulateUv(1, pool, texCoord1Accessor, layout.texcoord1.semantic);
        PopulateUv(2, pool, texCoord2Accessor, layout.texcoord2.semantic);
        PopulateUv(3, pool, texCoord3Accessor, Semantic.Unspecified);
    }
Esempio n. 2
0
    public void Populate(Transform m, ref GlTF_Accessor invBindMatricesAccessor, int invBindAccessorIndex)
    {
        SkinnedMeshRenderer skinMesh = m.GetComponent <SkinnedMeshRenderer>();

        if (!skinMesh)
        {
            return;
        }

        // Populate bind poses. From https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html:
        // The bind pose is bone's inverse transformation matrix
        // In this case we also make this matrix relative to the root
        // So that we can move the root game object around freely

        joints = new List <Transform>();
        //Collect all bones from skin object. Order should be kept here since bones are referenced in the mesh
        foreach (Transform t in skinMesh.bones)
        {
            joints.Add(t);
        }

        Matrix4x4[] invBindMatrices = new Matrix4x4[joints.Count];
        for (int i = 0; i < skinMesh.bones.Length; ++i)
        {
            // Generates inverseWorldMatrix in right-handed coordinate system
            Matrix4x4 invBind = skinMesh.sharedMesh.bindposes[i];
            convertMatrixLeftToRightHandedness(ref invBind);
            invBindMatrices[i] = invBind;
        }

        invBindMatricesAccessor.Populate(invBindMatrices, m);
        invBindMatricesAccessorIndex = invBindAccessorIndex;
    }
Esempio n. 3
0
    public void Populate(Mesh m)
    {
//		attributes.Populate (m);
        if (m.GetTopology(index) == MeshTopology.Triangles)
        {
            indices.Populate(m.GetTriangles(index), true);
        }
    }
    void PopulateTime(string animName, Keyframe[] keyFrames)
    {
        timeAccessor            = new GlTF_Accessor("accessor_anim_time_" + animName, GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.FLOAT);
        timeAccessor.bufferView = GlTF_Writer.floatBufferView;
        GlTF_Writer.accessors.Add(timeAccessor);
        var times = new float[keyFrames.Length];

        for (int i = 0; i < keyFrames.Length; i++)
        {
            times[i] = keyFrames[i].time;
        }
        timeAccessor.Populate(times);
    }
 public void Populate(Mesh m)
 {
     positionAccessor.Populate(m.vertices);
     if (colorAccessor != null)
     {
         colorAccessor.Populate(m.colors);
     }
     if (normalAccessor != null)
     {
         normalAccessor.Populate(m.normals);
     }
     if (texCoord0Accessor != null)
     {
         texCoord0Accessor.Populate(m.uv, false);
     }
     if (texCoord1Accessor != null)
     {
         texCoord1Accessor.Populate(m.uv2, false);
     }
     if (texCoord2Accessor != null)
     {
         texCoord2Accessor.Populate(m.uv3, false);
     }
     if (texCoord3Accessor != null)
     {
         texCoord3Accessor.Populate(m.uv4, false);
     }
     if (lightmapTexCoordAccessor != null)
     {
         lightmapTexCoordAccessor.PopulateWithOffsetScale(m.uv2, false);
     }
     if (jointAccessor != null)
     {
         Vector4[] bones = boneWeightToBoneVec4(m.boneWeights);
         jointAccessor.Populate(bones);
     }
     if (weightAccessor != null)
     {
         Vector4[] weights = boneWeightToWeightVec4(m.boneWeights);
         weightAccessor.Populate(weights);
     }
     if (tangentAccessor != null)
     {
         tangentAccessor.Populate(m.tangents, false);
     }
 }
Esempio n. 6
0
 public void Populate(Mesh m)
 {
     positionAccessor.Populate(m.vertices);
     if (normalAccessor != null)
     {
         normalAccessor.Populate(m.normals);
     }
     if (texCoord0Accessor != null)
     {
         texCoord0Accessor.Populate(m.uv, true);
     }
     if (texCoord1Accessor != null)
     {
         texCoord1Accessor.Populate(m.uv2, true);
     }
     if (texCoord2Accessor != null)
     {
         texCoord2Accessor.Populate(m.uv3, true);
     }
     if (texCoord3Accessor != null)
     {
         texCoord3Accessor.Populate(m.uv4, true);
     }
     if (boneIndexAccessor != null)
     {
         List <Vector4> indices = new List <Vector4>();
         foreach (var bw in m.boneWeights)
         {
             indices.Add(new Vector4(bw.boneIndex0, bw.boneIndex1, bw.boneIndex2, bw.boneIndex3));
         }
         boneIndexAccessor.Populate(indices.ToArray());
     }
     if (boneWeightAccessor != null)
     {
         List <Vector4> weights = new List <Vector4>();
         foreach (var bw in m.boneWeights)
         {
             weights.Add(new Vector4(bw.weight0, bw.weight1, bw.weight2, bw.weight3));
         }
         boneWeightAccessor.Populate(weights.ToArray());
     }
 }
Esempio n. 7
0
    public void Populate(Transform m, ref GlTF_Accessor invBindMatricesAccessor, int invBindAccessorIndex)
    {
        SkinnedMeshRenderer skinMesh = m.GetComponent <SkinnedMeshRenderer>();

        if (!skinMesh)
        {
            return;
        }

        // Populate bind poses. From https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html:
        // The bind pose is bone's inverse transformation matrix
        // In this case we also make this matrix relative to the root
        // So that we can move the root game object around freely
        joints = new List <Transform>();
        //Collect all bones from skin object. Order should be kept here since bones are referenced in the mesh
        foreach (Transform t in skinMesh.bones)
        {
            joints.Add(t);
        }

        // glTF expects a single hierarchy of bones, but Unity skips all the nodes that are not used.
        // Find the common ancestor of all used bones in order to get a valid bone herarchy
        rootBone = rebuildBoneHierarchy(skinMesh, ref joints);

        Matrix4x4[] invBindMatrices = new Matrix4x4[joints.Count];

        for (int i = 0; i < invBindMatrices.Length; ++i)
        {
            // Generates inverseWorldMatrix in right-handed coordinate system
            // Manually converts world translation and rotation from left to right handed coordinates systems
            Vector3    pos = joints[i].position;
            Quaternion rot = joints[i].rotation;
            convertQuatLeftToRightHandedness(ref rot);
            convertVector3LeftToRightHandedness(ref pos);

            invBindMatrices[i] = Matrix4x4.TRS(pos, rot, joints[i].lossyScale).inverse *sceneRootMatrix.inverse;
        }

        invBindMatricesAccessor.Populate(invBindMatrices, m);
        invBindMatricesAccessorIndex = invBindAccessorIndex;
    }
Esempio n. 8
0
    public void Populate(Transform m, ref GlTF_Accessor invBindMatricesAccessor, int invBindAccessorIndex)
    {
        SkinnedMeshRenderer skinMesh = m.GetComponent <SkinnedMeshRenderer>();

        if (!skinMesh)
        {
            return;
        }

        // Populate bind poses. From https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html:
        // The bind pose is bone's inverse transformation matrix
        // In this case we also make this matrix relative to the root
        // So that we can move the root game object around freely
        Mesh mesh = skinMesh.sharedMesh;

        Matrix4x4[] invBindMatrices = new Matrix4x4[skinMesh.sharedMesh.bindposes.Length];

        for (int i = 0; i < invBindMatrices.Length; ++i)
        {
            // Generates inverseWorldMatrix in right-handed coordinate system
            // Manually converts world translation and rotation from left to right handed coordinates systems
            Vector3    pos = skinMesh.bones[i].position;
            Quaternion rot = skinMesh.bones[i].rotation;
            convertQuatLeftToRightHandedness(ref rot);
            convertVector3LeftToRightHandedness(ref pos);

            invBindMatrices[i] = Matrix4x4.TRS(pos, rot, skinMesh.bones[i].lossyScale).inverse *sceneRootMatrix.inverse;
        }

        invBindMatricesAccessor.Populate(invBindMatrices, m);
        invBindMatricesAccessorIndex = invBindAccessorIndex;

        // Fill jointNames
        jointNames = new string[skinMesh.bones.Length];
        for (int i = 0; i < skinMesh.bones.Length; ++i)
        {
            jointNames[i] = GlTF_Node.GetNameFromObject(skinMesh.bones[i]);
        }
    }
    public void Populate(SkinnedMeshRenderer smr, List <Transform> skeletons)
    {
        name = GetNameFromObject(smr.transform);
        if (smr.rootBone != null)
        {
            boneNames = new List <string>();
            List <Matrix4x4> boneMats = new List <Matrix4x4>();

            var parent = smr.rootBone.parent;
            if (parent != null)
            {
                var mat = Matrix4x4.TRS(parent.localPosition, parent.localRotation, parent.localScale);
                bindShape = new GlTF_Matrix(mat);
            }
            else
            {
                bindShape = new GlTF_Matrix(Matrix4x4.identity);
            }
            bindShape.name = "bindShapeMatrix";

            skeletons.Add(smr.rootBone);
            for (var i = 0; i < smr.bones.Length; ++i)
            {
                var found = IsBoneInHierarchy(smr.rootBone, smr.bones[i]);
                if (!found)
                {
                    // set as its own skeleton to prevent error if it doesn't get included in rootBone hierarchy
                    skeletons.Add(smr.bones[i]);
                }
                boneNames.Add(GlTF_Node.GetNameFromObject(smr.bones[i]));
                boneMats.Add(smr.sharedMesh.bindposes[i]);
            }

            ibmAccessor            = new GlTF_Accessor("accessor_ibm_" + name, GlTF_Accessor.Type.MAT4, GlTF_Accessor.ComponentType.FLOAT);
            ibmAccessor.bufferView = GlTF_Writer.mat4BufferView;
            ibmAccessor.Populate(boneMats.ToArray());
            GlTF_Writer.accessors.Add(ibmAccessor);
        }
    }
    public void Populate(AnimationClipCurveData curveData)
    {
        string propName = curveData.propertyName;

        if (times == null)         // allocate one array of times, assumes all channels have same number of keys
        {
            timeAccessor            = new GlTF_Accessor(name + "TimeAccessor", GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.FLOAT);
            timeAccessor.bufferView = GlTF_Writer.floatBufferView;
            GlTF_Writer.accessors.Add(timeAccessor);
            times = new float[curveData.curve.keys.Length];
            for (int i = 0; i < curveData.curve.keys.Length; i++)
            {
                times[i] = curveData.curve.keys[i].time;
            }
            timeAccessor.Populate(times);
        }

        if (propName.Contains("m_LocalPosition"))
        {
            if (positions == null)
            {
                translationAccessor            = new GlTF_Accessor(name + "TranslationAccessor", GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                translationAccessor.bufferView = GlTF_Writer.vec3BufferView;
                GlTF_Writer.accessors.Add(translationAccessor);
                positions = new Vector3[curveData.curve.keys.Length];
            }

            if (propName.Contains(".x"))
            {
                px = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    positions[i].x = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".y"))
            {
                py = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    positions[i].y = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".z"))
            {
                pz = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    positions[i].z = curveData.curve.keys[i].value;
                }
            }
            if (px && py && pz)
            {
                translationAccessor.Populate(positions);
            }
        }

        if (propName.Contains("m_LocalScale"))
        {
            if (scales == null)
            {
                scaleAccessor            = new GlTF_Accessor(name + "ScaleAccessor", GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                scaleAccessor.bufferView = GlTF_Writer.vec3BufferView;
                GlTF_Writer.accessors.Add(scaleAccessor);
                scales = new Vector3[curveData.curve.keys.Length];
            }

            if (propName.Contains(".x"))
            {
                sx = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    scales[i].x = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".y"))
            {
                sy = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    scales[i].y = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".z"))
            {
                sz = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    scales[i].z = curveData.curve.keys[i].value;
                }
            }
            if (sx && sy && sz)
            {
                scaleAccessor.Populate(scales);
            }
        }

        if (propName.Contains("m_LocalRotation"))
        {
            if (rotations == null)
            {
                rotationAccessor            = new GlTF_Accessor(name + "RotationAccessor", GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT);
                rotationAccessor.bufferView = GlTF_Writer.vec4BufferView;
                GlTF_Writer.accessors.Add(rotationAccessor);
                rotations = new Vector4[curveData.curve.keys.Length];
            }

            if (propName.Contains(".x"))
            {
                rx = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    rotations[i].x = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".y"))
            {
                ry = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    rotations[i].y = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".z"))
            {
                rz = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    rotations[i].z = curveData.curve.keys[i].value;
                }
            }
            else if (propName.Contains(".w"))
            {
                rw = true;
                for (int i = 0; i < curveData.curve.keys.Length; i++)
                {
                    rotations[i].w = curveData.curve.keys[i].value;
                }
            }
            if (rx && ry && rz && rw)
            {
                rotationAccessor.Populate(scales);
            }
        }
    }
Esempio n. 11
0
    public void Populate(AnimationClip clip, Transform tr, bool bake = true)
    {
        // 1. browse clip, collect all curves and create a TargetCurveSet for each target
        Dictionary <string, TargetCurveSet> targetCurvesBinding = new Dictionary <string, TargetCurveSet>();

        collectClipCurves(clip, ref targetCurvesBinding);

        // Baking needs all properties, fill missing curves with transform data in 2 keyframes (start, endTime)
        // where endTime is clip duration
        generateMissingCurves(clip.length, ref tr, ref targetCurvesBinding);

        if (bake)
        {
            // Bake animation for all animated nodes
            foreach (string target in targetCurvesBinding.Keys)
            {
                Transform targetTr = target.Length > 0 ? tr.Find(target) : tr;
                if (targetTr == null)
                {
                    continue;
                }

                Transform targetObject = targetTr;
                string    targetId     = GlTF_Node.GetNameFromObject(targetObject);

                // Initialize accessors for current animation
                GlTF_Accessor timeAccessor = new GlTF_Accessor(targetId + "_TimeAccessor_" + clip.name, GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.FLOAT);
                timeAccessor.bufferView = GlTF_Writer.floatBufferView;
                int timeAccessorIndex = GlTF_Writer.accessors.Count;
                GlTF_Writer.accessors.Add(timeAccessor);

                // Translation
                GlTF_Channel chTranslation     = new GlTF_Channel("translation", animSamplers.Count);
                GlTF_Target  targetTranslation = new GlTF_Target();
                targetTranslation.id   = targetId;
                targetTranslation.path = "translation";
                chTranslation.target   = targetTranslation;
                channels.Add(chTranslation);

                GlTF_AnimSampler sTranslation        = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count);
                GlTF_Accessor    translationAccessor = new GlTF_Accessor(targetId + "_TranslationAccessor_" + clip.name, GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                translationAccessor.bufferView = GlTF_Writer.vec3BufferView;
                GlTF_Writer.accessors.Add(translationAccessor);
                animSamplers.Add(sTranslation);

                // Rotation
                GlTF_Channel chRotation     = new GlTF_Channel("rotation", animSamplers.Count);
                GlTF_Target  targetRotation = new GlTF_Target();
                targetRotation.id   = GlTF_Node.GetNameFromObject(targetObject);
                targetRotation.path = "rotation";
                chRotation.target   = targetRotation;
                channels.Add(chRotation);

                GlTF_AnimSampler sRotation        = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count);
                GlTF_Accessor    rotationAccessor = new GlTF_Accessor(targetId + "_RotationAccessor_" + clip.name, GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT);
                rotationAccessor.bufferView = GlTF_Writer.vec4BufferView;
                GlTF_Writer.accessors.Add(rotationAccessor);
                animSamplers.Add(sRotation);

                // Scale
                GlTF_Channel chScale     = new GlTF_Channel("scale", animSamplers.Count);
                GlTF_Target  targetScale = new GlTF_Target();
                targetScale.id   = GlTF_Node.GetNameFromObject(targetObject);
                targetScale.path = "scale";
                chScale.target   = targetScale;
                channels.Add(chScale);

                GlTF_AnimSampler sScale        = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count);
                GlTF_Accessor    scaleAccessor = new GlTF_Accessor(targetId + "_ScaleAccessor_" + clip.name, GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                scaleAccessor.bufferView = GlTF_Writer.vec3BufferView;
                GlTF_Writer.accessors.Add(scaleAccessor);
                animSamplers.Add(sScale);

                // Bake and populate animation data
                float[]   times     = null;
                Vector3[] positions = null;
                Vector3[] scales    = null;
                Vector4[] rotations = null;
                bakeCurveSet(targetCurvesBinding[target], clip.length, bakingFramerate, ref times, ref positions, ref rotations, ref scales);

                // Populate accessors
                timeAccessor.Populate(times);
                translationAccessor.Populate(positions);
                rotationAccessor.Populate(rotations, false);
                scaleAccessor.Populate(scales, true);
            }
        }
        else
        {
            Debug.LogError("Only baked animation is supported for now. Skipping animation");
        }
    }
Esempio n. 12
0
    public void Populate(Mesh m)
    {
//		attributes.Populate (m);
        indices.Populate(m.GetTriangles(index), true);
    }
Esempio n. 13
0
    private void PopulateUv(
        int channel, TiltBrush.GeometryPool pool, GlTF_Accessor accessor,
        Semantic semantic)
    {
        bool packVertId = m_layout.PackVertexIdIntoTexcoord1W && channel == 1;

        if (packVertId)
        {
            // Guaranteed by GlTF_VertexLayout
            Debug.Assert(m_layout.m_tbLayout.GetTexcoordInfo(channel).size == 3);
            Debug.Assert(m_layout.GetTexcoordSize(channel) == 4);
        }
        if (accessor == null)
        {
            return;
        }
        if (channel < 0 || channel > 3)
        {
            throw new ArgumentException("Invalid channel");
        }
        TiltBrush.GeometryPool.TexcoordData texcoordData = pool.GetTexcoordData(channel);

        if (semantic == Semantic.XyIsUvZIsDistance && accessor.type != GlTF_Accessor.Type.VEC3)
        {
            throw new ArgumentException("XyIsUvZIsDistance semantic can only be applied to VEC3");
        }

        bool flipY;

        if (semantic == Semantic.Unspecified && channel == 0 &&
            accessor.type == GlTF_Accessor.Type.VEC2)
        {
            Debug.LogWarning("Assuming Semantic.XyIsUv");
            semantic = Semantic.XyIsUv;
        }
        switch (semantic)
        {
        case Semantic.Position:
        case Semantic.Vector:
        case Semantic.Timestamp:
            flipY = false;
            break;

        case Semantic.XyIsUvZIsDistance:
        case Semantic.XyIsUv:
            flipY = true;
            break;

        default:
            throw new ArgumentException("semantic");
        }

        switch (accessor.type)
        {
        case GlTF_Accessor.Type.SCALAR:
            throw new NotImplementedException();

        case GlTF_Accessor.Type.VEC2:
            accessor.Populate(texcoordData.v2, flipY: flipY, calculateMinMax: false);
            break;

        case GlTF_Accessor.Type.VEC3:
            accessor.Populate(texcoordData.v3, flipY: flipY, calculateMinMax: false);
            break;

        case GlTF_Accessor.Type.VEC4:
            if (packVertId)
            {
                // In the vertexId case, we actually have a vec3, which needs to be augmented to a vec4.
                // TODO: this should happen at some higher level.
                int i  = 0;
                var v4 = texcoordData.v3.ConvertAll <Vector4>((v => new Vector4(v.x, v.y, v.z, i++)));
                accessor.Populate(v4, flipY: flipY, calculateMinMax: false);
            }
            else
            {
                accessor.Populate(texcoordData.v4, flipY: flipY, calculateMinMax: false);
            }
            break;

        default:
            throw new ArgumentException("Unexpected accessor.type");
        }
    }
        public void PopulateAccessor(AnimationClipCurveData cd, Keyframe[] refKeyFrames)
        {
            string propName = cd.propertyName;

            if (type == Type.Translation || type == Type.Scale)
            {
                if (v3 == null)
                {
                    v3 = new Vector3[refKeyFrames.Length];
                }

                if (propName.Contains(".x"))
                {
                    wx = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v3[i].x = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }
                else if (propName.Contains(".y"))
                {
                    wy = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v3[i].y = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }
                else if (propName.Contains(".z"))
                {
                    wz = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v3[i].z = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }

                if (wx && wy && wz)
                {
                    accessor.Populate(v3);
                }
            }
            else
            {
                if (v4 == null)
                {
                    v4 = new Vector4[refKeyFrames.Length];
                }

                if (propName.Contains(".x"))
                {
                    wx = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v4[i].x = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }
                else if (propName.Contains(".y"))
                {
                    wy = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v4[i].y = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }
                else if (propName.Contains(".z"))
                {
                    wz = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v4[i].z = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }
                else if (propName.Contains(".w"))
                {
                    ww = true;
                    for (var i = 0; i < refKeyFrames.Length; ++i)
                    {
                        v4[i].w = cd.curve.Evaluate(refKeyFrames[i].time);
                    }
                }

                if (wx && wy && wz && ww)
                {
                    accessor.Populate(v4);
                }
            }
        }
	public void Populate (AnimationClipCurveData curveData)
	{
		string propName = curveData.propertyName;
		if (times == null) // allocate one array of times, assumes all channels have same number of keys
		{
			timeAccessor = new GlTF_Accessor(name+"TimeAccessor", "SCALAR", "FLOAT");
			timeAccessor.bufferView = GlTF_Writer.floatBufferView;
			GlTF_Writer.accessors.Add (timeAccessor);
			times = new float[curveData.curve.keys.Length];
			for (int i = 0; i < curveData.curve.keys.Length; i++)
				times[i] = curveData.curve.keys[i].time;
			timeAccessor.Populate (times);
		}

		if (propName.Contains("m_LocalPosition"))
		{
			if (positions == null)
			{
				translationAccessor = new GlTF_Accessor(name+"TranslationAccessor", "VEC3", "FLOAT");
				translationAccessor.bufferView = GlTF_Writer.vec3BufferView;
				GlTF_Writer.accessors.Add (translationAccessor);
				positions = new Vector3[curveData.curve.keys.Length];
			}

			if (propName.Contains (".x"))
		    {
		    	px = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					positions[i].x = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".y"))
			{
				py = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					positions[i].y = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".z"))
			{
				pz = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					positions[i].z = curveData.curve.keys[i].value;
			}
			if (px && py && pz)
				translationAccessor.Populate (positions);
		}
		
		if (propName.Contains("m_LocalScale"))
		{
			if (scales == null)
			{
				scaleAccessor = new GlTF_Accessor(name+"ScaleAccessor", "VEC3", "FLOAT");
				scaleAccessor.bufferView = GlTF_Writer.vec3BufferView;
				GlTF_Writer.accessors.Add (scaleAccessor);
				scales = new Vector3[curveData.curve.keys.Length];
			}
			
			if (propName.Contains (".x"))
			{
				sx = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					scales[i].x = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".y"))
			{
				sy = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					scales[i].y = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".z"))
			{
				sz = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					scales[i].z = curveData.curve.keys[i].value;
			}
			if (sx && sy && sz)
				scaleAccessor.Populate (scales);
		}

		if (propName.Contains("m_LocalRotation"))
		{
			if (rotations == null)
			{
				rotationAccessor = new GlTF_Accessor(name+"RotationAccessor", "VEC4", "FLOAT");
				rotationAccessor.bufferView = GlTF_Writer.vec4BufferView;
				GlTF_Writer.accessors.Add (rotationAccessor);
				rotations = new Vector4[curveData.curve.keys.Length];
			}
			
			if (propName.Contains (".x"))
			{
				rx = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					rotations[i].x = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".y"))
			{
				ry = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					rotations[i].y = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".z"))
			{
				rz = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					rotations[i].z = curveData.curve.keys[i].value;
			}
			else if (propName.Contains (".w"))
			{
				rw = true;
				for (int i = 0; i < curveData.curve.keys.Length; i++)
					rotations[i].w = curveData.curve.keys[i].value;
			}
			if (rx && ry && rz && rw)
				rotationAccessor.Populate (scales);
		}
	}