private static void AddAnimation(PETFile pet, GameObject gameObject) { Animation animation = gameObject.AddComponent <Animation>(); animation.AddClip(AnimationHelper.CreateAnimationClip(pet), "test"); animation.Play("test"); }
private static void AddRenderer(PETFile pet, GameObject gameObject, string textureSearchPath) { SkinnedMeshRenderer renderer = gameObject.AddComponent <SkinnedMeshRenderer>(); renderer.materials = MaterialHelper.CreateMaterials(pet.Textures, textureSearchPath); renderer.sharedMesh = MeshHelper.CreateMesh(pet); renderer.bones = BoneHelper.CreateBones(pet.Bones, gameObject); }
// array size is vertex count private static BoneWeight[] CreateBoneWeights(PETFile pet) { int uniqueVertexCount = pet.Vertices.Count; // create unique vertices with the index used in the polygons BoneWeight[] uniqueBoneWeights = new BoneWeight[uniqueVertexCount]; for (int i = 0; i < uniqueVertexCount; i++) { List <BoneInformation> boneInformationList = pet.Vertices[i].BoneInformation; // TODO meh for (int index = 0; index < boneInformationList.Count; index++) { BoneInformation boneInformation = boneInformationList[index]; switch (index) { case 0: uniqueBoneWeights[i].boneIndex0 = boneInformation.BoneID; uniqueBoneWeights[i].weight0 = boneInformation.Weight; break; case 1: uniqueBoneWeights[i].boneIndex1 = boneInformation.BoneID; uniqueBoneWeights[i].weight1 = boneInformation.Weight; break; case 2: uniqueBoneWeights[i].boneIndex2 = boneInformation.BoneID; uniqueBoneWeights[i].weight2 = boneInformation.Weight; break; case 3: uniqueBoneWeights[i].boneIndex3 = boneInformation.BoneID; uniqueBoneWeights[i].weight3 = boneInformation.Weight; break; default: throw new NotSupportedException( "Unity only supports 4 different weights for a single bone"); } } } BoneWeight[] boneWeights = pet.Polygons .SelectMany(polygon => polygon.PolygonIndices) .Select(polygonIndex => uniqueBoneWeights[polygonIndex.Index]) .ToArray(); return(boneWeights); }
// array size is vertex count private static Vector3[] CreateVertices(PETFile pet) { // create unique vertices with the index used in the polygons Vector3[] uniqueVertices = pet.Vertices .Select(vertex => new Vector3(vertex.X, vertex.Y, vertex.Z)) .ToArray(); // every unique vertex can appear multiple times in a model (at points where polygons touch each other) Vector3[] vertices = pet.Polygons .SelectMany(polygon => polygon.PolygonIndices) .Select(polygonIndex => uniqueVertices[polygonIndex.Index]) .ToArray(); return(vertices); }
public static GameObject CreateGameObjectFromPet(string petFilePath, string textureSearchPath) { PETFile pet = new PETFile(petFilePath); GameObject gameObject = new GameObject { name = Path.GetFileName(petFilePath) ?? throw new InvalidOperationException("Please specify a PET file which should be initialized") }; AddRenderer(pet, gameObject, textureSearchPath); AddAnimation(pet, gameObject); return(gameObject); }
// same size as Materials array private static Dictionary <int, List <int> > CreateTrianglesByTextureIndex(PETFile pet) { // create lists because we don't know beforehand how many textures will be in a submesh Dictionary <int, List <int> > trianglesByTextureIndex = Enumerable.Range(0, pet.Textures.Count) .ToDictionary(i => i, _ => new List <int>()); for (int i = 0; i < pet.Polygons.Count; i++) { Polygon polygon = pet.Polygons[i]; for (int j = 0; j < 3; j++) { int targetIndex = i * 3 + j; int textureIndex = (int)polygon.TextureIndex; trianglesByTextureIndex[textureIndex].Add(targetIndex); } } return(trianglesByTextureIndex); }
public static AnimationClip CreateAnimationClip(PETFile pet) { AnimationClip clip = new AnimationClip { legacy = true, wrapMode = WrapMode.Loop }; foreach (Animation anim in pet.Animations) { // TODO AnimationFlags string boneName = pet.Bones[anim.BoneID].Name; AddPositionDataToClip(anim.PositionData, boneName, clip); AddRotationDataToClip(anim.RotationData, boneName, clip); AddScalingDataToClip(anim.ScalingData, boneName, clip); } return(clip); }
public static Mesh CreateMesh(PETFile pet) { Mesh mesh = new Mesh { vertices = CreateVertices(pet), boneWeights = CreateBoneWeights(pet), bindposes = CreateBindPoses(pet.Bones) }; Dictionary <int, Vector2[]> uvsById = CreateUvsById(pet.Polygons); for (int i = 0; i < uvsById.Count; i++) { switch (i) { case 0: mesh.uv = uvsById[i]; break; case 1: mesh.uv2 = uvsById[i]; break; default: throw new NotImplementedException("Currently only two UV mappings are supported"); } } Dictionary <int, List <int> > trianglesByTextureIndex = CreateTrianglesByTextureIndex(pet); mesh.subMeshCount = trianglesByTextureIndex.Count; for (int i = 0; i < mesh.subMeshCount; i++) { mesh.SetTriangles(trianglesByTextureIndex[i].ToArray(), i); } return(mesh); }