Inheritance: GlTF_Writer
Exemplo n.º 1
0
    // Get or create texture object, image and sampler
    private int processTexture(Texture2D t, IMAGETYPE format)
    {
        var texName = GlTF_Texture.GetNameFromObject(t);

        if (AssetDatabase.GetAssetPath(t).Length == 0)
        {
            Debug.LogWarning("Texture " + t.name + " cannot be found in assets");
            return(-1);
        }

        if (!GlTF_Writer.textureNames.Contains(texName))
        {
            string assetPath = AssetDatabase.GetAssetPath(t);

            // Create texture
            GlTF_Texture texture = new GlTF_Texture();
            texture.name = texName;

            // Export image
            GlTF_Image img = new GlTF_Image();
            img.name = GlTF_Image.GetNameFromObject(t);
            img.uri  = convertTexture(ref t, assetPath, savedPath, format);

            texture.source = GlTF_Writer.imageNames.Count;
            GlTF_Writer.imageNames.Add(img.name);
            GlTF_Writer.images.Add(img);

            // Add sampler
            GlTF_Sampler sampler;
            var          samplerName = GlTF_Sampler.GetNameFromObject(t);
            if (!GlTF_Writer.samplerNames.Contains(samplerName))
            {
                sampler      = new GlTF_Sampler(t);
                sampler.name = samplerName;
                GlTF_Writer.samplers.Add(sampler);
                GlTF_Writer.samplerNames.Add(samplerName);
            }

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

        return(GlTF_Writer.textureNames.IndexOf(texName));
    }
    /// Adds a texture parameter + uniform to the specified material.
    /// As a side effect, auto-creates textures, images, and maybe a sampler if necessary.
    /// Pass:
    ///   matObjName - the material
    ///   texParam - name of the material parameter to add
    ///   fileRef - file containing texture data
    public void AddTextureToMaterial(
        IExportableMaterial exportableMaterial, string texParam, ExportFileReference fileRef)
    {
        GlTF_Material material = G.materials[exportableMaterial];

        GlTF_Sampler sampler = GlTF_Sampler.LookupOrCreate(
            G, GlTF_Sampler.MagFilter.LINEAR, GlTF_Sampler.MinFilter.LINEAR_MIPMAP_LINEAR);

        // The names only matter for gltf1, so keep them similar for easier diffing.
        // Essentially, this names the image and texture after the first material that wanted them.
        string matNameAndParam = $"{exportableMaterial.UniqueName:D}_{texParam}";
        var    img             = GlTF_Image.LookupOrCreate(G, fileRef, proposedName: matNameAndParam);
        var    tex             = GlTF_Texture.LookupOrCreate(G, img, sampler, proposedName: matNameAndParam);

        material.values.Add(new GlTF_Material.TextureKV(key: texParam, texture: tex));

        // Add texture-related parameter and uniform.
        AddUniform(exportableMaterial,
                   texParam, GlTF_Technique.Type.SAMPLER_2D, GlTF_Technique.Semantic.UNKNOWN, null);
    }
Exemplo n.º 3
0
 public TextureKV(string key, GlTF_Texture texture)
 {
     this.key  = key;
     m_texture = texture;
 }
Exemplo n.º 4
0
    private int createOcclusionMetallicRoughnessTexture(ref Texture2D occlusion, ref Texture2D metallicRoughness)
    {
        string texName   = "";
        int    width     = -1;
        int    height    = -1;
        string assetPath = "";

        if (occlusion)
        {
            texName   = texName + GlTF_Texture.GetNameFromObject(occlusion);
            assetPath = AssetDatabase.GetAssetPath(occlusion);
            width     = occlusion.width;
            height    = occlusion.height;
        }
        else
        {
            texName = texName + "_";
        }

        if (metallicRoughness)
        {
            texName   = texName + GlTF_Texture.GetNameFromObject(metallicRoughness);
            assetPath = AssetDatabase.GetAssetPath(metallicRoughness);
            width     = metallicRoughness.width;
            height    = metallicRoughness.height;
        }
        else
        {
            texName = texName + "_";
        }

        if (!GlTF_Writer.textureNames.Contains(texName))
        {
            // Create texture
            GlTF_Texture texture = new GlTF_Texture();
            texture.name = texName;

            // Export image
            GlTF_Image img = new GlTF_Image();
            img.name = texName;
            //img.uri =

            // Let's consider that the three textures have the same resolution
            Color[] outputColors = new Color[width * height];
            for (int i = 0; i < outputColors.Length; ++i)
            {
                outputColors[i] = new Color(1.0f, 1.0f, 1.0f);
            }

            if (occlusion)
            {
                addTexturePixels(ref occlusion, ref outputColors, IMAGETYPE.R);
            }
            if (metallicRoughness)
            {
                addTexturePixels(ref metallicRoughness, ref outputColors, IMAGETYPE.B);
                addTexturePixels(ref metallicRoughness, ref outputColors, IMAGETYPE.G_INVERT, IMAGETYPE.A);
            }

            Texture2D newtex = new Texture2D(width, height);
            newtex.SetPixels(outputColors);
            newtex.Apply();

            string pathInArchive = Path.GetDirectoryName(assetPath);
            string exportDir     = Path.Combine(savedPath, pathInArchive);

            if (!Directory.Exists(exportDir))
            {
                Directory.CreateDirectory(exportDir);
            }

            string outputFilename = Path.GetFileNameWithoutExtension(assetPath) + "_converted_metalRoughness.jpg";
            string exportPath     = exportDir + "/" + outputFilename;          // relative path inside the .zip
            File.WriteAllBytes(exportPath, newtex.EncodeToJPG(jpgQuality));

            if (!GlTF_Writer.exportedFiles.ContainsKey(exportPath))
            {
                GlTF_Writer.exportedFiles.Add(exportPath, pathInArchive);
            }
            else
            {
                Debug.LogError("Texture '" + newtex.name + "' already exists");
            }

            img.uri = pathInArchive + "/" + outputFilename;

            texture.source = GlTF_Writer.imageNames.Count;
            GlTF_Writer.imageNames.Add(img.name);
            GlTF_Writer.images.Add(img);

            // Add sampler
            GlTF_Sampler sampler;
            var          samplerName = GlTF_Sampler.GetNameFromObject(metallicRoughness);
            if (!GlTF_Writer.samplerNames.Contains(samplerName))
            {
                sampler      = new GlTF_Sampler(metallicRoughness);
                sampler.name = samplerName;
                GlTF_Writer.samplers.Add(sampler);
                GlTF_Writer.samplerNames.Add(samplerName);
            }

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

        return(GlTF_Writer.textureNames.IndexOf(texName));
    }
Exemplo n.º 5
0
    private static string ExportTexture(Texture texture, string path)
    {
        var assetPath = AssetDatabase.GetAssetPath(texture);
        var fn        = Path.GetFileName(assetPath);
        var t         = texture as Texture2D;
        var name      = GlTF_Texture.GetNameFromObject(t);

        if (t != null)
        {
            var ext = Path.GetExtension(assetPath);
            if (ext == ".dds")
            {
                var ct = Type.GetType("Imaging.DDSReader.DDS");
                if (ct != null)
                {
                    var srcPath = GetAssetFullPath(assetPath);
                    //					var srcTex = Imaging.DDSReader.DDS.LoadImage(srcPath, true);
                    Texture2D srcTex = ct.GetMethod("LoadImage", new Type[] { typeof(string), typeof(bool) }).Invoke(null, new object[] { srcPath, true }) as Texture2D;
                    fn = Path.GetFileNameWithoutExtension(assetPath) + ".png";
                    var dstPath = Path.Combine(path, fn);

                    Texture2D curTex = null;
                    if (unpackTexture)
                    {
                        curTex = TextureUnpacker.ProcessTexture(name, srcTex);
                    }
                    else
                    {
                        curTex = srcTex;
                    }


                    var b = curTex.EncodeToPNG();
                    File.WriteAllBytes(dstPath, b);
                    if (curTex != srcTex)
                    {
                        Texture2D.DestroyImmediate(curTex);
                    }
                    Texture2D.DestroyImmediate(srcTex);
                }
                else
                {
                    fn = Path.GetFileNameWithoutExtension(assetPath) + ".png";
                    var       dstPath = Path.Combine(path, fn);
                    Texture2D t2      = new Texture2D(t.width, t.height, TextureFormat.RGBA32, false);
                    t2.SetPixels(t.GetPixels());
                    t2.Apply();

                    Texture2D curTex = null;
                    if (unpackTexture)
                    {
                        curTex = TextureUnpacker.ProcessTexture(name, t2);
                    }
                    else
                    {
                        curTex = t2;
                    }

                    var b = curTex.EncodeToPNG();
                    File.WriteAllBytes(dstPath, b);
                    if (curTex != t2)
                    {
                        Texture2D.DestroyImmediate(curTex);
                    }
                    Texture2D.DestroyImmediate(t2);
                }
            }
            else
            {
                var dstPath = Path.Combine(path, fn);
                if (unpackTexture)
                {
                    // load src texture from path to prevent access error
                    var       read    = File.ReadAllBytes(assetPath);
                    Texture2D copyTex = new Texture2D(t.width, t.height, TextureFormat.RGBA32, false);
                    copyTex.LoadImage(read);
                    copyTex.Apply();

                    // size could be different from import settings
                    if (t.width != copyTex.width || t.height != copyTex.height)
                    {
                        GltfTextureScale.Bilinear(copyTex, t.width, t.height);
                    }

                    Texture2D curTex = TextureUnpacker.ProcessTexture(name, copyTex);

                    byte[] b = null;
                    if (ext == ".jpg")
                    {
                        b = curTex.EncodeToJPG();
                    }
                    else if (ext == ".png")
                    {
                        b = curTex.EncodeToPNG();
                    }

                    if (b != null)
                    {
                        File.WriteAllBytes(dstPath, b);
                    }
                    else
                    {
                        Debug.LogError("Unsupported file format for: " + fn);
                    }

                    if (curTex != copyTex)
                    {
                        Texture2D.DestroyImmediate(curTex);
                    }
                    Texture2D.DestroyImmediate(copyTex);
                }
                else
                {
                    File.Copy(assetPath, dstPath, true);
                }
            }
        }
        return(fn);
    }
Exemplo n.º 6
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();
		}
	}
Exemplo n.º 7
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);
    }
Exemplo n.º 8
0
	public GlTF_MaterialTexture (string n, GlTF_Texture t) { name = n; texture = t; }
 public GlTF_MaterialTexture(GlTF_Globals globals, string n, GlTF_Texture t) : base(globals)
 {
     name = n; texture = t;
 }
Exemplo n.º 10
0
 public GlTF_MaterialTexture(string n, GlTF_Texture t)
 {
     name = n; texture = t;
 }
Exemplo n.º 11
0
 public static string GetNameFromObject(Object o)
 {
     return(GlTF_Texture.GetNameFromObject(o, IMAGETYPE.RGBA));
 }
Exemplo n.º 12
0
    public static void CheckPackedTexture(Transform t, Preset preset)
    {
        var m = GetMesh(t);
        var r = GetRenderer(t);

        if (m != null && r != null)
        {
            for (int i = 0; i < m.subMeshCount; ++i)
            {
                if (m.GetTopology(i) != MeshTopology.Triangles ||
                    i >= r.sharedMaterials.Length)
                {
                    continue;
                }
                var mat = r.sharedMaterials[i];
                if (mat == null)
                {
                    Debug.LogWarning("Failed getting shader name from material on mesh " + m.name);
                    continue;
                }
                List <Preset.UnpackUV> unpackUVList = null;
                preset.unpackUV.TryGetValue(mat.shader.name, out unpackUVList);
                if (unpackUVList == null)
                {
                    unpackUVList = preset.GetDefaultUnpackUVList();
                }

                var tris = m.GetTriangles(i);

                var uvsArr = new Vector2[][] { m.uv, m.uv2, m.uv3, m.uv4 };
                var mins   = new Vector2[4];
                var maxs   = new Vector2[4];
                var dxs    = new float[4];
                var dys    = new float[4];
                for (int k = 0; k < 4; ++k)
                {
                    Vector2 min = new Vector2(float.MaxValue, float.MaxValue);
                    Vector2 max = new Vector2(float.MinValue, float.MinValue);

                    var uvs = uvsArr[k];
                    if (uvs != null && uvs.Length > 0)
                    {
                        for (int j = 0; j < tris.Length; ++j)
                        {
                            Vector2 uv = uvs[tris[j]];
                            float   y  = 1.0f - uv.y; // flipped y
                            min.x = Mathf.Min(min.x, uv.x);
                            min.y = Mathf.Min(min.y, y);
                            max.x = Mathf.Max(max.x, uv.x);
                            max.y = Mathf.Max(max.y, y);
                        }

                        var dx = max.x - min.x;
                        var dy = max.y - min.y;
                        dxs[k] = dx;
                        dys[k] = dy;
                    }

                    mins[k] = min;
                    maxs[k] = max;
                }

                var texs = GetTexturesFromMaterial(mat);

                foreach (var unpackUV in unpackUVList)
                {
                    foreach (var texIdx in unpackUV.textureIndex)
                    {
                        if (texIdx < texs.Count)
                        {
                            var tex  = texs[texIdx];
                            var name = GlTF_Texture.GetNameFromObject(tex);
                            // var dx = dxs[unpackUV.index];
                            // var dy = dys[unpackUV.index];
                            var max = maxs[unpackUV.index];
                            var min = mins[unpackUV.index];

                            max.x = Mathf.Clamp01(max.x);
                            max.y = Mathf.Clamp01(max.y);
                            min.x = Mathf.Clamp01(min.x);
                            min.y = Mathf.Clamp01(min.y);

                            var tw = tex.width;
                            var th = tex.height;

                            var sx = Mathf.FloorToInt(min.x * tw);
                            var fx = Mathf.CeilToInt(max.x * tw);
                            var sy = Mathf.FloorToInt(min.y * th);
                            var fy = Mathf.CeilToInt(max.y * th);
                            int wx = fx - sx;
                            int wy = fy - sy;

                            wx = Mathf.NextPowerOfTwo(wx);
                            wy = Mathf.NextPowerOfTwo(wy);

                            var   meshName = GlTF_Mesh.GetNameFromObject(m);
                            Entry e;
                            if (entries.ContainsKey(name))
                            {
                                e = entries[name];

                                //merge
                                var minX = Mathf.Min(e.left, sx);
                                var maxX = Mathf.Max(e.right, fx);
                                var minY = Mathf.Min(e.top, sy);
                                var maxY = Mathf.Max(e.bottom, fy);

                                var mw = maxX - minX;
                                var mh = maxY - minY;

                                mw = Mathf.NextPowerOfTwo(mw);
                                mh = Mathf.NextPowerOfTwo(mh);

                                e.left   = minX;
                                e.right  = maxX;
                                e.top    = minY;
                                e.bottom = maxY;
                            }
                            else
                            {
                                e             = new Entry();
                                e.left        = sx;
                                e.right       = fx;
                                e.top         = sy;
                                e.bottom      = fy;
                                e.texWidth    = tex.width;
                                e.texHeight   = tex.height;
                                entries[name] = e;
                            }

                            List <int> subMeshId = null;
                            if (e.subMeshMap.ContainsKey(meshName))
                            {
                                subMeshId = e.subMeshMap[meshName];
                            }
                            else
                            {
                                subMeshId = new List <int>();
                                e.subMeshMap[meshName] = subMeshId;
                            }

                            if (!subMeshId.Contains(i))
                            {
                                subMeshId.Add(i);
                            }
                        }
                    }
                }
            }
        }
    }