mirror of
				https://github.com/maxartz15/VertexAnimation.git
				synced 2025-11-04 10:25:44 +01:00 
			
		
		
		
	Model Baker Updates
... Added fps to book data. Cleanup. Preparing LOD generation.
This commit is contained in:
		@@ -3,187 +3,190 @@ using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace TAO.VertexAnimation
 | 
			
		||||
{
 | 
			
		||||
    public static class AnimationBaker
 | 
			
		||||
    {
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct BakedData
 | 
			
		||||
        {
 | 
			
		||||
            public Mesh mesh;
 | 
			
		||||
            public List<Texture2D> positionMaps;
 | 
			
		||||
	public static class AnimationBaker
 | 
			
		||||
	{
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct BakedData
 | 
			
		||||
		{
 | 
			
		||||
			public Mesh mesh;
 | 
			
		||||
			public List<Texture2D> positionMaps;
 | 
			
		||||
 | 
			
		||||
            // Returns main position map.
 | 
			
		||||
            public Texture2D GetPositionMap
 | 
			
		||||
            {
 | 
			
		||||
                get
 | 
			
		||||
                {
 | 
			
		||||
                    return positionMaps[0];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
			// Returns main position map.
 | 
			
		||||
			public Texture2D GetPositionMap
 | 
			
		||||
			{
 | 
			
		||||
				get
 | 
			
		||||
				{
 | 
			
		||||
					return positionMaps[0];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct AnimationInfo
 | 
			
		||||
        {
 | 
			
		||||
            public int rawFrameHeight;
 | 
			
		||||
            public int frameHeight;
 | 
			
		||||
            public int frameSpacing;
 | 
			
		||||
            public int frames;
 | 
			
		||||
            public int maxFrames;
 | 
			
		||||
            public int textureWidth;
 | 
			
		||||
            public int textureHeight;
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct AnimationInfo
 | 
			
		||||
		{
 | 
			
		||||
			public int rawFrameHeight;
 | 
			
		||||
			public int frameHeight;
 | 
			
		||||
			public int frameSpacing;
 | 
			
		||||
			public int frames;
 | 
			
		||||
			public int maxFrames;
 | 
			
		||||
			public int textureWidth;
 | 
			
		||||
			public int textureHeight;
 | 
			
		||||
			public int fps;
 | 
			
		||||
 | 
			
		||||
            // Create animation info and calculate values.
 | 
			
		||||
            public AnimationInfo(Mesh mesh, int frames, int textureWidth)
 | 
			
		||||
            {
 | 
			
		||||
                this.frames = frames;
 | 
			
		||||
                this.textureWidth = textureWidth;
 | 
			
		||||
			// Create animation info and calculate values.
 | 
			
		||||
			public AnimationInfo(Mesh mesh, int frames, int textureWidth, int fps)
 | 
			
		||||
			{
 | 
			
		||||
				this.frames = frames;
 | 
			
		||||
				this.textureWidth = textureWidth;
 | 
			
		||||
				this.fps = fps;
 | 
			
		||||
 | 
			
		||||
                rawFrameHeight = Mathf.CeilToInt((float)mesh.vertices.Length / this.textureWidth);
 | 
			
		||||
                frameHeight = Mathf.NextPowerOfTwo(rawFrameHeight);
 | 
			
		||||
                frameSpacing = (frameHeight - rawFrameHeight) + 1;
 | 
			
		||||
				rawFrameHeight = Mathf.CeilToInt((float)mesh.vertices.Length / this.textureWidth);
 | 
			
		||||
				frameHeight = Mathf.NextPowerOfTwo(rawFrameHeight);
 | 
			
		||||
				frameSpacing = (frameHeight - rawFrameHeight) + 1;
 | 
			
		||||
 | 
			
		||||
                textureHeight = Mathf.NextPowerOfTwo(frameHeight * this.frames);
 | 
			
		||||
				textureHeight = Mathf.NextPowerOfTwo(frameHeight * this.frames);
 | 
			
		||||
 | 
			
		||||
                maxFrames = textureHeight / frameHeight;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
				maxFrames = textureHeight / frameHeight;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static BakedData Bake(this GameObject model, AnimationClip[] animationClips, int fps, int textureWidth)
 | 
			
		||||
        {
 | 
			
		||||
            BakedData bakedData = new BakedData()
 | 
			
		||||
            {
 | 
			
		||||
                mesh = null,
 | 
			
		||||
                positionMaps = new List<Texture2D>()
 | 
			
		||||
            };
 | 
			
		||||
		public static BakedData Bake(this GameObject model, AnimationClip[] animationClips, int fps, int textureWidth)
 | 
			
		||||
		{
 | 
			
		||||
			BakedData bakedData = new BakedData()
 | 
			
		||||
			{
 | 
			
		||||
				mesh = null,
 | 
			
		||||
				positionMaps = new List<Texture2D>()
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
            // Calculate what our max frames/time is going to be.
 | 
			
		||||
            int maxFrames = 0;
 | 
			
		||||
            foreach (AnimationClip ac in animationClips)
 | 
			
		||||
            {
 | 
			
		||||
                int frames = Mathf.FloorToInt(fps * ac.length);
 | 
			
		||||
			// Calculate what our max frames/time is going to be.
 | 
			
		||||
			int maxFrames = 0;
 | 
			
		||||
			foreach (AnimationClip ac in animationClips)
 | 
			
		||||
			{
 | 
			
		||||
				int frames = Mathf.FloorToInt(fps * ac.length);
 | 
			
		||||
 | 
			
		||||
                if (maxFrames < frames)
 | 
			
		||||
                {
 | 
			
		||||
                    maxFrames = frames;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				if (maxFrames < frames)
 | 
			
		||||
				{
 | 
			
		||||
					maxFrames = frames;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // Get the target mesh to calculate the animation info.
 | 
			
		||||
            Mesh mesh = model.GetComponent<SkinnedMeshRenderer>().sharedMesh;
 | 
			
		||||
			// Get the target mesh to calculate the animation info.
 | 
			
		||||
			Mesh mesh = model.GetComponent<SkinnedMeshRenderer>().sharedMesh;
 | 
			
		||||
 | 
			
		||||
            // Get the info for the biggest animation.
 | 
			
		||||
            AnimationInfo animationInfo = new AnimationInfo(mesh, maxFrames, textureWidth);
 | 
			
		||||
			// Get the info for the biggest animation.
 | 
			
		||||
			AnimationInfo animationInfo = new AnimationInfo(mesh, maxFrames, textureWidth, fps);
 | 
			
		||||
 | 
			
		||||
            foreach (AnimationClip ac in animationClips)
 | 
			
		||||
            {
 | 
			
		||||
                // Set the frames for this animation.
 | 
			
		||||
                animationInfo.frames = Mathf.FloorToInt(fps * ac.length);
 | 
			
		||||
			foreach (AnimationClip ac in animationClips)
 | 
			
		||||
			{
 | 
			
		||||
				// Set the frames for this animation.
 | 
			
		||||
				animationInfo.frames = Mathf.FloorToInt(fps * ac.length);
 | 
			
		||||
 | 
			
		||||
                BakedData bd = Bake(model, ac, animationInfo);
 | 
			
		||||
                bakedData.mesh = bd.mesh;
 | 
			
		||||
                bakedData.positionMaps.AddRange(bd.positionMaps);
 | 
			
		||||
            }
 | 
			
		||||
				BakedData bd = Bake(model, ac, animationInfo);
 | 
			
		||||
				bakedData.mesh = bd.mesh;
 | 
			
		||||
				bakedData.positionMaps.AddRange(bd.positionMaps);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            return bakedData;
 | 
			
		||||
        }
 | 
			
		||||
			return bakedData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static BakedData Bake(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo)
 | 
			
		||||
        {
 | 
			
		||||
            Mesh mesh = new Mesh
 | 
			
		||||
            {
 | 
			
		||||
                name = string.Format("{0}", model.name)
 | 
			
		||||
            };
 | 
			
		||||
		public static BakedData Bake(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo)
 | 
			
		||||
		{
 | 
			
		||||
			Mesh mesh = new Mesh
 | 
			
		||||
			{
 | 
			
		||||
				name = string.Format("{0}", model.name)
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
            // Bake mesh for a copy and to apply the new UV's to.
 | 
			
		||||
            SkinnedMeshRenderer skinnedMeshRenderer = model.GetComponent<SkinnedMeshRenderer>();
 | 
			
		||||
            skinnedMeshRenderer.BakeMesh(mesh);
 | 
			
		||||
            mesh.RecalculateBounds();
 | 
			
		||||
			// Bake mesh for a copy and to apply the new UV's to.
 | 
			
		||||
			SkinnedMeshRenderer skinnedMeshRenderer = model.GetComponent<SkinnedMeshRenderer>();
 | 
			
		||||
			skinnedMeshRenderer.BakeMesh(mesh);
 | 
			
		||||
			mesh.RecalculateBounds();
 | 
			
		||||
 | 
			
		||||
            mesh.uv3 = mesh.BakePositionUVs(animationInfo);
 | 
			
		||||
			mesh.uv3 = mesh.BakePositionUVs(animationInfo);
 | 
			
		||||
 | 
			
		||||
            BakedData bakedData = new BakedData()
 | 
			
		||||
            {
 | 
			
		||||
                mesh = mesh,
 | 
			
		||||
                positionMaps = new List<Texture2D>() { BakePositionMap(model, animationClip, animationInfo) }
 | 
			
		||||
            };
 | 
			
		||||
			BakedData bakedData = new BakedData()
 | 
			
		||||
			{
 | 
			
		||||
				mesh = mesh,
 | 
			
		||||
				positionMaps = new List<Texture2D>() { BakePositionMap(model, animationClip, animationInfo) }
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
            return bakedData;
 | 
			
		||||
        }
 | 
			
		||||
			return bakedData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static Texture2D BakePositionMap(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo)
 | 
			
		||||
        {
 | 
			
		||||
            // Create positionMap Texture without MipMaps which is Linear and HDR to store values in a bigger range.
 | 
			
		||||
            Texture2D positionMap = new Texture2D(animationInfo.textureWidth, animationInfo.textureHeight, TextureFormat.RGBAHalf, false, true);
 | 
			
		||||
		public static Texture2D BakePositionMap(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo)
 | 
			
		||||
		{
 | 
			
		||||
			// Create positionMap Texture without MipMaps which is Linear and HDR to store values in a bigger range.
 | 
			
		||||
			Texture2D positionMap = new Texture2D(animationInfo.textureWidth, animationInfo.textureHeight, TextureFormat.RGBAHalf, false, true);
 | 
			
		||||
 | 
			
		||||
            // Create instance to sample from.
 | 
			
		||||
            GameObject inst = GameObject.Instantiate(model);
 | 
			
		||||
            SkinnedMeshRenderer skinnedMeshRenderer = inst.GetComponent<SkinnedMeshRenderer>();
 | 
			
		||||
			// Create instance to sample from.
 | 
			
		||||
			GameObject inst = GameObject.Instantiate(model);
 | 
			
		||||
			SkinnedMeshRenderer skinnedMeshRenderer = inst.GetComponent<SkinnedMeshRenderer>();
 | 
			
		||||
 | 
			
		||||
            int y = 0;
 | 
			
		||||
            for (int f = 0; f < animationInfo.frames; f++)
 | 
			
		||||
            {
 | 
			
		||||
                animationClip.SampleAnimation(inst, (animationClip.length / animationInfo.frames) * f);
 | 
			
		||||
			int y = 0;
 | 
			
		||||
			for (int f = 0; f < animationInfo.frames; f++)
 | 
			
		||||
			{
 | 
			
		||||
				animationClip.SampleAnimation(inst, (animationClip.length / animationInfo.frames) * f);
 | 
			
		||||
 | 
			
		||||
                Mesh sampledMesh = new Mesh();
 | 
			
		||||
                skinnedMeshRenderer.BakeMesh(sampledMesh);
 | 
			
		||||
                sampledMesh.RecalculateBounds();
 | 
			
		||||
				Mesh sampledMesh = new Mesh();
 | 
			
		||||
				skinnedMeshRenderer.BakeMesh(sampledMesh);
 | 
			
		||||
				sampledMesh.RecalculateBounds();
 | 
			
		||||
 | 
			
		||||
                int x = 0;
 | 
			
		||||
                for (int v = 0; v < sampledMesh.vertices.Length; v++)
 | 
			
		||||
                {
 | 
			
		||||
                    Vector3 vert = sampledMesh.vertices[v];
 | 
			
		||||
                    Vector3 normal = sampledMesh.normals[v];
 | 
			
		||||
				List<Vector3> verts = new List<Vector3>();
 | 
			
		||||
				sampledMesh.GetVertices(verts);
 | 
			
		||||
				List<Vector3> normals = new List<Vector3>();
 | 
			
		||||
				sampledMesh.GetNormals(normals);
 | 
			
		||||
 | 
			
		||||
                    positionMap.SetPixel(x, y,
 | 
			
		||||
                            new Color(vert.x, vert.y, vert.z,
 | 
			
		||||
                            VectorUtils.Float3ToFloat(normal))
 | 
			
		||||
                        );
 | 
			
		||||
				int x = 0;
 | 
			
		||||
				for (int v = 0; v < verts.Count; v++)
 | 
			
		||||
				{
 | 
			
		||||
					positionMap.SetPixel(x, y,
 | 
			
		||||
							new Color(verts[v].x, verts[v].y, verts[v].z,
 | 
			
		||||
							VectorUtils.Float3ToFloat(normals[v]))
 | 
			
		||||
						);
 | 
			
		||||
 | 
			
		||||
                    x++;
 | 
			
		||||
                    if (x >= animationInfo.textureWidth)
 | 
			
		||||
                    {
 | 
			
		||||
                        x = 0;
 | 
			
		||||
                        y++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                y += animationInfo.frameSpacing;
 | 
			
		||||
            }
 | 
			
		||||
					x++;
 | 
			
		||||
					if (x >= animationInfo.textureWidth)
 | 
			
		||||
					{
 | 
			
		||||
						x = 0;
 | 
			
		||||
						y++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				y += animationInfo.frameSpacing;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            GameObject.DestroyImmediate(inst);
 | 
			
		||||
			GameObject.DestroyImmediate(inst);
 | 
			
		||||
 | 
			
		||||
            positionMap.name = string.Format("VA_N-{0}_F-{1}_MF-{2}", animationClip.name, animationInfo.frames, animationInfo.maxFrames);
 | 
			
		||||
            positionMap.filterMode = FilterMode.Point;
 | 
			
		||||
            // TODO: Make no longer readable.
 | 
			
		||||
            positionMap.Apply(false, false);
 | 
			
		||||
			positionMap.name = string.Format("VA_N-{0}_F-{1}_MF-{2}_FPS-{3}", animationClip.name, animationInfo.frames, animationInfo.maxFrames, animationInfo.fps);
 | 
			
		||||
			positionMap.filterMode = FilterMode.Point;
 | 
			
		||||
			positionMap.Apply(false, true);
 | 
			
		||||
 | 
			
		||||
            return positionMap;
 | 
			
		||||
        }
 | 
			
		||||
			return positionMap;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static Vector2[] BakePositionUVs(this Mesh mesh, AnimationInfo animationInfo)
 | 
			
		||||
        {
 | 
			
		||||
            Vector2[] uv3 = new Vector2[mesh.vertices.Length];
 | 
			
		||||
		public static Vector2[] BakePositionUVs(this Mesh mesh, AnimationInfo animationInfo)
 | 
			
		||||
		{
 | 
			
		||||
			Vector2[] uv3 = new Vector2[mesh.vertexCount];
 | 
			
		||||
 | 
			
		||||
            float xOffset = 1.0f / animationInfo.textureWidth;
 | 
			
		||||
            float yOffset = 1.0f / animationInfo.textureHeight;
 | 
			
		||||
			float xOffset = 1.0f / animationInfo.textureWidth;
 | 
			
		||||
			float yOffset = 1.0f / animationInfo.textureHeight;
 | 
			
		||||
 | 
			
		||||
            float x = xOffset / 2.0f;
 | 
			
		||||
            float y = yOffset / 2.0f;
 | 
			
		||||
			float x = xOffset / 2.0f;
 | 
			
		||||
			float y = yOffset / 2.0f;
 | 
			
		||||
 | 
			
		||||
            for (int v = 0; v < mesh.vertices.Length; v++)
 | 
			
		||||
            {
 | 
			
		||||
                uv3[v] = new Vector2(x, y);
 | 
			
		||||
			for (int v = 0; v < uv3.Length; v++)
 | 
			
		||||
			{
 | 
			
		||||
				uv3[v] = new Vector2(x, y);
 | 
			
		||||
 | 
			
		||||
                x += xOffset;
 | 
			
		||||
                if (x >= 1.0f)
 | 
			
		||||
                {
 | 
			
		||||
                    x = xOffset / 2.0f;
 | 
			
		||||
                    y += yOffset;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				x += xOffset;
 | 
			
		||||
				if (x >= 1.0f)
 | 
			
		||||
				{
 | 
			
		||||
					x = xOffset / 2.0f;
 | 
			
		||||
					y += yOffset;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            mesh.uv3 = uv3;
 | 
			
		||||
			mesh.uv3 = uv3;
 | 
			
		||||
 | 
			
		||||
            return uv3;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
			return uv3;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								Runtime/Scripts/ModelBaker/AnimationMaterial.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Runtime/Scripts/ModelBaker/AnimationMaterial.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace TAO.VertexAnimation
 | 
			
		||||
{
 | 
			
		||||
	public static class AnimationMaterial
 | 
			
		||||
	{
 | 
			
		||||
		public static Material Create(string name, Shader shader)
 | 
			
		||||
		{
 | 
			
		||||
			Material material = new Material(shader)
 | 
			
		||||
			{
 | 
			
		||||
				name = name,
 | 
			
		||||
				enableInstancing = true
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			return material;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
fileFormatVersion: 2
 | 
			
		||||
guid: 6752e365d065458469473b601e74e699
 | 
			
		||||
guid: 2c06ab1e65507bd46925ac9091097b58
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
@@ -1,242 +1,247 @@
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
// References:
 | 
			
		||||
// https://forum.unity.com/threads/help-combining-and-manipulating-skinned-mesh-renderers-imported-from-blender.505078/
 | 
			
		||||
// http://wiki.unity3d.com/index.php/CombineSkinnedMeshes
 | 
			
		||||
// http://wiki.unity3d.com/index.php/SkinnedMeshCombiner
 | 
			
		||||
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace TAO.VertexAnimation
 | 
			
		||||
{
 | 
			
		||||
    public static class MeshCombiner
 | 
			
		||||
    {
 | 
			
		||||
        private struct MaterialMeshGroup
 | 
			
		||||
        {
 | 
			
		||||
            public List<SkinnedMeshRenderer> skinnedMeshes;
 | 
			
		||||
            public List<(MeshFilter mf, MeshRenderer mr)> meshes;
 | 
			
		||||
            public Material material;
 | 
			
		||||
        }
 | 
			
		||||
	public static class MeshCombiner
 | 
			
		||||
	{
 | 
			
		||||
		private struct MaterialMeshGroup
 | 
			
		||||
		{
 | 
			
		||||
			public List<SkinnedMeshRenderer> skinnedMeshes;
 | 
			
		||||
			public List<(MeshFilter mf, MeshRenderer mr)> meshes;
 | 
			
		||||
			public Material material;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static SkinnedMeshRenderer Combine(this SkinnedMeshRenderer target, List<SkinnedMeshRenderer> skinnedMeshes, List<(MeshFilter mf, MeshRenderer mr)> meshes)
 | 
			
		||||
        {
 | 
			
		||||
            List<MaterialMeshGroup> groups = new List<MaterialMeshGroup>();
 | 
			
		||||
		public static SkinnedMeshRenderer Combine(this SkinnedMeshRenderer target, List<SkinnedMeshRenderer> skinnedMeshes, List<(MeshFilter mf, MeshRenderer mr)> meshes)
 | 
			
		||||
		{
 | 
			
		||||
			List<MaterialMeshGroup> groups = new List<MaterialMeshGroup>();
 | 
			
		||||
 | 
			
		||||
            // Group skinnedMeshes.
 | 
			
		||||
            foreach (var sm in skinnedMeshes)
 | 
			
		||||
            {
 | 
			
		||||
                bool hasGroup = false;
 | 
			
		||||
                foreach (var g in groups)
 | 
			
		||||
                {
 | 
			
		||||
                    if (sm.sharedMaterial == g.material)
 | 
			
		||||
                    {
 | 
			
		||||
                        hasGroup = true;
 | 
			
		||||
                        g.skinnedMeshes.Add(sm);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
			// Group skinnedMeshes.
 | 
			
		||||
			foreach (var sm in skinnedMeshes)
 | 
			
		||||
			{
 | 
			
		||||
				bool hasGroup = false;
 | 
			
		||||
				foreach (var g in groups)
 | 
			
		||||
				{
 | 
			
		||||
					if (sm.sharedMaterial == g.material)
 | 
			
		||||
					{
 | 
			
		||||
						hasGroup = true;
 | 
			
		||||
						g.skinnedMeshes.Add(sm);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                if (!hasGroup)
 | 
			
		||||
                {
 | 
			
		||||
                    groups.Add(new MaterialMeshGroup()
 | 
			
		||||
                    { 
 | 
			
		||||
                        skinnedMeshes = new List<SkinnedMeshRenderer>()
 | 
			
		||||
                        {
 | 
			
		||||
                            sm
 | 
			
		||||
                        },
 | 
			
		||||
                        meshes = new List<(MeshFilter mf, MeshRenderer mr)>(),
 | 
			
		||||
                        material = sm.sharedMaterial
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				if (!hasGroup)
 | 
			
		||||
				{
 | 
			
		||||
					groups.Add(new MaterialMeshGroup()
 | 
			
		||||
					{ 
 | 
			
		||||
						skinnedMeshes = new List<SkinnedMeshRenderer>()
 | 
			
		||||
						{
 | 
			
		||||
							sm
 | 
			
		||||
						},
 | 
			
		||||
						meshes = new List<(MeshFilter mf, MeshRenderer mr)>(),
 | 
			
		||||
						material = sm.sharedMaterial
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // Group Meshes.
 | 
			
		||||
            foreach (var m in meshes)
 | 
			
		||||
            {
 | 
			
		||||
                bool hasGroup = false;
 | 
			
		||||
                foreach (var g in groups)
 | 
			
		||||
                {
 | 
			
		||||
                    if (m.mr.sharedMaterial == g.material)
 | 
			
		||||
                    {
 | 
			
		||||
                        hasGroup = true;
 | 
			
		||||
                        g.meshes.Add(m);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
			// Group Meshes.
 | 
			
		||||
			foreach (var m in meshes)
 | 
			
		||||
			{
 | 
			
		||||
				bool hasGroup = false;
 | 
			
		||||
				foreach (var g in groups)
 | 
			
		||||
				{
 | 
			
		||||
					if (m.mr.sharedMaterial == g.material)
 | 
			
		||||
					{
 | 
			
		||||
						hasGroup = true;
 | 
			
		||||
						g.meshes.Add(m);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                if (!hasGroup)
 | 
			
		||||
                {
 | 
			
		||||
                    groups.Add(new MaterialMeshGroup()
 | 
			
		||||
                    {
 | 
			
		||||
                        skinnedMeshes = new List<SkinnedMeshRenderer>(),
 | 
			
		||||
                        meshes = new List<(MeshFilter mf, MeshRenderer mr)>()
 | 
			
		||||
                        {
 | 
			
		||||
                            m
 | 
			
		||||
                        },
 | 
			
		||||
                        material = m.mr.sharedMaterial
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				if (!hasGroup)
 | 
			
		||||
				{
 | 
			
		||||
					groups.Add(new MaterialMeshGroup()
 | 
			
		||||
					{
 | 
			
		||||
						skinnedMeshes = new List<SkinnedMeshRenderer>(),
 | 
			
		||||
						meshes = new List<(MeshFilter mf, MeshRenderer mr)>()
 | 
			
		||||
						{
 | 
			
		||||
							m
 | 
			
		||||
						},
 | 
			
		||||
						material = m.mr.sharedMaterial
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            List<GameObject> tmp = new List<GameObject>();
 | 
			
		||||
            for (int i = 0; i < groups.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                tmp.Add(new GameObject("tmpChild", typeof(SkinnedMeshRenderer)));
 | 
			
		||||
                tmp[i].transform.parent = target.transform;
 | 
			
		||||
			List<GameObject> tmp = new List<GameObject>();
 | 
			
		||||
			for (int i = 0; i < groups.Count; i++)
 | 
			
		||||
			{
 | 
			
		||||
				tmp.Add(new GameObject("tmpChild", typeof(SkinnedMeshRenderer)));
 | 
			
		||||
				tmp[i].transform.parent = target.transform;
 | 
			
		||||
 | 
			
		||||
                MaterialMeshGroup mmg = groups[i];
 | 
			
		||||
                tmp[i].GetComponent<SkinnedMeshRenderer>().Combine(mmg.skinnedMeshes, mmg.meshes, mmg.material);
 | 
			
		||||
            }
 | 
			
		||||
				MaterialMeshGroup mmg = groups[i];
 | 
			
		||||
				tmp[i].GetComponent<SkinnedMeshRenderer>().Combine(mmg.skinnedMeshes, mmg.meshes, mmg.material);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // TODO: Merge materialMergedObjects.
 | 
			
		||||
            // TEMP: Remove when materialMergedObjects.
 | 
			
		||||
            SkinnedMeshRenderer newSkinnedMeshRenderer = tmp[0].GetComponent<SkinnedMeshRenderer>();
 | 
			
		||||
            target.sharedMesh = newSkinnedMeshRenderer.sharedMesh;
 | 
			
		||||
            target.sharedMaterial = newSkinnedMeshRenderer.sharedMaterial;
 | 
			
		||||
            target.bones = newSkinnedMeshRenderer.bones;
 | 
			
		||||
			// TODO: Merge materialMergedObjects.
 | 
			
		||||
			// TEMP: Remove when materialMergedObjects.
 | 
			
		||||
			SkinnedMeshRenderer newSkinnedMeshRenderer = tmp[0].GetComponent<SkinnedMeshRenderer>();
 | 
			
		||||
			target.sharedMesh = newSkinnedMeshRenderer.sharedMesh;
 | 
			
		||||
			target.sharedMaterial = newSkinnedMeshRenderer.sharedMaterial;
 | 
			
		||||
			target.bones = newSkinnedMeshRenderer.bones;
 | 
			
		||||
 | 
			
		||||
            foreach (var go in tmp)
 | 
			
		||||
            {
 | 
			
		||||
                GameObject.DestroyImmediate(go);
 | 
			
		||||
            }
 | 
			
		||||
			foreach (var go in tmp)
 | 
			
		||||
			{
 | 
			
		||||
				GameObject.DestroyImmediate(go);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // Set a name to make it more clear.
 | 
			
		||||
            target.sharedMesh.name = target.transform.name.Replace("(Clone)", "");
 | 
			
		||||
            return target;
 | 
			
		||||
        }
 | 
			
		||||
			// Set a name to make it more clear.
 | 
			
		||||
			target.sharedMesh.name = target.transform.name.Replace("(Clone)", "");
 | 
			
		||||
			return target;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static SkinnedMeshRenderer Combine(this SkinnedMeshRenderer target, List<SkinnedMeshRenderer> skinnedMeshes, List<(MeshFilter mf, MeshRenderer mr)> meshes, Material mainMaterial)
 | 
			
		||||
        {
 | 
			
		||||
            List<Transform> bones = new List<Transform>();
 | 
			
		||||
            List<BoneWeight> boneWeights = new List<BoneWeight>();
 | 
			
		||||
            List<Matrix4x4> bindPoses = new List<Matrix4x4>();
 | 
			
		||||
            List<CombineInstance> combineInstances = new List<CombineInstance>();
 | 
			
		||||
		public static SkinnedMeshRenderer Combine(this SkinnedMeshRenderer target, List<SkinnedMeshRenderer> skinnedMeshes, List<(MeshFilter mf, MeshRenderer mr)> meshes, Material mainMaterial)
 | 
			
		||||
		{
 | 
			
		||||
			List<Transform> bones = new List<Transform>();
 | 
			
		||||
			List<BoneWeight> boneWeights = new List<BoneWeight>();
 | 
			
		||||
			List<Matrix4x4> bindPoses = new List<Matrix4x4>();
 | 
			
		||||
			List<CombineInstance> combineInstances = new List<CombineInstance>();
 | 
			
		||||
 | 
			
		||||
            // Combine SkinnedMeshes.
 | 
			
		||||
            int boneOffset = 0;
 | 
			
		||||
            for (int s = 0; s < skinnedMeshes.Count; s++)
 | 
			
		||||
            {
 | 
			
		||||
                SkinnedMeshRenderer smr = skinnedMeshes[s];
 | 
			
		||||
			// Combine SkinnedMeshes.
 | 
			
		||||
			int boneOffset = 0;
 | 
			
		||||
			for (int s = 0; s < skinnedMeshes.Count; s++)
 | 
			
		||||
			{
 | 
			
		||||
				SkinnedMeshRenderer smr = skinnedMeshes[s];
 | 
			
		||||
 | 
			
		||||
                //if the skinned mesh renderer has a material other than the default
 | 
			
		||||
                //we assume it's a one-off face material and deal with it later
 | 
			
		||||
                if (smr.sharedMaterial != mainMaterial)
 | 
			
		||||
                {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
				//if the skinned mesh renderer has a material other than the default
 | 
			
		||||
				//we assume it's a one-off face material and deal with it later
 | 
			
		||||
				if (smr.sharedMaterial != mainMaterial)
 | 
			
		||||
				{
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                BoneWeight[] meshBoneweight = smr.sharedMesh.boneWeights;
 | 
			
		||||
				BoneWeight[] meshBoneweight = smr.sharedMesh.boneWeights;
 | 
			
		||||
 | 
			
		||||
                // May want to modify this if the renderer shares bones as unnecessary bones will get added.
 | 
			
		||||
                // We don't care since it is going to be converted into vertex animations later anyways.
 | 
			
		||||
                for (int i = 0; i < meshBoneweight.Length; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    BoneWeight bWeight = meshBoneweight[i];
 | 
			
		||||
				// May want to modify this if the renderer shares bones as unnecessary bones will get added.
 | 
			
		||||
				// We don't care since it is going to be converted into vertex animations later anyways.
 | 
			
		||||
				for (int i = 0; i < meshBoneweight.Length; ++i)
 | 
			
		||||
				{
 | 
			
		||||
					BoneWeight bWeight = meshBoneweight[i];
 | 
			
		||||
 | 
			
		||||
                    bWeight.boneIndex0 += boneOffset;
 | 
			
		||||
                    bWeight.boneIndex1 += boneOffset;
 | 
			
		||||
                    bWeight.boneIndex2 += boneOffset;
 | 
			
		||||
                    bWeight.boneIndex3 += boneOffset;
 | 
			
		||||
					bWeight.boneIndex0 += boneOffset;
 | 
			
		||||
					bWeight.boneIndex1 += boneOffset;
 | 
			
		||||
					bWeight.boneIndex2 += boneOffset;
 | 
			
		||||
					bWeight.boneIndex3 += boneOffset;
 | 
			
		||||
 | 
			
		||||
                    boneWeights.Add(bWeight);
 | 
			
		||||
                }
 | 
			
		||||
					boneWeights.Add(bWeight);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                boneOffset += smr.bones.Length;
 | 
			
		||||
				boneOffset += smr.bones.Length;
 | 
			
		||||
 | 
			
		||||
                Transform[] meshBones = smr.bones;
 | 
			
		||||
                for (int i = 0; i < meshBones.Length; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    bones.Add(meshBones[i]);
 | 
			
		||||
				Transform[] meshBones = smr.bones;
 | 
			
		||||
				for (int i = 0; i < meshBones.Length; ++i)
 | 
			
		||||
				{
 | 
			
		||||
					bones.Add(meshBones[i]);
 | 
			
		||||
 | 
			
		||||
                    //we take the old bind pose that mapped from our mesh to world to bone,
 | 
			
		||||
                    //and take out our localToWorldMatrix, so now it's JUST the bone matrix
 | 
			
		||||
                    //since our skinned mesh renderer is going to be on the root of our object that works
 | 
			
		||||
                    bindPoses.Add(smr.sharedMesh.bindposes[i] * smr.transform.worldToLocalMatrix);
 | 
			
		||||
                }
 | 
			
		||||
					//we take the old bind pose that mapped from our mesh to world to bone,
 | 
			
		||||
					//and take out our localToWorldMatrix, so now it's JUST the bone matrix
 | 
			
		||||
					//since our skinned mesh renderer is going to be on the root of our object that works
 | 
			
		||||
					bindPoses.Add(smr.sharedMesh.bindposes[i] * smr.transform.worldToLocalMatrix);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                CombineInstance ci = new CombineInstance
 | 
			
		||||
                {
 | 
			
		||||
                    mesh = smr.sharedMesh,
 | 
			
		||||
                    transform = smr.transform.localToWorldMatrix
 | 
			
		||||
                };
 | 
			
		||||
                combineInstances.Add(ci);
 | 
			
		||||
				CombineInstance ci = new CombineInstance
 | 
			
		||||
				{
 | 
			
		||||
					mesh = smr.sharedMesh,
 | 
			
		||||
					transform = smr.transform.localToWorldMatrix
 | 
			
		||||
				};
 | 
			
		||||
				combineInstances.Add(ci);
 | 
			
		||||
 | 
			
		||||
                GameObject.DestroyImmediate(smr);
 | 
			
		||||
            }
 | 
			
		||||
				GameObject.DestroyImmediate(smr);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // Combine Meshes.
 | 
			
		||||
            for (int s = 0; meshes != null && s < meshes.Count; s++)
 | 
			
		||||
            {
 | 
			
		||||
                MeshFilter filter = meshes[s].mf;
 | 
			
		||||
                MeshRenderer renderer = meshes[s].mr;
 | 
			
		||||
            
 | 
			
		||||
                //if the skinned mesh renderer has a material other than the default
 | 
			
		||||
                //we assume it's a one-off face material and deal with it later
 | 
			
		||||
                if (renderer.sharedMaterial != mainMaterial)
 | 
			
		||||
                {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
			// Combine Meshes.
 | 
			
		||||
			for (int s = 0; meshes != null && s < meshes.Count; s++)
 | 
			
		||||
			{
 | 
			
		||||
				MeshFilter filter = meshes[s].mf;
 | 
			
		||||
				MeshRenderer renderer = meshes[s].mr;
 | 
			
		||||
			
 | 
			
		||||
				//if the skinned mesh renderer has a material other than the default
 | 
			
		||||
				//we assume it's a one-off face material and deal with it later
 | 
			
		||||
				if (renderer.sharedMaterial != mainMaterial)
 | 
			
		||||
				{
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                // May want to modify this if the renderer shares bones as unnecessary bones will get added.
 | 
			
		||||
                // We don't care since it is going to be converted into vertex animations later anyways.
 | 
			
		||||
                int vertCount = filter.sharedMesh.vertexCount;
 | 
			
		||||
                for (int i = 0; i < vertCount; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    BoneWeight bWeight = new BoneWeight
 | 
			
		||||
                    {
 | 
			
		||||
                        boneIndex0 = boneOffset,
 | 
			
		||||
                        boneIndex1 = boneOffset,
 | 
			
		||||
                        boneIndex2 = boneOffset,
 | 
			
		||||
                        boneIndex3 = boneOffset,
 | 
			
		||||
                        weight0 = 1
 | 
			
		||||
                    };
 | 
			
		||||
				// May want to modify this if the renderer shares bones as unnecessary bones will get added.
 | 
			
		||||
				// We don't care since it is going to be converted into vertex animations later anyways.
 | 
			
		||||
				int vertCount = filter.sharedMesh.vertexCount;
 | 
			
		||||
				for (int i = 0; i < vertCount; ++i)
 | 
			
		||||
				{
 | 
			
		||||
					BoneWeight bWeight = new BoneWeight
 | 
			
		||||
					{
 | 
			
		||||
						boneIndex0 = boneOffset,
 | 
			
		||||
						boneIndex1 = boneOffset,
 | 
			
		||||
						boneIndex2 = boneOffset,
 | 
			
		||||
						boneIndex3 = boneOffset,
 | 
			
		||||
						weight0 = 1
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
                    boneWeights.Add(bWeight);
 | 
			
		||||
                }
 | 
			
		||||
					boneWeights.Add(bWeight);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                boneOffset += 1;
 | 
			
		||||
				boneOffset += 1;
 | 
			
		||||
 | 
			
		||||
                bones.Add(filter.transform);
 | 
			
		||||
				bones.Add(filter.transform);
 | 
			
		||||
 | 
			
		||||
                // TODO: figure out what this should be.
 | 
			
		||||
                bindPoses.Add(filter.transform.worldToLocalMatrix);
 | 
			
		||||
				// TODO: figure out what this should be.
 | 
			
		||||
				bindPoses.Add(filter.transform.worldToLocalMatrix);
 | 
			
		||||
 | 
			
		||||
                CombineInstance ci = new CombineInstance
 | 
			
		||||
                {
 | 
			
		||||
                    mesh = filter.sharedMesh,
 | 
			
		||||
                    transform = filter.transform.localToWorldMatrix
 | 
			
		||||
                };
 | 
			
		||||
                combineInstances.Add(ci);
 | 
			
		||||
				CombineInstance ci = new CombineInstance
 | 
			
		||||
				{
 | 
			
		||||
					mesh = filter.sharedMesh,
 | 
			
		||||
					transform = filter.transform.localToWorldMatrix
 | 
			
		||||
				};
 | 
			
		||||
				combineInstances.Add(ci);
 | 
			
		||||
 | 
			
		||||
                GameObject.DestroyImmediate(filter);
 | 
			
		||||
                GameObject.DestroyImmediate(renderer);
 | 
			
		||||
            }
 | 
			
		||||
				GameObject.DestroyImmediate(filter);
 | 
			
		||||
				GameObject.DestroyImmediate(renderer);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // Actually combine and recalculate mesh.
 | 
			
		||||
            Mesh skinnedMesh = new Mesh();
 | 
			
		||||
            skinnedMesh.CombineMeshes(combineInstances.ToArray(), true, true);
 | 
			
		||||
            skinnedMesh.RecalculateBounds();
 | 
			
		||||
			// Actually combine and recalculate mesh.
 | 
			
		||||
			Mesh skinnedMesh = new Mesh();
 | 
			
		||||
			skinnedMesh.CombineMeshes(combineInstances.ToArray(), true, true);
 | 
			
		||||
			skinnedMesh.RecalculateBounds();
 | 
			
		||||
 | 
			
		||||
            // Copy settings to target.
 | 
			
		||||
            target.sharedMesh = skinnedMesh;
 | 
			
		||||
            target.sharedMaterial = mainMaterial;
 | 
			
		||||
            target.bones = bones.ToArray();
 | 
			
		||||
            target.sharedMesh.boneWeights = boneWeights.ToArray();
 | 
			
		||||
            target.sharedMesh.bindposes = bindPoses.ToArray();
 | 
			
		||||
			// Copy settings to target.
 | 
			
		||||
			target.sharedMesh = skinnedMesh;
 | 
			
		||||
			target.sharedMaterial = mainMaterial;
 | 
			
		||||
			target.bones = bones.ToArray();
 | 
			
		||||
			target.sharedMesh.boneWeights = boneWeights.ToArray();
 | 
			
		||||
			target.sharedMesh.bindposes = bindPoses.ToArray();
 | 
			
		||||
 | 
			
		||||
            return target;
 | 
			
		||||
        }
 | 
			
		||||
			return target;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static void ConbineAndConvertGameObject(this GameObject gameObject)
 | 
			
		||||
        {
 | 
			
		||||
            // Get Skinned Meshes.
 | 
			
		||||
            List<SkinnedMeshRenderer> skinnedMeshes = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true).ToList();
 | 
			
		||||
            // Get Meshes.
 | 
			
		||||
            List<(MeshFilter, MeshRenderer)> meshes = new List<(MeshFilter, MeshRenderer)>();
 | 
			
		||||
            foreach (var mf in gameObject.GetComponentsInChildren<MeshFilter>(true))
 | 
			
		||||
            {
 | 
			
		||||
                if (mf.TryGetComponent(out MeshRenderer mr))
 | 
			
		||||
                {
 | 
			
		||||
                    meshes.Add((mf, mr));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
		public static void ConbineAndConvertGameObject(this GameObject gameObject)
 | 
			
		||||
		{
 | 
			
		||||
			// Get Skinned Meshes.
 | 
			
		||||
			List<SkinnedMeshRenderer> skinnedMeshes = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true).ToList();
 | 
			
		||||
			// Get Meshes.
 | 
			
		||||
			List<(MeshFilter, MeshRenderer)> meshes = new List<(MeshFilter, MeshRenderer)>();
 | 
			
		||||
			foreach (var mf in gameObject.GetComponentsInChildren<MeshFilter>(true))
 | 
			
		||||
			{
 | 
			
		||||
				if (mf.TryGetComponent(out MeshRenderer mr))
 | 
			
		||||
				{
 | 
			
		||||
					meshes.Add((mf, mr));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            // Add target mesh.
 | 
			
		||||
            SkinnedMeshRenderer target = gameObject.AddComponent<SkinnedMeshRenderer>();
 | 
			
		||||
            target.Combine(skinnedMeshes, meshes);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
			// Add target mesh.
 | 
			
		||||
			SkinnedMeshRenderer target = gameObject.AddComponent<SkinnedMeshRenderer>();
 | 
			
		||||
			target.Combine(skinnedMeshes, meshes);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace TAO.VertexAnimation
 | 
			
		||||
{
 | 
			
		||||
	[CreateAssetMenu(fileName = "new ModelBaker", menuName = "VA_ModelBaker/ModelBaker", order = 400)]
 | 
			
		||||
	public class VA_ModelBaker : ScriptableObject
 | 
			
		||||
	{
 | 
			
		||||
		public GameObject model;
 | 
			
		||||
		public AnimationClip[] animationClips;
 | 
			
		||||
		[Range(1, 60)]
 | 
			
		||||
		public int fps = 24;
 | 
			
		||||
		public int textureWidth = 512;
 | 
			
		||||
 | 
			
		||||
#if UNITY_EDITOR
 | 
			
		||||
		public bool saveBakedDataToAsset = true;
 | 
			
		||||
		public bool generateAnimationBook = true;
 | 
			
		||||
		public bool generatePrefab = true;
 | 
			
		||||
		public Shader materialShader = null;
 | 
			
		||||
 | 
			
		||||
		public GameObject prefab = null;
 | 
			
		||||
		public Material material = null;
 | 
			
		||||
		public VA_AnimationBook book = null;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		[SerializeField]
 | 
			
		||||
		private AnimationBaker.BakedData bakedData;
 | 
			
		||||
		public AnimationBaker.BakedData BakedData
 | 
			
		||||
        {
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return bakedData;
 | 
			
		||||
			}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Bake()
 | 
			
		||||
		{
 | 
			
		||||
			var target = Instantiate(model);
 | 
			
		||||
 | 
			
		||||
			target.ConbineAndConvertGameObject();
 | 
			
		||||
			bakedData = target.Bake(animationClips, fps, textureWidth);
 | 
			
		||||
 | 
			
		||||
			DestroyImmediate(target);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -3,173 +3,176 @@ using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace TAO.VertexAnimation
 | 
			
		||||
{
 | 
			
		||||
    [CreateAssetMenu(fileName = "new AnimationBook", menuName = "VA_Animation/AnimationBook", order = 400)]
 | 
			
		||||
    public class VA_AnimationBook : ScriptableObject
 | 
			
		||||
    {
 | 
			
		||||
        public PlayData playData = null;
 | 
			
		||||
	[CreateAssetMenu(fileName = "new AnimationBook", menuName = "VA_Animation/AnimationBook", order = 400)]
 | 
			
		||||
	public class VA_AnimationBook : ScriptableObject
 | 
			
		||||
	{
 | 
			
		||||
		public PlayData playData = null;
 | 
			
		||||
#if UNITY_EDITOR
 | 
			
		||||
        public EditorData editorData = new EditorData();
 | 
			
		||||
		public EditorData editorData = new EditorData();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        private void OnValidate()
 | 
			
		||||
        {
 | 
			
		||||
            // TODO: Check for naming conflicts and textures.
 | 
			
		||||
            // TODO: Debug message box instead of debug logs.
 | 
			
		||||
        }
 | 
			
		||||
		private void OnValidate()
 | 
			
		||||
		{
 | 
			
		||||
			// TODO: Check for naming conflicts and textures.
 | 
			
		||||
			// TODO: Debug message box instead of debug logs.
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public void SetMaterials()
 | 
			
		||||
        {
 | 
			
		||||
            if (playData.materials != null)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (Material mat in playData.materials)
 | 
			
		||||
                {
 | 
			
		||||
                    if (mat != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (mat.HasProperty("_MaxFrames"))
 | 
			
		||||
                        {
 | 
			
		||||
                            mat.SetFloat("_MaxFrames", playData.maxFrames);
 | 
			
		||||
                        }
 | 
			
		||||
		public void SetMaterials()
 | 
			
		||||
		{
 | 
			
		||||
			if (playData.materials != null)
 | 
			
		||||
			{
 | 
			
		||||
				foreach (Material mat in playData.materials)
 | 
			
		||||
				{
 | 
			
		||||
					if (mat != null)
 | 
			
		||||
					{
 | 
			
		||||
						if (mat.HasProperty("_MaxFrames"))
 | 
			
		||||
						{
 | 
			
		||||
							mat.SetFloat("_MaxFrames", playData.maxFrames);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
                        for (int i = 0; i < playData.texture2DArray.Count; i++)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (mat.HasProperty(playData.textureGroups[i].shaderParamName))
 | 
			
		||||
                            {
 | 
			
		||||
                                mat.SetTexture(playData.textureGroups[i].shaderParamName, playData.texture2DArray[i]);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
						for (int i = 0; i < playData.texture2DArray.Count; i++)
 | 
			
		||||
						{
 | 
			
		||||
							if (mat.HasProperty(playData.textureGroups[i].shaderParamName))
 | 
			
		||||
							{
 | 
			
		||||
								mat.SetTexture(playData.textureGroups[i].shaderParamName, playData.texture2DArray[i]);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        #region PlayData
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public class PlayData
 | 
			
		||||
        {
 | 
			
		||||
            public List<PlayTextureGroup> textureGroups = new List<PlayTextureGroup>();
 | 
			
		||||
            public List<PlayAnimationPage> animationPages = new List<PlayAnimationPage>();
 | 
			
		||||
		#region PlayData
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public class PlayData
 | 
			
		||||
		{
 | 
			
		||||
			public List<PlayTextureGroup> textureGroups = new List<PlayTextureGroup>();
 | 
			
		||||
			public List<PlayAnimationPage> animationPages = new List<PlayAnimationPage>();
 | 
			
		||||
 | 
			
		||||
            public int maxFrames;
 | 
			
		||||
            public Material[] materials;
 | 
			
		||||
            public List<Texture2DArray> texture2DArray = new List<Texture2DArray>();
 | 
			
		||||
			public int fps;
 | 
			
		||||
			public int maxFrames;
 | 
			
		||||
			public Material[] materials;
 | 
			
		||||
			public List<Texture2DArray> texture2DArray = new List<Texture2DArray>();
 | 
			
		||||
 | 
			
		||||
            // NOTE: for some reason FixedString32 data gets lost when entering play mode.
 | 
			
		||||
            // That is why this is here... and also the animationPages...
 | 
			
		||||
            public List<VA_AnimationData> GetAnimations
 | 
			
		||||
            {
 | 
			
		||||
                get
 | 
			
		||||
                {
 | 
			
		||||
                    List<VA_AnimationData> animations = new List<VA_AnimationData>();
 | 
			
		||||
                    foreach (var ap in animationPages)
 | 
			
		||||
                    {
 | 
			
		||||
                        animations.Add(new VA_AnimationData
 | 
			
		||||
                        {
 | 
			
		||||
                            name = ap.name,
 | 
			
		||||
                            frames = ap.frames,
 | 
			
		||||
                            maxFrames = maxFrames,
 | 
			
		||||
                            frameTime = 1.0f / maxFrames,
 | 
			
		||||
                            duration = 1.0f / maxFrames * ap.frames,
 | 
			
		||||
                            animationMapIndex = GetFirstAnimationMapIndex(in ap.textures, in textureGroups),
 | 
			
		||||
                            colorMapIndex = GetFirstColorMapIndex(in ap.textures, in textureGroups)
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    return animations;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
			// NOTE: for some reason FixedString32 data gets lost when entering play mode.
 | 
			
		||||
			// That is why this is here... and also the animationPages...
 | 
			
		||||
			public List<VA_AnimationData> GetAnimations
 | 
			
		||||
			{
 | 
			
		||||
				get
 | 
			
		||||
				{
 | 
			
		||||
					List<VA_AnimationData> animations = new List<VA_AnimationData>();
 | 
			
		||||
					foreach (var ap in animationPages)
 | 
			
		||||
					{
 | 
			
		||||
						animations.Add(new VA_AnimationData
 | 
			
		||||
						{
 | 
			
		||||
							name = ap.name,
 | 
			
		||||
							frames = ap.frames,
 | 
			
		||||
							maxFrames = maxFrames,
 | 
			
		||||
							frameTime = 1.0f / maxFrames * fps,
 | 
			
		||||
							// TODO: Frames -1 ?????
 | 
			
		||||
							duration = 1.0f / maxFrames * (ap.frames - 1),
 | 
			
		||||
							animationMapIndex = GetFirstAnimationMapIndex(in ap.textures, in textureGroups),
 | 
			
		||||
							colorMapIndex = GetFirstColorMapIndex(in ap.textures, in textureGroups)
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
					return animations;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            public static int GetFirstAnimationMapIndex(in List<PlayTextureEntry> textures, in List<PlayTextureGroup> textureGroups)
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < textureGroups.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    if (textureGroups[i].textureType == TextureType.AnimationMap)
 | 
			
		||||
                    {
 | 
			
		||||
                        return textures[i].textureArrayIndex;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
			public static int GetFirstAnimationMapIndex(in List<PlayTextureEntry> textures, in List<PlayTextureGroup> textureGroups)
 | 
			
		||||
			{
 | 
			
		||||
				for (int i = 0; i < textureGroups.Count; i++)
 | 
			
		||||
				{
 | 
			
		||||
					if (textureGroups[i].textureType == TextureType.AnimationMap)
 | 
			
		||||
					{
 | 
			
		||||
						return textures[i].textureArrayIndex;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
				return -1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            public static int GetFirstColorMapIndex(in List<PlayTextureEntry> textures, in List<PlayTextureGroup> textureGroups)
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < textureGroups.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    if (textureGroups[i].textureType == TextureType.ColorMap)
 | 
			
		||||
                    {
 | 
			
		||||
                        return textures[i].textureArrayIndex;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
			public static int GetFirstColorMapIndex(in List<PlayTextureEntry> textures, in List<PlayTextureGroup> textureGroups)
 | 
			
		||||
			{
 | 
			
		||||
				for (int i = 0; i < textureGroups.Count; i++)
 | 
			
		||||
				{
 | 
			
		||||
					if (textureGroups[i].textureType == TextureType.ColorMap)
 | 
			
		||||
					{
 | 
			
		||||
						return textures[i].textureArrayIndex;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
				return -1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct PlayAnimationPage
 | 
			
		||||
        {
 | 
			
		||||
            public string name;
 | 
			
		||||
            public int frames;
 | 
			
		||||
            public List<PlayTextureEntry> textures;
 | 
			
		||||
        }
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct PlayAnimationPage
 | 
			
		||||
		{
 | 
			
		||||
			public string name;
 | 
			
		||||
			public int frames;
 | 
			
		||||
			public List<PlayTextureEntry> textures;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct PlayTextureGroup
 | 
			
		||||
        {
 | 
			
		||||
            public string shaderParamName;
 | 
			
		||||
            public TextureType textureType;
 | 
			
		||||
        }
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct PlayTextureGroup
 | 
			
		||||
		{
 | 
			
		||||
			public string shaderParamName;
 | 
			
		||||
			public TextureType textureType;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct PlayTextureEntry
 | 
			
		||||
        {
 | 
			
		||||
            public int textureArrayIndex;
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct PlayTextureEntry
 | 
			
		||||
		{
 | 
			
		||||
			public int textureArrayIndex;
 | 
			
		||||
		}
 | 
			
		||||
		#endregion
 | 
			
		||||
 | 
			
		||||
        #region EditorData
 | 
			
		||||
		#region EditorData
 | 
			
		||||
#if UNITY_EDITOR
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public class EditorData
 | 
			
		||||
        {
 | 
			
		||||
            public List<EditorTextureGroup> textureGroups = new List<EditorTextureGroup>() { new EditorTextureGroup { shaderParamName = "_PositionMap", textureType = TextureType.AnimationMap, wrapMode = TextureWrapMode.Repeat, filterMode = FilterMode.Point, isLinear = false } };
 | 
			
		||||
            public List<EditorAnimationPage> animationPages = new List<EditorAnimationPage>();
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public class EditorData
 | 
			
		||||
		{
 | 
			
		||||
			public List<EditorTextureGroup> textureGroups = new List<EditorTextureGroup>() { new EditorTextureGroup { shaderParamName = "_PositionMap", textureType = TextureType.AnimationMap, wrapMode = TextureWrapMode.Repeat, filterMode = FilterMode.Point, isLinear = false } };
 | 
			
		||||
			public List<EditorAnimationPage> animationPages = new List<EditorAnimationPage>();
 | 
			
		||||
 | 
			
		||||
            public int maxFrames;
 | 
			
		||||
            public Material[] materials;
 | 
			
		||||
            public List<Texture2DArray> texture2DArray = null;
 | 
			
		||||
        }
 | 
			
		||||
			public int fps;
 | 
			
		||||
			public int maxFrames;
 | 
			
		||||
			public Material[] materials;
 | 
			
		||||
			public List<Texture2DArray> texture2DArray = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct EditorAnimationPage
 | 
			
		||||
        {
 | 
			
		||||
            public string name;
 | 
			
		||||
            public int frames;
 | 
			
		||||
            public List<EditorTextureEntry> textures;
 | 
			
		||||
        }
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct EditorAnimationPage
 | 
			
		||||
		{
 | 
			
		||||
			public string name;
 | 
			
		||||
			public int frames;
 | 
			
		||||
			public List<EditorTextureEntry> textures;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public struct EditorTextureGroup
 | 
			
		||||
        {
 | 
			
		||||
            public string shaderParamName;
 | 
			
		||||
            public TextureType textureType;
 | 
			
		||||
            public TextureWrapMode wrapMode;
 | 
			
		||||
            public FilterMode filterMode;
 | 
			
		||||
            public bool isLinear;
 | 
			
		||||
        }
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public struct EditorTextureGroup
 | 
			
		||||
		{
 | 
			
		||||
			public string shaderParamName;
 | 
			
		||||
			public TextureType textureType;
 | 
			
		||||
			public TextureWrapMode wrapMode;
 | 
			
		||||
			public FilterMode filterMode;
 | 
			
		||||
			public bool isLinear;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        [System.Serializable]
 | 
			
		||||
        public class EditorTextureEntry
 | 
			
		||||
        {
 | 
			
		||||
            public Texture2D texture2D = null;
 | 
			
		||||
            public int textureArrayIndex = -1;
 | 
			
		||||
        }
 | 
			
		||||
		[System.Serializable]
 | 
			
		||||
		public class EditorTextureEntry
 | 
			
		||||
		{
 | 
			
		||||
			public Texture2D texture2D = null;
 | 
			
		||||
			public int textureArrayIndex = -1;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
        #endregion
 | 
			
		||||
		#endregion
 | 
			
		||||
 | 
			
		||||
        public enum TextureType
 | 
			
		||||
        {
 | 
			
		||||
            AnimationMap,
 | 
			
		||||
            ColorMap
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		public enum TextureType
 | 
			
		||||
		{
 | 
			
		||||
			AnimationMap,
 | 
			
		||||
			ColorMap
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace TAO.VertexAnimation
 | 
			
		||||
					// Set all the data.
 | 
			
		||||
					BlobBuilderArray<VA_AnimationData> animationDataArray = blobBuilder.Allocate(ref animationDataBlobAsset.animations, animationLib.animationLibrary.animations.Count);
 | 
			
		||||
 | 
			
		||||
                    for (int i = 0; i < animationDataArray.Length; i++)
 | 
			
		||||
					for (int i = 0; i < animationDataArray.Length; i++)
 | 
			
		||||
					{
 | 
			
		||||
						// Copy data.
 | 
			
		||||
						animationDataArray[i] = animationLib.animationLibrary.animations[i];
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ namespace TAO.VertexAnimation
 | 
			
		||||
		public int frames;
 | 
			
		||||
		// The maximum of frames the texture holds.
 | 
			
		||||
		public int maxFrames;
 | 
			
		||||
		// 1.0f / maxFrames.
 | 
			
		||||
		// 1.0f / fps.
 | 
			
		||||
		public float frameTime;
 | 
			
		||||
		// FrameTime * frames.
 | 
			
		||||
		public float duration;
 | 
			
		||||
@@ -27,27 +27,27 @@ namespace TAO.VertexAnimation
 | 
			
		||||
		public BlobArray<VA_AnimationData> animations;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public static class VA_AnimationLibraryUtils
 | 
			
		||||
	public static class VA_AnimationLibraryUtils
 | 
			
		||||
	{
 | 
			
		||||
		public const string AnimationLibraryAssetStoreName = "VA_AnimationLibrary";
 | 
			
		||||
 | 
			
		||||
        public static int GetAnimation(ref VA_AnimationLibraryData animationsRef, FixedString32 animationName)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < animationsRef.animations.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (animationsRef.animations[i].name == animationName)
 | 
			
		||||
                {
 | 
			
		||||
                    return i;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static int GetAnimationMapIndex(ref VA_AnimationLibraryData animationsRef, int animation)
 | 
			
		||||
		public static int GetAnimation(ref VA_AnimationLibraryData animationsRef, FixedString32 animationName)
 | 
			
		||||
		{
 | 
			
		||||
            return animationsRef.animations[animation].animationMapIndex;
 | 
			
		||||
        }
 | 
			
		||||
			for (int i = 0; i < animationsRef.animations.Length; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (animationsRef.animations[i].name == animationName)
 | 
			
		||||
				{
 | 
			
		||||
					return i;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static int GetAnimationMapIndex(ref VA_AnimationLibraryData animationsRef, int animation)
 | 
			
		||||
		{
 | 
			
		||||
			return animationsRef.animations[animation].animationMapIndex;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static int GetColorMapIndex(ref VA_AnimationLibraryData animationsRef, int animation)
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
@@ -51,9 +51,9 @@ namespace TAO.VertexAnimation
 | 
			
		||||
					Entity ent = GetPrimaryEntity(children[i]);
 | 
			
		||||
				
 | 
			
		||||
					VA_AnimationDataComponent animationData = new VA_AnimationDataComponent();
 | 
			
		||||
                    DstEntityManager.AddComponentData(ent, animationData);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
					DstEntityManager.AddComponentData(ent, animationData);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,104 +2,104 @@
 | 
			
		||||
 | 
			
		||||
namespace TAO.VertexAnimation
 | 
			
		||||
{
 | 
			
		||||
    public static class VA_Texture2DArrayUtils
 | 
			
		||||
    {
 | 
			
		||||
        public static Texture2DArray CreateTextureArray(Texture2D[] a_textures, bool a_useMipChain, bool a_isLinear,
 | 
			
		||||
            TextureWrapMode a_wrapMode = TextureWrapMode.Repeat, FilterMode a_filterMode = FilterMode.Bilinear, int a_anisoLevel = 1, string a_name = "")
 | 
			
		||||
        {
 | 
			
		||||
            if(!IsValidForTextureArray(a_textures) || !IsValidCopyTexturePlatform())
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
	public static class VA_Texture2DArrayUtils
 | 
			
		||||
	{
 | 
			
		||||
		public static Texture2DArray CreateTextureArray(Texture2D[] a_textures, bool a_useMipChain, bool a_isLinear,
 | 
			
		||||
			TextureWrapMode a_wrapMode = TextureWrapMode.Repeat, FilterMode a_filterMode = FilterMode.Bilinear, int a_anisoLevel = 1, string a_name = "")
 | 
			
		||||
		{
 | 
			
		||||
			if(!IsValidForTextureArray(a_textures) || !IsValidCopyTexturePlatform())
 | 
			
		||||
			{
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            Texture2DArray textureArray = new Texture2DArray(a_textures[0].width, a_textures[0].height, a_textures.Length, a_textures[0].format, a_useMipChain, a_isLinear);
 | 
			
		||||
			Texture2DArray textureArray = new Texture2DArray(a_textures[0].width, a_textures[0].height, a_textures.Length, a_textures[0].format, a_useMipChain, a_isLinear);
 | 
			
		||||
 | 
			
		||||
            if (IsValidCopyTexturePlatform())
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < a_textures.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    Graphics.CopyTexture(a_textures[i], 0, 0, textureArray, i, 0);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
			if (IsValidCopyTexturePlatform())
 | 
			
		||||
			{
 | 
			
		||||
				for (int i = 0; i < a_textures.Length; i++)
 | 
			
		||||
				{
 | 
			
		||||
					Graphics.CopyTexture(a_textures[i], 0, 0, textureArray, i, 0);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            textureArray.wrapMode = a_wrapMode;
 | 
			
		||||
            textureArray.filterMode = a_filterMode;
 | 
			
		||||
            textureArray.anisoLevel = a_anisoLevel;
 | 
			
		||||
            textureArray.name = a_name;
 | 
			
		||||
			textureArray.wrapMode = a_wrapMode;
 | 
			
		||||
			textureArray.filterMode = a_filterMode;
 | 
			
		||||
			textureArray.anisoLevel = a_anisoLevel;
 | 
			
		||||
			textureArray.name = a_name;
 | 
			
		||||
 | 
			
		||||
            textureArray.Apply(false, false);
 | 
			
		||||
			textureArray.Apply(false, false);
 | 
			
		||||
 | 
			
		||||
            return textureArray;
 | 
			
		||||
        }
 | 
			
		||||
			return textureArray;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static bool IsValidForTextureArray(Texture2D[] a_textures)
 | 
			
		||||
        {
 | 
			
		||||
            if (a_textures == null || a_textures.Length <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                Debug.LogError("No textures assigned!");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
		public static bool IsValidForTextureArray(Texture2D[] a_textures)
 | 
			
		||||
		{
 | 
			
		||||
			if (a_textures == null || a_textures.Length <= 0)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.LogError("No textures assigned!");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < a_textures.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (a_textures[i] == null)
 | 
			
		||||
                {
 | 
			
		||||
                    Debug.LogError("Texture " + i.ToString() + " not assigned!");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
			for (int i = 0; i < a_textures.Length; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (a_textures[i] == null)
 | 
			
		||||
				{
 | 
			
		||||
					Debug.LogError("Texture " + i.ToString() + " not assigned!");
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                if (a_textures[0].width != a_textures[i].width || a_textures[0].height != a_textures[i].height)
 | 
			
		||||
                {
 | 
			
		||||
                    Debug.LogError("Texture " + a_textures[i].name + " has a different size!");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
				if (a_textures[0].width != a_textures[i].width || a_textures[0].height != a_textures[i].height)
 | 
			
		||||
				{
 | 
			
		||||
					Debug.LogError("Texture " + a_textures[i].name + " has a different size!");
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                if (a_textures[0].format != a_textures[i].format || a_textures[0].graphicsFormat != a_textures[i].graphicsFormat)
 | 
			
		||||
                {
 | 
			
		||||
                    Debug.LogError("Texture " + a_textures[i].name + " has a different format/graphics format!");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
				if (a_textures[0].format != a_textures[i].format || a_textures[0].graphicsFormat != a_textures[i].graphicsFormat)
 | 
			
		||||
				{
 | 
			
		||||
					Debug.LogError("Texture " + a_textures[i].name + " has a different format/graphics format!");
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                if (!a_textures[0].isReadable)
 | 
			
		||||
                {
 | 
			
		||||
				if (!a_textures[0].isReadable)
 | 
			
		||||
				{
 | 
			
		||||
#if UNITY_EDITOR
 | 
			
		||||
                    //Debug.LogWarning("Texture " + a_textures[i].name + " is not readable!");
 | 
			
		||||
                    return true;
 | 
			
		||||
					//Debug.LogWarning("Texture " + a_textures[i].name + " is not readable!");
 | 
			
		||||
					return true;
 | 
			
		||||
#else
 | 
			
		||||
                    Debug.LogError("Texture " + a_textures[i].name + " is not readable!");
 | 
			
		||||
                    return false;
 | 
			
		||||
					Debug.LogError("Texture " + a_textures[i].name + " is not readable!");
 | 
			
		||||
					return false;
 | 
			
		||||
#endif
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public static bool IsValidCopyTexturePlatform()
 | 
			
		||||
        {
 | 
			
		||||
            switch (SystemInfo.copyTextureSupport)
 | 
			
		||||
            {
 | 
			
		||||
                case UnityEngine.Rendering.CopyTextureSupport.None:
 | 
			
		||||
                    Debug.LogError("No CopyTextureSupport on this platform!");
 | 
			
		||||
                    return false;
 | 
			
		||||
                case UnityEngine.Rendering.CopyTextureSupport.Basic:
 | 
			
		||||
                    return true;
 | 
			
		||||
                case UnityEngine.Rendering.CopyTextureSupport.Copy3D:
 | 
			
		||||
                    return true;
 | 
			
		||||
                case UnityEngine.Rendering.CopyTextureSupport.DifferentTypes:
 | 
			
		||||
                    return true;
 | 
			
		||||
                case UnityEngine.Rendering.CopyTextureSupport.TextureToRT:
 | 
			
		||||
                    return true;
 | 
			
		||||
                case UnityEngine.Rendering.CopyTextureSupport.RTToTexture:
 | 
			
		||||
                    return true;
 | 
			
		||||
                default:
 | 
			
		||||
		public static bool IsValidCopyTexturePlatform()
 | 
			
		||||
		{
 | 
			
		||||
			switch (SystemInfo.copyTextureSupport)
 | 
			
		||||
			{
 | 
			
		||||
				case UnityEngine.Rendering.CopyTextureSupport.None:
 | 
			
		||||
					Debug.LogError("No CopyTextureSupport on this platform!");
 | 
			
		||||
					return false;
 | 
			
		||||
				case UnityEngine.Rendering.CopyTextureSupport.Basic:
 | 
			
		||||
					return true;
 | 
			
		||||
				case UnityEngine.Rendering.CopyTextureSupport.Copy3D:
 | 
			
		||||
					return true;
 | 
			
		||||
				case UnityEngine.Rendering.CopyTextureSupport.DifferentTypes:
 | 
			
		||||
					return true;
 | 
			
		||||
				case UnityEngine.Rendering.CopyTextureSupport.TextureToRT:
 | 
			
		||||
					return true;
 | 
			
		||||
				case UnityEngine.Rendering.CopyTextureSupport.RTToTexture:
 | 
			
		||||
					return true;
 | 
			
		||||
				default:
 | 
			
		||||
#if UNITY_EDITOR
 | 
			
		||||
                    return true;
 | 
			
		||||
					return true;
 | 
			
		||||
#else
 | 
			
		||||
                    Debug.LogError("No CopyTextureSupport on this platform!");
 | 
			
		||||
                    return false;
 | 
			
		||||
					Debug.LogError("No CopyTextureSupport on this platform!");
 | 
			
		||||
					return false;
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user