public Mesh Clone(AssetCabinet file) { file.MergeTypeDefinition(this.file, UnityClassID.Mesh); Mesh mesh = new Mesh(file); using (MemoryStream mem = new MemoryStream()) { WriteTo(mem); mem.Position = 0; mesh.LoadFrom(mem); } return mesh; }
public dynamic LoadComponent(Stream stream, int index, NotLoaded comp) { stream.Position = comp.offset; try { switch (comp.classID1) { case UnityClassID.AnimationClip: { AnimationClip animationClip = new AnimationClip(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, animationClip, comp); animationClip.LoadFrom(stream); return animationClip; } case UnityClassID.Animator: { Animator animator = new Animator(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, animator, comp); animator.LoadFrom(stream); return animator; } case UnityClassID.AnimatorController: { AnimatorController animatorController = new AnimatorController(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, animatorController, comp); animatorController.LoadFrom(stream); return animatorController; } case UnityClassID.AssetBundle: { AssetBundle assetBundle = new AssetBundle(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, assetBundle, comp); assetBundle.LoadFrom(stream); return assetBundle; } case UnityClassID.AudioClip: { if (loadingReferencials) { return comp; } AudioClip ac = new AudioClip(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, ac, comp); ac.LoadFrom(stream); return ac; } case UnityClassID.AudioListener: { AudioListener audioListener = new AudioListener(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, audioListener, comp); audioListener.LoadFrom(stream); return audioListener; } case UnityClassID.AudioSource: { AudioSource audioSrc = new AudioSource(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, audioSrc, comp); audioSrc.LoadFrom(stream); return audioSrc; } case UnityClassID.Avatar: { if (loadingReferencials) { return comp; } Avatar avatar = new Avatar(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, avatar, comp); avatar.LoadFrom(stream); return avatar; } case UnityClassID.BoxCollider: { BoxCollider boxCol = new BoxCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, boxCol, comp); boxCol.LoadFrom(stream); return boxCol; } case UnityClassID.Camera: { Camera camera = new Camera(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, camera, comp); camera.LoadFrom(stream); return camera; } case UnityClassID.CapsuleCollider: { CapsuleCollider capsuleCol = new CapsuleCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, capsuleCol, comp); capsuleCol.LoadFrom(stream); return capsuleCol; } case UnityClassID.Cubemap: { Cubemap cubemap = new Cubemap(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, cubemap, comp); cubemap.LoadFrom(stream); Parser.Textures.Add(cubemap); return cubemap; } case UnityClassID.EllipsoidParticleEmitter: { EllipsoidParticleEmitter ellipsoid = new EllipsoidParticleEmitter(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, ellipsoid, comp); ellipsoid.LoadFrom(stream); return ellipsoid; } case UnityClassID.FlareLayer: { FlareLayer flareLayer = new FlareLayer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, flareLayer, comp); flareLayer.LoadFrom(stream); return flareLayer; } case UnityClassID.Light: { Light light = new Light(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, light, comp); light.LoadFrom(stream); return light; } case UnityClassID.LinkToGameObject: { LinkToGameObject link = new LinkToGameObject(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, link, comp); link.LoadFrom(stream); return link; } case UnityClassID.LinkToGameObject223: { LinkToGameObject223 link = new LinkToGameObject223(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, link, comp); link.LoadFrom(stream); return link; } case UnityClassID.LinkToGameObject225: { LinkToGameObject225 link = new LinkToGameObject225(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, link, comp); link.LoadFrom(stream); return link; } case UnityClassID.GameObject: { GameObject gameObj = new GameObject(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, gameObj, comp); gameObj.LoadFrom(stream); return gameObj; } case UnityClassID.Material: { Material mat = new Material(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, mat, comp); mat.LoadFrom(stream); return mat; } case UnityClassID.Mesh: { if (loadingReferencials) { return comp; } Mesh mesh = new Mesh(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, mesh, comp); mesh.LoadFrom(stream); return mesh; } case UnityClassID.MeshCollider: { MeshCollider meshCol = new MeshCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, meshCol, comp); meshCol.LoadFrom(stream); return meshCol; } case UnityClassID.MeshFilter: { MeshFilter meshFilter = new MeshFilter(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, meshFilter, comp); meshFilter.LoadFrom(stream); return meshFilter; } case UnityClassID.MeshRenderer: { MeshRenderer meshRenderer = new MeshRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, meshRenderer, comp); meshRenderer.LoadFrom(stream); return meshRenderer; } default: if (comp.classID2 == UnityClassID.MonoBehaviour) { if (Types.Count > 0) { MonoBehaviour monoBehaviour = new MonoBehaviour(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, monoBehaviour, comp); monoBehaviour.LoadFrom(stream); return monoBehaviour; } else { string message = comp.classID2 + " unhandled because of absence of Types in Cabinet (*.assets)"; if (!reported.Contains(message)) { Report.ReportLog(message); reported.Add(message); } return comp; } } else { string message = "Unhandled class: " + comp.classID1 + "/" + comp.classID2; if (!reported.Contains(message)) { Report.ReportLog(message); reported.Add(message); } } break; case UnityClassID.MonoScript: { if (loadingReferencials) { return comp; } MonoScript monoScript = new MonoScript(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, monoScript, comp); monoScript.LoadFrom(stream); return monoScript; } case UnityClassID.MultiLink: { MultiLink multi = new MultiLink(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, multi, comp); multi.LoadFrom(stream); return multi; } case UnityClassID.ParticleAnimator: { ParticleAnimator particleAnimator = new ParticleAnimator(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleAnimator, comp); particleAnimator.LoadFrom(stream); return particleAnimator; } case UnityClassID.ParticleRenderer: { ParticleRenderer particleRenderer = new ParticleRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleRenderer, comp); particleRenderer.LoadFrom(stream); return particleRenderer; } case UnityClassID.ParticleSystem: { ParticleSystem particleSystem = new ParticleSystem(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleSystem, comp); particleSystem.LoadFrom(stream); return particleSystem; } case UnityClassID.ParticleSystemRenderer: { ParticleSystemRenderer particleSystemRenderer = new ParticleSystemRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, particleSystemRenderer, comp); particleSystemRenderer.LoadFrom(stream); return particleSystemRenderer; } case UnityClassID.Projector: { Projector projector = new Projector(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, projector, comp); projector.LoadFrom(stream); return projector; } case UnityClassID.Rigidbody: { RigidBody rigidBody = new RigidBody(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, rigidBody, comp); rigidBody.LoadFrom(stream); return rigidBody; } case UnityClassID.Shader: { Shader shader = new Shader(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, shader, comp); shader.LoadFrom(stream); return shader; } case UnityClassID.SkinnedMeshRenderer: { SkinnedMeshRenderer sMesh = new SkinnedMeshRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, sMesh, comp); sMesh.LoadFrom(stream); return sMesh; } case UnityClassID.SphereCollider: { SphereCollider sphereCol = new SphereCollider(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, sphereCol, comp); sphereCol.LoadFrom(stream); return sphereCol; } case UnityClassID.Sprite: { Sprite sprite = new Sprite(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, sprite, comp); sprite.LoadFrom(stream); return sprite; } case UnityClassID.SpriteRenderer: { SpriteRenderer spriteRenderer = new SpriteRenderer(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, spriteRenderer, comp); spriteRenderer.LoadFrom(stream); return spriteRenderer; } case UnityClassID.TextAsset: { if (loadingReferencials) { return comp; } TextAsset ta = new TextAsset(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, ta, comp); ta.LoadFrom(stream); return ta; } case UnityClassID.Texture2D: { if (loadingReferencials) { return comp; } Texture2D tex = new Texture2D(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, tex, comp); tex.LoadFrom(stream); Parser.Textures.Add(tex); return tex; } case UnityClassID.Transform: { Transform trans = new Transform(this, comp.pathID, comp.classID1, comp.classID2); ReplaceSubfile(index, trans, comp); trans.LoadFrom(stream); return trans; } } } catch { Report.ReportLog("Failed to load " + comp.classID1 + "/" + comp.classID2 + " PathID=" + comp.pathID); foreach (NotLoaded notLoaded in RemovedList) { if (notLoaded == comp) { RemovedList.Remove(notLoaded); Components.RemoveAt(index); notLoaded.replacement = null; Components.Insert(index, notLoaded); break; } } } return null; }
public static SkinnedMeshRenderer CreateSkinnedMeshRenderer(Animator parser, List<Material> materials, WorkspaceMesh mesh, Matrix meshMatrix, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { numUncheckedSubmeshes++; } } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; List<Matrix> poseMatrices = new List<Matrix>(mesh.BoneList.Count); Transform animatorTransform = parser.m_GameObject.instance.FindLinkedComponent(UnityClassID.Transform); List<PPtr<Transform>> bones = CreateBoneList(animatorTransform, meshMatrix, mesh.BoneList, poseMatrices); SkinnedMeshRenderer sMesh = new SkinnedMeshRenderer(parser.file); int totVerts = 0, totFaces = 0; sMesh.m_Materials.Capacity = numSubmeshes; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { continue; } Material matFound = materials.Find ( delegate(Material mat) { return mat.m_Name == submesh.Material; } ); sMesh.m_Materials.Add(new PPtr<Material>(matFound)); totVerts += submesh.VertexList.Count; totFaces += submesh.FaceList.Count; } Mesh uMesh = new Mesh(parser.file); uMesh.m_Name = mesh.Name; sMesh.m_Mesh = new PPtr<Mesh>(uMesh); sMesh.m_Bones = bones; uMesh.m_BindPose = poseMatrices; uMesh.m_BoneNameHashes = new List<uint>(poseMatrices.Count); for (int i = 0; i < mesh.BoneList.Count; i++) { string bone = mesh.BoneList[i].Name; uint hash = parser.m_Avatar.instance.BoneHash(bone); uMesh.m_BoneNameHashes.Add(hash); } uMesh.m_VertexData = new VertexData((uint)totVerts); uMesh.m_Skin = new List<BoneInfluence>(totVerts); uMesh.m_IndexBuffer = new byte[totFaces * 3 * sizeof(ushort)]; using (BinaryWriter vertWriter = new BinaryWriter(new MemoryStream(uMesh.m_VertexData.m_DataSize)), indexWriter = new BinaryWriter(new MemoryStream(uMesh.m_IndexBuffer))) { uMesh.m_LocalAABB.m_Center = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue); uMesh.m_LocalAABB.m_Extend = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue); uMesh.m_SubMeshes = new List<SubMesh>(numSubmeshes); int vertIndex = 0; for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) { submeshIdx++; } SubMesh submesh = new SubMesh(); submesh.indexCount = (uint)mesh.SubmeshList[submeshIdx].FaceList.Count * 3; submesh.vertexCount = (uint)mesh.SubmeshList[submeshIdx].VertexList.Count; submesh.firstVertex = (uint)vertIndex; uMesh.m_SubMeshes.Add(submesh); indices[i] = mesh.SubmeshList[submeshIdx].Index; worldCoords[i] = mesh.SubmeshList[submeshIdx].WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List<ImportedVertex> vertexList = mesh.SubmeshList[submeshIdx].VertexList; Vector3 min = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue); Vector3 max = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue); for (int str = 0; str < uMesh.m_VertexData.m_Streams.Count; str++) { StreamInfo sInfo = uMesh.m_VertexData.m_Streams[str]; if (sInfo.channelMask == 0) { continue; } for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; for (int chn = 0; chn < uMesh.m_VertexData.m_Channels.Count; chn++) { ChannelInfo cInfo = uMesh.m_VertexData.m_Channels[chn]; if ((sInfo.channelMask & (1 << chn)) == 0) { continue; } vertWriter.BaseStream.Position = sInfo.offset + (j + submesh.firstVertex) * sInfo.stride + cInfo.offset; switch (chn) { case 0: Vector3 pos = vert.Position; pos.X *= -1; vertWriter.Write(pos); min = Vector3.Minimize(min, pos); max = Vector3.Maximize(max, pos); break; case 1: Vector3 normal = vert.Normal; normal.X *= -1; vertWriter.Write(normal); break; case 3: vertWriter.Write(vert.UV); break; case 5: Vector4 tangent = vert.Tangent; tangent.X *= -1; tangent.W *= -1; vertWriter.Write(tangent); break; } } if (sMesh.m_Bones.Count > 0 && sInfo.offset == 0 && uMesh.m_Skin.Count < totVerts) { BoneInfluence item = new BoneInfluence(); for (int k = 0; k < 4; k++) { item.boneIndex[k] = vert.BoneIndices[k] != 0xFF ? vert.BoneIndices[k] : 0; } vert.Weights.CopyTo(item.weight, 0); uMesh.m_Skin.Add(item); } } } vertIndex += (int)submesh.vertexCount; submesh.localAABB.m_Extend = max - min; submesh.localAABB.m_Center = min + submesh.localAABB.m_Extend / 2; uMesh.m_LocalAABB.m_Extend = Vector3.Maximize(uMesh.m_LocalAABB.m_Extend, max); uMesh.m_LocalAABB.m_Center = Vector3.Minimize(uMesh.m_LocalAABB.m_Center, min); List<ImportedFace> faceList = mesh.SubmeshList[submeshIdx].FaceList; submesh.firstByte = (uint)indexWriter.BaseStream.Position; for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; indexWriter.Write((ushort)(vertexIndices[0] + submesh.firstVertex)); indexWriter.Write((ushort)(vertexIndices[2] + submesh.firstVertex)); indexWriter.Write((ushort)(vertexIndices[1] + submesh.firstVertex)); } } uMesh.m_LocalAABB.m_Extend -= uMesh.m_LocalAABB.m_Center; uMesh.m_LocalAABB.m_Center += uMesh.m_LocalAABB.m_Extend / 2; } return sMesh; }