Inheritance: GlTF_Writer
コード例 #1
0
        public BoneAnimPath(Type type, string animName, string objectName)
        {
            this.type = type;
            var typeStr = TypeToString(type);

            target      = new GlTF_Target();
            target.id   = objectName;
            target.path = typeStr;
            var subName = typeStr + "_" + animName + "_" + objectName;

            sampler  = new GlTF_AnimSampler("sampler_" + subName, "param_" + subName);
            channel  = new GlTF_Channel(sampler, target);
            accessor = new GlTF_Accessor("accessor_anim_" + subName, TypeToAccType(type), GlTF_Accessor.ComponentType.FLOAT);
            switch (type)
            {
            case Type.Translation:
            case Type.Scale:
                accessor.bufferView = GlTF_Writer.vec3BufferView;
                break;

            case Type.Rotation:
                accessor.bufferView = GlTF_Writer.vec4BufferView;
                break;
            }
            GlTF_Writer.accessors.Add(accessor);
        }
コード例 #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;
    }
コード例 #3
0
    /// Returns an accessor that uses a differenttype.
    /// This is useful if you want to create (for example) a VEC2 view of a buffer that holds VEC4s.
    /// If the type is smaller, you get a new accessor that uses the same bufferview
    /// If the type is the same, you get the same accessor back.
    /// If the type is bigger, you get an exception
    public static GlTF_Accessor CloneWithDifferentType(
        GlTF_Globals G, GlTF_Accessor fromAccessor, Type newType)
    {
        if (newType == fromAccessor.type)
        {
            return(fromAccessor);
        }
        var ret = new GlTF_Accessor(G, fromAccessor, newType);

        G.accessors.Add(ret);
        return(ret);
    }
コード例 #4
0
    // Returns null if the layout says there's no data in the specified texcoord
    public AttributeInfo?GetTexcoordInfo(int texcoord)
    {
        var numComponents = GetTexcoordSize(texcoord);

        if (numComponents == 0)
        {
            return(null);
        }
        return(new AttributeInfo(
                   GlTF_Accessor.GetTypeForNumComponents(numComponents),
                   GlTF_Accessor.ComponentType.FLOAT));
    }
コード例 #5
0
    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);
    }
コード例 #6
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;
    }
コード例 #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
        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]);
        }
    }
コード例 #8
0
    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);
        }
    }
コード例 #9
0
    // Adds to gltfMesh the glTF dependencies (primitive, material, technique, program, shaders)
    // required by unityMesh, using matObjName for naming the various material-related glTF
    // components. This does not add any geometry from the mesh (that's done separately using
    // GlTF_Mesh.Populate()).
    //
    // This does not create the material either. It adds a reference to a material that
    // presumably will be created very soon (if it hasn't previously been created).
    private void AddMeshDependencies(
        ObjectName meshName, IExportableMaterial exportableMaterial, GlTF_Mesh gltfMesh,
        GlTF_VertexLayout gltfLayout)
    {
        GlTF_Primitive primitive = new GlTF_Primitive(
            new GlTF_Attributes(G, meshName, gltfLayout));

        GlTF_Accessor indexAccessor = G.CreateAccessor(
            GlTF_Accessor.GetNameFromObject(meshName, "indices_0"),
            GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.USHORT,
            isNonVertexAttributeAccessor: true);

        primitive.indices = indexAccessor;
        if (gltfMesh.primitives.Count > 0)
        {
            Debug.LogError("More than one primitive per mesh is unimplemented and unsupported");
        }
        gltfMesh.primitives.Add(primitive);

        // This needs to be a forward-reference (ie, by name) because G.materials[exportableMaterial]
        // may not have been created yet.
        primitive.materialName = GlTF_Material.GetNameFromObject(exportableMaterial);
    }
コード例 #10
0
    // Private to force people to use the better-named CloneWithDifferentType() method.
    private GlTF_Accessor(GlTF_Globals G, GlTF_Accessor fromAccessor, Type newType)
        : base(G)
    {
        m_clonedFrom = fromAccessor;
        if (newType >= fromAccessor.type)
        {
            throw new ArgumentException("newType must be smaller than fromAccessor.type");
        }
        this.name          = $"{fromAccessor.name}_{newType}";
        this.bufferView    = fromAccessor.bufferView;
        this.byteStride    = fromAccessor.byteStride;
        this.type          = newType;
        this.componentType = fromAccessor.componentType;
        // Leave these null; at serialization time, we "inherit" a value from m_clonedFrom
        // this.count      = fromAccessor.count;
        // this.byteOffset    = fromAccessor.byteOffset;
        // These aren't nullables because the purity isn't worth the pain, but at least poison them
        this.maxFloat = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN);
        this.minFloat = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN);
        this.minInt   = 0x0D00B015;
        this.maxInt   = 0x0D00B015;

        SanityCheckBufferViewStride();
    }
コード例 #11
0
    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);
            }
        }
    }
コード例 #12
0
    public IEnumerator Export(string path, Preset presetAsset, bool buildZip, bool exportPBRMaterials, bool exportAnimation = true, bool doConvertImages = false)
    {
        writer = new GlTF_Writer();
        writer.Init();
        done = false;
        bool debugRightHandedScale = false;

        GlTF_Writer.exportedFiles.Clear();
        if (debugRightHandedScale)
        {
            GlTF_Writer.convertRightHanded = false;
        }

        writer.extraString.Add("exporterVersion", GlTF_Writer.exporterVersion);

        // Create rootNode
        GlTF_Node correctionNode = new GlTF_Node();

        correctionNode.id   = "UnityGlTF_root";
        correctionNode.name = "UnityGlTF_root";
        GlTF_Writer.nodes.Add(correctionNode);
        GlTF_Writer.nodeNames.Add(correctionNode.name);
        GlTF_Writer.rootNodes.Add(correctionNode);

        //path = toGlTFname(path);
        savedPath = Path.GetDirectoryName(path);

        // Temp list to keep track of skeletons
        Dictionary <string, GlTF_Skin> parsedSkins = new Dictionary <string, GlTF_Skin>();

        parsedSkins.Clear();

        // first, collect objects in the scene, add to lists
        Transform[]      transforms = Selection.GetTransforms(SelectionMode.Deep);
        List <Transform> trs        = new List <Transform>(transforms);
        // Prefilter selected nodes and look for skinning in order to list "bones" nodes
        //FIXME: improve this
        List <Transform> bones = new List <Transform>();

        foreach (Transform tr in trs)
        {
            if (!tr.gameObject.activeSelf)
            {
                continue;
            }

            SkinnedMeshRenderer skin = tr.GetComponent <SkinnedMeshRenderer>();
            if (skin)
            {
                foreach (Transform bone in skin.bones)
                {
                    bones.Add(bone);
                }
            }
        }

        nbSelectedObjects = trs.Count;
        int nbDisabledObjects = 0;

        foreach (Transform tr in trs)
        {
            if (tr.gameObject.activeInHierarchy == false)
            {
                nbDisabledObjects++;
                continue;
            }

            // Initialize the node
            GlTF_Node node = new GlTF_Node();
            node.id   = GlTF_Node.GetNameFromObject(tr);
            node.name = GlTF_Writer.cleanNonAlphanumeric(tr.name);

            if (tr.GetComponent <Camera>() != null)
            {
                parseUnityCamera(tr);
            }

            if (tr.GetComponent <Light>() != null)
            {
                parseUnityLight(tr);
            }

            Mesh m = GetMesh(tr);
            if (m != null)
            {
                GlTF_Mesh mesh = new GlTF_Mesh();
                mesh.name = GlTF_Writer.cleanNonAlphanumeric(GlTF_Mesh.GetNameFromObject(m) + tr.name);

                GlTF_Accessor positionAccessor = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "position"), GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                positionAccessor.bufferView = GlTF_Writer.vec3BufferView;
                GlTF_Writer.accessors.Add(positionAccessor);

                GlTF_Accessor normalAccessor = null;
                if (m.normals.Length > 0)
                {
                    normalAccessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "normal"), GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                    normalAccessor.bufferView = GlTF_Writer.vec3BufferView;
                    GlTF_Writer.accessors.Add(normalAccessor);
                }

                GlTF_Accessor colorAccessor = null;
                if (m.colors.Length > 0)
                {
                    colorAccessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "color"), GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT);
                    colorAccessor.bufferView = GlTF_Writer.vec4BufferView;
                    GlTF_Writer.accessors.Add(colorAccessor);
                }

                GlTF_Accessor uv0Accessor = null;
                if (m.uv.Length > 0)
                {
                    uv0Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv0"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv0Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv0Accessor);
                }

                GlTF_Accessor uv1Accessor = null;
                if (m.uv2.Length > 0)
                {
                    // check if object is affected by a lightmap
                    uv1Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv1"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv1Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv1Accessor);
                }

                GlTF_Accessor uv2Accessor = null;
                if (m.uv3.Length > 0)
                {
                    uv2Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv2"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv2Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv2Accessor);
                }

                GlTF_Accessor uv3Accessor = null;
                if (m.uv4.Length > 0)
                {
                    uv3Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv3"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv3Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv3Accessor);
                }

                GlTF_Accessor jointAccessor = null;
                if (exportAnimation && m.boneWeights.Length > 0)
                {
                    jointAccessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "joints"), GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.USHORT);
                    jointAccessor.bufferView = GlTF_Writer.vec4UshortBufferView;
                    GlTF_Writer.accessors.Add(jointAccessor);
                }

                GlTF_Accessor weightAccessor = null;
                if (exportAnimation && m.boneWeights.Length > 0)
                {
                    weightAccessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "weights"), GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT);
                    weightAccessor.bufferView = GlTF_Writer.vec4BufferView;
                    GlTF_Writer.accessors.Add(weightAccessor);
                }

                GlTF_Accessor tangentAccessor = null;
                if (m.tangents.Length > 0)
                {
                    tangentAccessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "tangents"), GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT);
                    tangentAccessor.bufferView = GlTF_Writer.vec4BufferView;
                    GlTF_Writer.accessors.Add(tangentAccessor);
                }

                var smCount = m.subMeshCount;
                for (var i = 0; i < smCount; ++i)
                {
                    GlTF_Primitive primitive = new GlTF_Primitive();
                    primitive.name  = GlTF_Primitive.GetNameFromObject(m, i);
                    primitive.index = i;
                    GlTF_Attributes attributes = new GlTF_Attributes();
                    attributes.positionAccessor  = positionAccessor;
                    attributes.normalAccessor    = normalAccessor;
                    attributes.colorAccessor     = colorAccessor;
                    attributes.texCoord0Accessor = uv0Accessor;
                    attributes.texCoord1Accessor = uv1Accessor;
                    attributes.texCoord2Accessor = uv2Accessor;
                    attributes.texCoord3Accessor = uv3Accessor;
                    attributes.jointAccessor     = jointAccessor;
                    attributes.weightAccessor    = weightAccessor;
                    attributes.tangentAccessor   = tangentAccessor;
                    primitive.attributes         = attributes;
                    GlTF_Accessor indexAccessor = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "indices_" + i), GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.USHORT);
                    indexAccessor.bufferView = GlTF_Writer.ushortBufferView;
                    GlTF_Writer.accessors.Add(indexAccessor);
                    primitive.indices = indexAccessor;

                    var mr = GetRenderer(tr);
                    var sm = mr.sharedMaterials;
                    if (i < sm.Length)
                    {
                        var mat     = sm[i];
                        var matName = GlTF_Material.GetNameFromObject(mat);
                        if (GlTF_Writer.materialNames.Contains(matName))
                        {
                            primitive.materialIndex = GlTF_Writer.materialNames.IndexOf(matName);                             // THIS INDIRECTION CAN BE REMOVED!
                        }
                        else
                        {
                            GlTF_Material material = new GlTF_Material();
                            material.name           = GlTF_Writer.cleanNonAlphanumeric(mat.name);
                            primitive.materialIndex = GlTF_Writer.materials.Count;
                            GlTF_Writer.materialNames.Add(matName);
                            GlTF_Writer.materials.Add(material);

                            //technique
                            var s        = mat.shader;
                            var techName = GlTF_Technique.GetNameFromObject(s);
                            if (GlTF_Writer.techniqueNames.Contains(techName))
                            {
                                material.instanceTechniqueIndex = GlTF_Writer.techniqueNames.IndexOf(techName);                                // THIS INDIRECTION CAN BE REMOVED!
                            }
                            else
                            {
                                GlTF_Technique tech = new GlTF_Technique();
                                tech.name = techName;
                                GlTF_Technique.Parameter tParam = new GlTF_Technique.Parameter();
                                tParam.name     = "position";
                                tParam.type     = GlTF_Technique.Type.FLOAT_VEC3;
                                tParam.semantic = GlTF_Technique.Semantic.POSITION;
                                tech.parameters.Add(tParam);
                                GlTF_Technique.Attribute tAttr = new GlTF_Technique.Attribute();
                                tAttr.name  = "a_position";
                                tAttr.param = tParam.name;
                                tech.attributes.Add(tAttr);

                                if (normalAccessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "normal";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC3;
                                    tParam.semantic = GlTF_Technique.Semantic.NORMAL;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_normal";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv0Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord0";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_0;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord0";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv1Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord1";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_1;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord1";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv2Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord2";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_2;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord2";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv3Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord3";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_3;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord3";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                tech.AddDefaultUniforms();

                                // Populate technique with shader data
                                GlTF_Writer.techniqueNames.Add(techName);
                                GlTF_Writer.techniques.Add(tech);

                                // create program
                                GlTF_Program program = new GlTF_Program();
                                program.name = GlTF_Program.GetNameFromObject(s);
                                tech.program = program.name;
                                foreach (var attr in tech.attributes)
                                {
                                    program.attributes.Add(attr.name);
                                }
                                GlTF_Writer.programs.Add(program);
                            }

                            unityToPBRMaterial(mat, ref material);
                        }
                    }
                    mesh.primitives.Add(primitive);
                }

                // If gameobject having SkinnedMeshRenderer component has been transformed,
                // the mesh would need to be baked here.
                mesh.Populate(m);
                GlTF_Writer.meshes.Add(mesh);
                node.meshIndex = GlTF_Writer.meshes.IndexOf(mesh);
            }

            // Parse animations
            if (exportAnimation)
            {
                Animator a = tr.GetComponent <Animator>();
                if (a != null)
                {
                    AnimationClip[] clips = AnimationUtility.GetAnimationClips(tr.gameObject);
                    for (int i = 0; i < clips.Length; i++)
                    {
                        //FIXME It seems not good to generate one animation per animator.
                        GlTF_Animation anim = new GlTF_Animation(GlTF_Writer.cleanNonAlphanumeric(a.name));
                        anim.Populate(clips[i], tr, GlTF_Writer.bakeAnimation);
                        if (anim.channels.Count > 0)
                        {
                            GlTF_Writer.animations.Add(anim);
                        }
                    }
                }

                Animation animation = tr.GetComponent <Animation>();
                if (animation != null)
                {
                    AnimationClip clip = animation.clip;
                    //FIXME It seems not good to generate one animation per animator.
                    GlTF_Animation anim = new GlTF_Animation(GlTF_Writer.cleanNonAlphanumeric(animation.name));
                    anim.Populate(clip, tr, GlTF_Writer.bakeAnimation);
                    if (anim.channels.Count > 0)
                    {
                        GlTF_Writer.animations.Add(anim);
                    }
                }
            }

            // Parse transform
            if (tr.parent == null)
            {
                Matrix4x4 mat = Matrix4x4.identity;
                if (debugRightHandedScale)
                {
                    mat.m22 = -1;
                }
                mat         = mat * Matrix4x4.TRS(tr.localPosition, tr.localRotation, tr.localScale);
                node.matrix = new GlTF_Matrix(mat);
            }
            // Use good transform if parent object is not in selection
            else if (!trs.Contains(tr.parent))
            {
                node.hasParent = false;
                Matrix4x4 mat = Matrix4x4.identity;
                if (debugRightHandedScale)
                {
                    mat.m22 = -1;
                }
                mat         = mat * tr.localToWorldMatrix;
                node.matrix = new GlTF_Matrix(mat);
            }
            else
            {
                node.hasParent = true;
                if (tr.localPosition != Vector3.zero)
                {
                    node.translation = new GlTF_Translation(tr.localPosition);
                }
                if (tr.localScale != Vector3.one)
                {
                    node.scale = new GlTF_Scale(tr.localScale);
                }
                if (tr.localRotation != Quaternion.identity)
                {
                    node.rotation = new GlTF_Rotation(tr.localRotation);
                }
            }

            if (!node.hasParent)
            {
                correctionNode.childrenNames.Add(node.id);
            }

            if (tr.GetComponent <Camera>() != null)
            {
                node.cameraName = GlTF_Writer.cleanNonAlphanumeric(tr.name);
            }
            else if (tr.GetComponent <Light>() != null)
            {
                node.lightName = GlTF_Writer.cleanNonAlphanumeric(tr.name);
            }

            // Parse node's skin data
            GlTF_Accessor       invBindMatrixAccessor = null;
            SkinnedMeshRenderer skinMesh = tr.GetComponent <SkinnedMeshRenderer>();
            if (exportAnimation && skinMesh != null && skinMesh.enabled && checkSkinValidity(skinMesh, trs) && skinMesh.rootBone != null)
            {
                GlTF_Skin skin = new GlTF_Skin();

                skin.name = GlTF_Writer.cleanNonAlphanumeric(skinMesh.rootBone.name) + "_skeleton_" + GlTF_Writer.cleanNonAlphanumeric(node.name) + tr.GetInstanceID();

                // Create invBindMatrices accessor
                invBindMatrixAccessor            = new GlTF_Accessor(skin.name + "invBindMatrices", GlTF_Accessor.Type.MAT4, GlTF_Accessor.ComponentType.FLOAT);
                invBindMatrixAccessor.bufferView = GlTF_Writer.mat4BufferView;
                GlTF_Writer.accessors.Add(invBindMatrixAccessor);

                // Generate skin data
                skin.Populate(tr, ref invBindMatrixAccessor, GlTF_Writer.accessors.Count - 1);
                GlTF_Writer.skins.Add(skin);
                node.skinIndex = GlTF_Writer.skins.IndexOf(skin);
            }

            foreach (Transform t in tr.transform)
            {
                if (t.gameObject.activeInHierarchy)
                {
                    node.childrenNames.Add(GlTF_Node.GetNameFromObject(t));
                }
            }

            GlTF_Writer.nodeNames.Add(node.id);
            GlTF_Writer.nodes.Add(node);
        }

        if (GlTF_Writer.meshes.Count == 0)
        {
            Debug.Log("No visible objects have been exported. Aboring export");
            yield return(false);
        }

        writer.OpenFiles(path);
        writer.Write();
        writer.CloseFiles();

        if (nbDisabledObjects > 0)
        {
            Debug.Log(nbDisabledObjects + " disabled object ignored during export");
        }

        Debug.Log("Scene has been exported to " + path);
        if (buildZip)
        {
            ZipFile zip = new ZipFile();
            Debug.Log(GlTF_Writer.exportedFiles.Count + " files generated");
            string zipName = Path.GetFileNameWithoutExtension(path) + ".zip";
            foreach (string originFilePath in GlTF_Writer.exportedFiles.Keys)
            {
                zip.AddFile(originFilePath, GlTF_Writer.exportedFiles[originFilePath]);
            }

            zip.Save(savedPath + "/" + zipName);

            // Remove all files
            foreach (string pa in GlTF_Writer.exportedFiles.Keys)
            {
                if (System.IO.File.Exists(pa))
                {
                    System.IO.File.Delete(pa);
                }
            }

            Debug.Log("Files have been cleaned");
        }
        done = true;

        yield return(true);
    }
コード例 #13
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");
        }
    }
コード例 #14
0
    public GlTF_Attributes(
        GlTF_Globals G, ObjectName meshName, GlTF_VertexLayout layout)
    {
        // This prefix should be used with possibly-nonconforming gltf data:
        // - texcoords that are not 2-element or that don't contain texture coordinates
        // - made-up / mythical semantics like VERTEXID
        string nonconformingPrefix = (G.GltfCompatibilityMode) ? "_TB_UNITY_" : "";

        m_layout = layout;

        {
            AttributeInfo positionInfo = layout.PositionInfo;
            positionAccessor = G.CreateAccessor(
                GlTF_Accessor.GetNameFromObject(meshName, "position"),
                positionInfo.accessorType, positionInfo.accessorComponentType);
            m_accessors.Add("POSITION", positionAccessor);
        }

        { if (layout.NormalInfo is AttributeInfo normalInfo)
          {
              normalAccessor = G.CreateAccessor(
                  GlTF_Accessor.GetNameFromObject(meshName, "normal"),
                  normalInfo.accessorType, normalInfo.accessorComponentType);
              // Genius particles put things that don't look like normals into the normal attribute.
              bool   isNonconforming = (layout.m_tbLayout.normalSemantic == Semantic.Position);
              string prefix          = isNonconforming ? nonconformingPrefix : "";
              m_accessors.Add(prefix + "NORMAL", normalAccessor);
          }
        }

        { if (layout.ColorInfo is AttributeInfo cInfo)
          {
              colorAccessor = G.CreateAccessor(
                  GlTF_Accessor.GetNameFromObject(meshName, "color"),
                  cInfo.accessorType, cInfo.accessorComponentType,
                  normalized: true);
              m_accessors.Add(G.Gltf2 ? "COLOR_0" : "COLOR", colorAccessor);
          }
        }

        { if (layout.TangentInfo is AttributeInfo tangentInfo)
          {
              tangentAccessor = G.CreateAccessor(
                  GlTF_Accessor.GetNameFromObject(meshName, "tangent"),
                  tangentInfo.accessorType, tangentInfo.accessorComponentType);
              m_accessors.Add("TANGENT", tangentAccessor);
          }
        }

        if (layout.PackVertexIdIntoTexcoord1W)
        {
            // The vertexid hack modifies the gl layout to extend texcoord1 so the vertexid
            // can be stuffed into it
            Debug.Assert(layout.m_tbLayout.GetTexcoordInfo(1).size == 3);
            Debug.Assert(layout.GetTexcoordSize(1) == 4);
        }

        GlTF_Accessor MakeAccessorFor(int texcoord)
        {
            var txcInfo = layout.GetTexcoordInfo(texcoord);

            if (txcInfo == null)
            {
                return(null);
            }
            Semantic tbSemantic = layout.m_tbLayout.GetTexcoordInfo(texcoord).semantic;
            string   attrName   = $"{nonconformingPrefix}TEXCOORD_{texcoord}";

            // Timestamps are tunneled into us via a texcoord because there's not really a better way
            // due to GeometryPool limitations. But that's an internal implementation detail. I'd like
            // them to have a better attribute name in the gltf.
            if (tbSemantic == Semantic.Timestamp)
            {
                // For b/141876882; Poly doesn't like _TB_TIMESTAMP
                if (!G.Gltf2)
                {
                    return(null);
                }
                attrName = "_TB_TIMESTAMP";
            }
            var ret = G.CreateAccessor(
                GlTF_Accessor.GetNameFromObject(meshName, $"uv{texcoord}"),
                txcInfo.Value.accessorType, txcInfo.Value.accessorComponentType);

            m_accessors.Add(attrName, ret);
            return(ret);
        }

        texCoord0Accessor = MakeAccessorFor(0);
        texCoord1Accessor = MakeAccessorFor(1);
        texCoord2Accessor = MakeAccessorFor(2);
        texCoord3Accessor = MakeAccessorFor(3);

        if (G.GltfCompatibilityMode)
        {
            TiltBrush.GeometryPool.VertexLayout tbLayout = layout.m_tbLayout;
            switch (tbLayout.texcoord0.semantic)
            {
            case Semantic.Unspecified when tbLayout.texcoord0.size == 2:
            case Semantic.XyIsUv:
            case Semantic.XyIsUvZIsDistance: {
                GlTF_Accessor accessor = GlTF_Accessor.CloneWithDifferentType(
                    G, texCoord0Accessor, GlTF_Accessor.Type.VEC2);
                m_accessors.Add("TEXCOORD_0", accessor);
                break;
            }
            }
            // No need to check the other texcoords because TB only ever puts texture coordinates
            // in texcoord0
        }
    }
コード例 #15
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");
        }
    }
コード例 #16
0
	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);
		}
	}
コード例 #17
0
    public static BoundsDouble Export(string path, Transform[] trs, Transform root, out double minHeight, out double maxHeight)
    {
        minHeight = 0;
        maxHeight = 0;

        writer = new GlTF_Writer();
        writer.Init();

        if (presetAsset != null)
        {
            string psPath = AssetDatabase.GetAssetPath(presetAsset);
            if (psPath != null)
            {
                psPath = psPath.Remove(0, "Assets".Length);
                psPath = Application.dataPath + psPath;
                preset.Load(psPath);
            }
        }

        savedPath = Path.GetDirectoryName(path);
        savedFile = Path.GetFileNameWithoutExtension(path);

        EditorPrefs.SetString(KEY_PATH, savedPath);
        EditorPrefs.SetString(KEY_FILE, savedFile);

        Debug.Log("attempting to save to " + path);
        writer.OpenFiles(path);

        if (rtcScript != null && root != null)
        {
            var instance = Activator.CreateInstance(rtcScript.GetClass());
            var rtc      = instance as RTCCallback;
            if (rtc != null)
            {
                writer.RTCCenter = rtc.GetCenter(root);
            }
        }

        RotationCallback rotCallback = null;;

        if (rotScript != null)
        {
            var instance = Activator.CreateInstance(rotScript.GetClass());
            rotCallback = instance as RotationCallback;
        }

        if (unpackTexture)
        {
            // prepass, for texture unpacker
            TextureUnpacker.Reset();
            foreach (Transform tr in trs)
            {
                TextureUnpacker.CheckPackedTexture(tr, preset);
            }
            TextureUnpacker.Build();
        }

        BoundsDouble bb = new BoundsDouble();

        // first, collect objects in the scene, add to lists
        foreach (Transform tr in trs)
        {
            if (tr.GetComponent <Camera>() != null)
            {
                if (tr.GetComponent <Camera>().orthographic)
                {
                    GlTF_Orthographic cam;
                    cam       = new GlTF_Orthographic();
                    cam.type  = "orthographic";
                    cam.zfar  = tr.GetComponent <Camera>().farClipPlane;
                    cam.znear = tr.GetComponent <Camera>().nearClipPlane;
                    cam.name  = tr.name;
                    //cam.orthographic.xmag = tr.camera.
                    GlTF_Writer.cameras.Add(cam);
                }
                else
                {
                    GlTF_Perspective cam;
                    cam              = new GlTF_Perspective();
                    cam.type         = "perspective";
                    cam.zfar         = tr.GetComponent <Camera>().farClipPlane;
                    cam.znear        = tr.GetComponent <Camera>().nearClipPlane;
                    cam.aspect_ratio = tr.GetComponent <Camera>().aspect;
                    cam.yfov         = tr.GetComponent <Camera>().fieldOfView;
                    cam.name         = tr.name;
                    GlTF_Writer.cameras.Add(cam);
                }
            }

            if (tr.GetComponent <Light>() != null)
            {
                switch (tr.GetComponent <Light>().type)
                {
                case LightType.Point:
                    GlTF_PointLight pl = new GlTF_PointLight();
                    pl.color = new GlTF_ColorRGB(tr.GetComponent <Light>().color);
                    pl.name  = tr.name;
                    GlTF_Writer.lights.Add(pl);
                    break;

                case LightType.Spot:
                    GlTF_SpotLight sl = new GlTF_SpotLight();
                    sl.color = new GlTF_ColorRGB(tr.GetComponent <Light>().color);
                    sl.name  = tr.name;
                    GlTF_Writer.lights.Add(sl);
                    break;

                case LightType.Directional:
                    GlTF_DirectionalLight dl = new GlTF_DirectionalLight();
                    dl.color = new GlTF_ColorRGB(tr.GetComponent <Light>().color);
                    dl.name  = tr.name;
                    GlTF_Writer.lights.Add(dl);
                    break;

                case LightType.Area:
                    GlTF_AmbientLight al = new GlTF_AmbientLight();
                    al.color = new GlTF_ColorRGB(tr.GetComponent <Light>().color);
                    al.name  = tr.name;
                    GlTF_Writer.lights.Add(al);
                    break;
                }
            }

            Mesh m = GetMesh(tr);
            if (m != null)
            {
                GlTF_Mesh mesh = new GlTF_Mesh();
                mesh.name = GlTF_Mesh.GetNameFromObject(m);

                GlTF_Accessor positionAccessor = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "position"), GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                positionAccessor.bufferView = GlTF_Writer.vec3BufferView;
                GlTF_Writer.accessors.Add(positionAccessor);

                GlTF_Accessor normalAccessor = null;
                if (m.normals.Length > 0)
                {
                    normalAccessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "normal"), GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT);
                    normalAccessor.bufferView = GlTF_Writer.vec3BufferView;
                    GlTF_Writer.accessors.Add(normalAccessor);
                }

                GlTF_Accessor uv0Accessor = null;
                if (m.uv.Length > 0)
                {
                    uv0Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv0"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv0Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv0Accessor);
                }

                GlTF_Accessor uv1Accessor = null;
                if (m.uv2.Length > 0)
                {
                    uv1Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv1"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv1Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv1Accessor);
                }

                GlTF_Accessor uv2Accessor = null;
                if (m.uv3.Length > 0)
                {
                    uv2Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv2"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv2Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv2Accessor);
                }

                GlTF_Accessor uv3Accessor = null;
                if (m.uv4.Length > 0)
                {
                    uv3Accessor            = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "uv3"), GlTF_Accessor.Type.VEC2, GlTF_Accessor.ComponentType.FLOAT);
                    uv3Accessor.bufferView = GlTF_Writer.vec2BufferView;
                    GlTF_Writer.accessors.Add(uv3Accessor);
                }

                var smCount = m.subMeshCount;
                for (var i = 0; i < smCount; ++i)
                {
                    GlTF_Primitive primitive = new GlTF_Primitive();
                    primitive.name  = GlTF_Primitive.GetNameFromObject(m, i);
                    primitive.index = i;
                    GlTF_Attributes attributes = new GlTF_Attributes();
                    attributes.positionAccessor  = positionAccessor;
                    attributes.normalAccessor    = normalAccessor;
                    attributes.texCoord0Accessor = uv0Accessor;
                    attributes.texCoord1Accessor = uv1Accessor;
                    attributes.texCoord2Accessor = uv2Accessor;
                    attributes.texCoord3Accessor = uv3Accessor;
                    primitive.attributes         = attributes;
                    GlTF_Accessor indexAccessor = new GlTF_Accessor(GlTF_Accessor.GetNameFromObject(m, "indices_" + i), GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.USHORT);
                    indexAccessor.bufferView = GlTF_Writer.ushortBufferView;
                    GlTF_Writer.accessors.Add(indexAccessor);
                    primitive.indices = indexAccessor;

                    var mr = GetRenderer(tr);
                    var sm = mr.sharedMaterials;
                    if (i < sm.Length && sm[i] != null)
                    {
                        var mat     = sm[i];
                        var matName = GlTF_Material.GetNameFromObject(mat);
                        primitive.materialName = matName;
                        if (!GlTF_Writer.materials.ContainsKey(matName))
                        {
                            GlTF_Material material = new GlTF_Material();
                            material.name = matName;
                            GlTF_Writer.materials.Add(material.name, material);

                            //technique
                            var s        = mat.shader;
                            var techName = GlTF_Technique.GetNameFromObject(s);
                            material.instanceTechniqueName = techName;
                            if (!GlTF_Writer.techniques.ContainsKey(techName))
                            {
                                GlTF_Technique tech = new GlTF_Technique();
                                tech.name = techName;

                                GlTF_Technique.States ts = null;
                                if (preset.techniqueStates.ContainsKey(s.name))
                                {
                                    ts = preset.techniqueStates[s.name];
                                }
                                else if (preset.techniqueStates.ContainsKey("*"))
                                {
                                    ts = preset.techniqueStates["*"];
                                }

                                if (ts == null)
                                {
                                    // Unless otherwise specified by a preset file, enable z-buffering.
                                    ts = new GlTF_Technique.States();
                                    const int DEPTH_TEST = 2929;
                                    // int CULL_FACE = 2884;
                                    ts.enable = new int[1] {
                                        DEPTH_TEST
                                    };
                                }

                                tech.states = ts;

                                GlTF_Technique.Parameter tParam = new GlTF_Technique.Parameter();
                                tParam.name     = "position";
                                tParam.type     = GlTF_Technique.Type.FLOAT_VEC3;
                                tParam.semantic = GlTF_Technique.Semantic.POSITION;
                                tech.parameters.Add(tParam);
                                GlTF_Technique.Attribute tAttr = new GlTF_Technique.Attribute();
                                tAttr.name  = "a_position";
                                tAttr.param = tParam.name;
                                tech.attributes.Add(tAttr);

                                if (normalAccessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "normal";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC3;
                                    tParam.semantic = GlTF_Technique.Semantic.NORMAL;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_normal";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv0Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord0";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_0;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord0";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv1Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord1";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_1;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord1";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv2Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord2";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_2;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord2";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                if (uv3Accessor != null)
                                {
                                    tParam          = new GlTF_Technique.Parameter();
                                    tParam.name     = "texcoord3";
                                    tParam.type     = GlTF_Technique.Type.FLOAT_VEC2;
                                    tParam.semantic = GlTF_Technique.Semantic.TEXCOORD_3;
                                    tech.parameters.Add(tParam);
                                    tAttr       = new GlTF_Technique.Attribute();
                                    tAttr.name  = "a_texcoord3";
                                    tAttr.param = tParam.name;
                                    tech.attributes.Add(tAttr);
                                }

                                tech.AddDefaultUniforms(writer.RTCCenter != null);

                                GlTF_Writer.techniques.Add(techName, tech);

                                int spCount = ShaderUtil.GetPropertyCount(s);
                                for (var j = 0; j < spCount; ++j)
                                {
                                    var pName = ShaderUtil.GetPropertyName(s, j);
                                    var pType = ShaderUtil.GetPropertyType(s, j);
                                    // Debug.Log(pName + " " + pType);

                                    GlTF_Technique.Uniform tUni;
                                    if (pType == ShaderUtil.ShaderPropertyType.Color)
                                    {
                                        tParam      = new GlTF_Technique.Parameter();
                                        tParam.name = pName;
                                        tParam.type = GlTF_Technique.Type.FLOAT_VEC4;
                                        tech.parameters.Add(tParam);
                                        tUni       = new GlTF_Technique.Uniform();
                                        tUni.name  = pName;
                                        tUni.param = tParam.name;
                                        tech.uniforms.Add(tUni);
                                    }
                                    else if (pType == ShaderUtil.ShaderPropertyType.Vector)
                                    {
                                        tParam      = new GlTF_Technique.Parameter();
                                        tParam.name = pName;
                                        tParam.type = GlTF_Technique.Type.FLOAT_VEC4;
                                        tech.parameters.Add(tParam);
                                        tUni       = new GlTF_Technique.Uniform();
                                        tUni.name  = pName;
                                        tUni.param = tParam.name;
                                        tech.uniforms.Add(tUni);
                                    }
                                    else if (pType == ShaderUtil.ShaderPropertyType.Float ||
                                             pType == ShaderUtil.ShaderPropertyType.Range)
                                    {
                                        tParam      = new GlTF_Technique.Parameter();
                                        tParam.name = pName;
                                        tParam.type = GlTF_Technique.Type.FLOAT;
                                        tech.parameters.Add(tParam);
                                        tUni       = new GlTF_Technique.Uniform();
                                        tUni.name  = pName;
                                        tUni.param = tParam.name;
                                        tech.uniforms.Add(tUni);
                                    }
                                    else if (pType == ShaderUtil.ShaderPropertyType.TexEnv)
                                    {
                                        var td = ShaderUtil.GetTexDim(s, j);
                                        if (td == UnityEngine.Rendering.TextureDimension.Tex2D)
                                        {
                                            tParam      = new GlTF_Technique.Parameter();
                                            tParam.name = pName;
                                            tParam.type = GlTF_Technique.Type.SAMPLER_2D;
                                            tech.parameters.Add(tParam);
                                            tUni       = new GlTF_Technique.Uniform();
                                            tUni.name  = pName;
                                            tUni.param = tParam.name;
                                            tech.uniforms.Add(tUni);
                                        }
                                    }
                                }

                                // create program
                                GlTF_Program program = new GlTF_Program();
                                program.name = GlTF_Program.GetNameFromObject(s);
                                tech.program = program.name;
                                foreach (var attr in tech.attributes)
                                {
                                    program.attributes.Add(attr.name);
                                }
                                GlTF_Writer.programs.Add(program);

                                // shader
                                GlTF_Shader vs = new GlTF_Shader();
                                vs.name = GlTF_Shader.GetNameFromObject(s, GlTF_Shader.Type.Vertex);
                                program.vertexShader = vs.name;
                                vs.type = GlTF_Shader.Type.Vertex;
                                vs.uri  = preset.GetVertexShader(s.name);
                                GlTF_Writer.shaders.Add(vs);

                                GlTF_Shader fs = new GlTF_Shader();
                                fs.name = GlTF_Shader.GetNameFromObject(s, GlTF_Shader.Type.Fragment);
                                program.fragmentShader = fs.name;
                                fs.type = GlTF_Shader.Type.Fragment;
                                fs.uri  = preset.GetFragmentShader(s.name);
                                GlTF_Writer.shaders.Add(fs);
                            }

                            int spCount2 = ShaderUtil.GetPropertyCount(s);
                            for (var j = 0; j < spCount2; ++j)
                            {
                                var pName = ShaderUtil.GetPropertyName(s, j);
                                var pType = ShaderUtil.GetPropertyType(s, j);

                                if (pType == ShaderUtil.ShaderPropertyType.Color)
                                {
                                    var matCol = new GlTF_Material.ColorValue();
                                    matCol.name  = pName;
                                    matCol.color = mat.GetColor(pName);
                                    material.values.Add(matCol);
                                }
                                else if (pType == ShaderUtil.ShaderPropertyType.Vector)
                                {
                                    var matVec = new GlTF_Material.VectorValue();
                                    matVec.name   = pName;
                                    matVec.vector = mat.GetVector(pName);
                                    material.values.Add(matVec);
                                }
                                else if (pType == ShaderUtil.ShaderPropertyType.Float ||
                                         pType == ShaderUtil.ShaderPropertyType.Range)
                                {
                                    var matFloat = new GlTF_Material.FloatValue();
                                    matFloat.name  = pName;
                                    matFloat.value = mat.GetFloat(pName);
                                    material.values.Add(matFloat);
                                }
                                else if (pType == ShaderUtil.ShaderPropertyType.TexEnv)
                                {
                                    var td = ShaderUtil.GetTexDim(s, j);
                                    if (td == UnityEngine.Rendering.TextureDimension.Tex2D)
                                    {
                                        var t = mat.GetTexture(pName);
                                        if (t == null)
                                        {
                                            continue;
                                        }
                                        var val = new GlTF_Material.StringValue();
                                        val.name = pName;
                                        string texName = null;
                                        texName   = GlTF_Texture.GetNameFromObject(t);
                                        val.value = texName;
                                        material.values.Add(val);
                                        if (!GlTF_Writer.textures.ContainsKey(texName))
                                        {
                                            var        texPath = ExportTexture(t, savedPath);
                                            GlTF_Image img     = new GlTF_Image();
                                            img.name = GlTF_Image.GetNameFromObject(t);
                                            img.uri  = texPath;
                                            GlTF_Writer.images.Add(img);

                                            GlTF_Sampler sampler;
                                            var          samplerName = GlTF_Sampler.GetNameFromObject(t);
                                            if (GlTF_Writer.samplers.ContainsKey(samplerName))
                                            {
                                                sampler = GlTF_Writer.samplers[samplerName];
                                            }
                                            else
                                            {
                                                sampler      = new GlTF_Sampler(t);
                                                sampler.name = samplerName;
                                                GlTF_Writer.samplers[samplerName] = sampler;
                                            }

                                            GlTF_Texture texture = new GlTF_Texture();
                                            texture.name        = texName;
                                            texture.source      = img.name;
                                            texture.samplerName = samplerName;

                                            GlTF_Writer.textures.Add(texName, texture);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    mesh.primitives.Add(primitive);
                }

                mesh.Populate(m);
                GlTF_Writer.meshes.Add(mesh);
                if (unpackTexture)
                {
                    TextureUnpacker.ProcessMesh(mesh);
                }

                // calculate bounding box transform
                if (root != null)
                {
                    Matrix4x4 brot = Matrix4x4.identity;
                    if (rotCallback != null)
                    {
                        brot = rotCallback.GetBoundsRotationMatrix(root);
                    }

                    var pos    = tr.position - root.position; // relative to parent
                    var objMat = Matrix4x4.TRS(pos, tr.rotation, tr.lossyScale);

                    //read vertices
                    var ms     = positionAccessor.bufferView.memoryStream;
                    var offset = (int)positionAccessor.byteOffset;
                    var len    = positionAccessor.count;
                    var buffer = new byte[len * 12];
                    var mspos  = ms.Position;
                    ms.Position = offset;
                    ms.Read(buffer, 0, buffer.Length);

                    minHeight = double.MaxValue;
                    maxHeight = double.MinValue;

                    double[] c = writer.RTCCenter;

                    double[] minPos = new double[3];
                    minPos[0] = double.MaxValue;
                    minPos[1] = double.MaxValue;
                    minPos[2] = double.MaxValue;

                    double[] maxPos = new double[3];
                    maxPos[0] = double.MinValue;
                    maxPos[1] = double.MinValue;
                    maxPos[2] = double.MinValue;

                    for (int j = 0; j < len; ++j)
                    {
                        var x = System.BitConverter.ToSingle(buffer, j * 12);
                        var y = System.BitConverter.ToSingle(buffer, j * 12 + 4);
                        var z = System.BitConverter.ToSingle(buffer, j * 12 + 8);

                        // local rotation
                        var lx = objMat.m00 * x + objMat.m01 * y + objMat.m02 * z;
                        var ly = objMat.m10 * x + objMat.m11 * y + objMat.m12 * z;
                        var lz = objMat.m20 * x + objMat.m21 * y + objMat.m22 * z;

                        minHeight = Math.Min(minHeight, ly);
                        maxHeight = Math.Max(maxHeight, ly);

                        // to world
                        double wx = brot.m00 * lx + brot.m01 * ly + brot.m02 * lz;
                        double wy = brot.m10 * lx + brot.m11 * ly + brot.m12 * lz;
                        double wz = brot.m20 * lx + brot.m21 * ly + brot.m22 * lz;

                        // local translation to world
                        double tx = brot.m00 * pos.x + brot.m01 * pos.y + brot.m02 * pos.z;
                        double ty = brot.m10 * pos.x + brot.m11 * pos.y + brot.m12 * pos.z;
                        double tz = brot.m20 * pos.x + brot.m21 * pos.y + brot.m22 * pos.z;

                        wx += tx;
                        wy += ty;
                        wz += tz;

                        if (c != null)
                        {
                            wx += c[0];
                            wy += c[1];
                            wz += c[2];
                        }

                        minPos[0] = Math.Min(minPos[0], wx);
                        minPos[1] = Math.Min(minPos[1], wy);
                        minPos[2] = Math.Min(minPos[2], wz);

                        maxPos[0] = Math.Max(maxPos[0], wx);
                        maxPos[1] = Math.Max(maxPos[1], wy);
                        maxPos[2] = Math.Max(maxPos[2], wz);
                    }

                    ms.Position = mspos;

                    BoundsDouble tbb = new BoundsDouble();
                    tbb.Encapsulate(new BoundsDouble(minPos, maxPos));
                    bb.Encapsulate(tbb);
                }
            }

            Animation a = tr.GetComponent <Animation>();

            //				Animator a = tr.GetComponent<Animator>();
            if (a != null)
            {
                AnimationClip[] clips  = AnimationUtility.GetAnimationClips(tr.gameObject);
                int             nClips = clips.Length;
                //					int nClips = a.GetClipCount();
                for (int i = 0; i < nClips; i++)
                {
                    GlTF_Animation anim = new GlTF_Animation(a.name);
                    anim.Populate(clips[i]);
                    GlTF_Writer.animations.Add(anim);
                }
            }


            // next, build hierarchy of nodes
            GlTF_Node node = new GlTF_Node();

            Matrix4x4 rotMat = Matrix4x4.identity;
            if (root != null && rotCallback != null)
            {
                rotMat = rotCallback.GetNodeRotationMatrix(root);
            }

            if (tr == root)
            {
                Matrix4x4 mat = Matrix4x4.identity;
                mat.m22 = -1; // flip z axis

                if (rotMat != Matrix4x4.identity)
                {
                    mat = rotMat;
                }

                // do not use global position if rtc is defined
                Vector3 pos = Vector3.zero;
                if (writer.RTCCenter == null)
                {
                    pos = tr.localPosition;
                }

                mat         = mat * Matrix4x4.TRS(pos, tr.localRotation, tr.localScale);
                node.matrix = new GlTF_Matrix(mat);
            }
            else
            {
                node.hasParent = true;
                if (tr.localPosition != Vector3.zero)
                {
                    node.translation = new GlTF_Translation(tr.localPosition);
                }
                if (tr.localScale != Vector3.one)
                {
                    node.scale = new GlTF_Scale(tr.localScale);
                }
                if (tr.localRotation != Quaternion.identity)
                {
                    node.rotation = new GlTF_Rotation(tr.localRotation);
                }
            }

            node.name = GlTF_Node.GetNameFromObject(tr);
            if (tr.GetComponent <Camera>() != null)
            {
                node.cameraName = tr.name;
            }
            else if (tr.GetComponent <Light>() != null)
            {
                node.lightName = tr.name;
            }
            else if (m != null)
            {
                node.meshNames.Add(GlTF_Mesh.GetNameFromObject(m));
            }

            foreach (Transform t in tr.transform)
            {
                var found = false;
                foreach (var check in trs)
                {
                    if (t == check)
                    {
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    node.childrenNames.Add(GlTF_Node.GetNameFromObject(t));
                }
            }

            GlTF_Writer.nodes.Add(node);
        }

        if (copyShaders && preset.shaderDir != null)
        {
            var sd = Path.Combine(Application.dataPath, preset.shaderDir);
            foreach (var shader in GlTF_Writer.shaders)
            {
                var srcPath = Path.Combine(sd, shader.uri);
                if (File.Exists(srcPath))
                {
                    var dstPath = Path.Combine(savedPath, shader.uri);
                    File.Copy(srcPath, dstPath, true);
                }
            }
        }

        // third, add meshes etc to byte stream, keeping track of buffer offsets
        writer.Write();
        writer.CloseFiles();
        return(bb);
    }
コード例 #18
0
    void OnWizardCreate() // Create (Export) button has been hit (NOT wizard has been created!)
    {
		writer = new GlTF_Writer();
		writer.Init ();
/*
		Object[] deps = EditorUtility.CollectDependencies  (trs);
		foreach (Object o in deps)
		{
			Debug.Log("obj "+o.name+"  "+o.GetType());
		}
*/		
		
		path = EditorUtility.SaveFilePanel("Save glTF file as", savedPath, savedFile, "gltf");
		if (path.Length != 0)
		{
			Debug.Log ("attempting to save to "+path);
			writer.OpenFiles (path);

			// FOR NOW!
			GlTF_Sampler sampler = new GlTF_Sampler("sampler1"); // make the default one for now
			GlTF_Writer.samplers.Add (sampler);
			// first, collect objects in the scene, add to lists
			Transform[] trs = Selection.GetTransforms (SelectionMode.Deep);
			foreach (Transform tr in trs)
			{
				if (tr.camera != null)
				{
					if (tr.camera.isOrthoGraphic)
					{
						GlTF_Orthographic cam;
						cam = new GlTF_Orthographic();
						cam.type = "orthographic";
						cam.zfar = tr.camera.farClipPlane;
						cam.znear = tr.camera.nearClipPlane;
						cam.name = tr.name;
						//cam.orthographic.xmag = tr.camera.
						GlTF_Writer.cameras.Add(cam);
					}
					else
					{
						GlTF_Perspective cam;
						cam = new GlTF_Perspective();
						cam.type = "perspective";
						cam.zfar = tr.camera.farClipPlane;
						cam.znear = tr.camera.nearClipPlane;
						cam.aspect_ratio = tr.camera.aspect;
						cam.yfov = tr.camera.fieldOfView;
						cam.name = tr.name;
						GlTF_Writer.cameras.Add(cam);
					}
				}
				
				if (tr.light != null)
				{
					switch (tr.light.type)
					{
					case LightType.Point:
						GlTF_PointLight pl = new GlTF_PointLight();
						pl.color = new GlTF_ColorRGB (tr.light.color);
						pl.name = tr.name;
						GlTF_Writer.lights.Add (pl);
						break;

					case LightType.Spot:
						GlTF_SpotLight sl = new GlTF_SpotLight();
						sl.color = new GlTF_ColorRGB (tr.light.color);
						sl.name = tr.name;
						GlTF_Writer.lights.Add (sl);
						break;
						
					case LightType.Directional:
						GlTF_DirectionalLight dl = new GlTF_DirectionalLight();
						dl.color = new GlTF_ColorRGB (tr.light.color);
						dl.name = tr.name;
						GlTF_Writer.lights.Add (dl);
						break;
						
					case LightType.Area:
						GlTF_AmbientLight al = new GlTF_AmbientLight();
						al.color = new GlTF_ColorRGB (tr.light.color);
						al.name = tr.name;
						GlTF_Writer.lights.Add (al);
						break;
					}
				}

				MeshRenderer mr = tr.GetComponent<MeshRenderer>();
				if (mr != null)
				{
					MeshFilter mf = tr.GetComponent<MeshFilter>();
					Mesh m = mf.sharedMesh;
					GlTF_Accessor normalAccessor = new GlTF_Accessor("normalAccessor-" + tr.name + "_FIXTHIS", "VEC3", "FLOAT");
					GlTF_Accessor positionAccessor = new GlTF_Accessor("positionAccessor-" + tr.name + "_FIXTHIS", "VEC3", "FLOAT");
					GlTF_Accessor texCoord0Accessor = new GlTF_Accessor("texCoord0Accessor-" + tr.name + "_FIXTHIS", "VEC2", "FLOAT");
					GlTF_Accessor indexAccessor = new GlTF_Accessor("indicesAccessor-" + tr.name + "_FIXTHIS", "SCALAR", "USHORT");
					indexAccessor.bufferView = GlTF_Writer.ushortBufferView;
					normalAccessor.bufferView = GlTF_Writer.vec3BufferView;
					positionAccessor.bufferView = GlTF_Writer.vec3BufferView;
					texCoord0Accessor.bufferView = GlTF_Writer.vec2BufferView;
					GlTF_Mesh mesh = new GlTF_Mesh();
					mesh.name = "mesh-" + tr.name;
					GlTF_Primitive primitive = new GlTF_Primitive();
					primitive.name = "primitive-"+tr.name+"_FIXTHIS";
					GlTF_Attributes attributes = new GlTF_Attributes();
					attributes.normalAccessor = normalAccessor;
					attributes.positionAccessor = positionAccessor;
					attributes.texCoord0Accessor = texCoord0Accessor;
					primitive.attributes = attributes;
					primitive.indices = indexAccessor;
					mesh.primitives.Add (primitive);
					mesh.Populate (m);
					GlTF_Writer.accessors.Add (normalAccessor);
					GlTF_Writer.accessors.Add (positionAccessor);
					GlTF_Writer.accessors.Add (texCoord0Accessor);
					GlTF_Writer.accessors.Add (indexAccessor);
					GlTF_Writer.meshes.Add (mesh);

					// next, add material(s) to dictionary (when unique)
					string matName = mr.sharedMaterial.name;
					if (matName == "")
						matName = "material-diffault-diffuse";
					else
						matName = "material-" + matName;
					primitive.materialName = matName;
					if (!GlTF_Writer.materials.ContainsKey (matName))
					{
						GlTF_Material material = new GlTF_Material();
						material.name = matName;
						if (mr.sharedMaterial.HasProperty ("shininess"))
							material.shininess = mr.sharedMaterial.GetFloat("shininess");
						material.diffuse = new GlTF_MaterialColor ("diffuse", mr.sharedMaterial.color);
						//material.ambient = new GlTF_Color ("ambient", mr.material.color);
						
						if (mr.sharedMaterial.HasProperty ("specular"))
						{
							Color sc = mr.sharedMaterial.GetColor ("specular");
							material.specular = new GlTF_MaterialColor ("specular", sc);
						}
						GlTF_Writer.materials.Add (material.name, material);

						// if there are textures, add them too
						if (mr.sharedMaterial.mainTexture != null)
						{
							if (!GlTF_Writer.textures.ContainsKey (mr.sharedMaterial.mainTexture.name))
							{
								GlTF_Texture texture = new GlTF_Texture ();
								texture.name = mr.sharedMaterial.mainTexture.name;
								texture.source = AssetDatabase.GetAssetPath(mr.sharedMaterial.mainTexture);
								texture.samplerName = sampler.name; // FIX! For now!
								GlTF_Writer.textures.Add (mr.sharedMaterial.mainTexture.name, texture);
								material.diffuse = new GlTF_MaterialTexture ("diffuse", texture);
							}
						}
					}
					
				}

				Animation a = tr.animation;
				
//				Animator a = tr.GetComponent<Animator>();				
				if (a != null)
				{
					AnimationClip[] clips = AnimationUtility.GetAnimationClips(tr.gameObject);
					int nClips = clips.Length;
//					int nClips = a.GetClipCount();
					for (int i = 0; i < nClips; i++)
					{
						GlTF_Animation anim = new GlTF_Animation(a.name);
						anim.Populate (clips[i]);
						GlTF_Writer.animations.Add (anim);
					}
				}

	
				// next, build hierarchy of nodes
				GlTF_Node node = new GlTF_Node();
				if (tr.parent != null)
					node.hasParent = true;
				if (tr.localPosition != Vector3.zero)
					node.translation = new GlTF_Translation (tr.localPosition);
				if (tr.localScale != Vector3.one)
					node.scale = new GlTF_Scale (tr.localScale);
				if (tr.localRotation != Quaternion.identity)
					node.rotation = new GlTF_Rotation (tr.localRotation);
				node.name = tr.name;
				if (tr.camera != null)
				{
					node.cameraName = tr.name;
				}
				else if (tr.light != null)
					node.lightName = tr.name;
				else if (mr != null)
				{
					node.meshNames.Add ("mesh-" + tr.name);
				}

				foreach (Transform t in tr.transform)
					node.childrenNames.Add ("node-" + t.name);
				
				GlTF_Writer.nodes.Add (node);
			}

			// third, add meshes etc to byte stream, keeping track of buffer offsets
			writer.Write ();
			writer.CloseFiles();
		}
	}