public override void OnInspectorGUI(){ PointCache t = target as PointCache; GUILayout.Label("Point Cache Asset", EditorStyles.boldLabel); EditorGUI.indentLevel++; if (t.Meshes[0].mesh == null) { EditorGUILayout.HelpBox(" 1) Create player \n 2) Set sources in Import Tab \n 3) Press Import button", MessageType.Info); } else { for (int i = 0; i < t.PostImport.UsedMeshesCount; i++) { EditorGUILayout.LabelField(string.Format("Mesh #{0} name:{1}", i, t.Meshes[i].Name)); EditorGUI.indentLevel++; EditorGUILayout.LabelField(string.Format("Path {0}", t.Meshes[i].Path)); EditorGUILayout.LabelField(string.Format("Mesh: {0} vertices, {1} triangles", t.Meshes[i].mesh.vertexCount, t.Meshes[i].mesh.triangles.Length / 3)); EditorGUILayout.LabelField(string.Format("Source: {0}", t.Meshes[i].Info)); EditorGUI.indentLevel--; GUILayout.Space(4); } GUILayout.Space(4); for (int i = 0; i < t.PostImport.UsedClipsCount; i++) { EditorGUILayout.LabelField(string.Format("Clip #{0} name:{1}", i, t.Clips[i].PostImport.Name)); EditorGUI.indentLevel++; EditorGUILayout.LabelField(string.Format("{0} frames {1} ", t.Clips[i].PostImport.ImportRangeLength, t.Clips[i].PostImport.IsLoop ? ", loop" : "")); EditorGUILayout.LabelField(string.Format("Path: {0}", t.Clips[i].PostImport.FilePath)); string type = t.Clips[i].PostImport.FilePath.EndsWith("obj") ? "obj sequence" : ".pc2"; EditorGUILayout.LabelField(string.Format("Source type: {0}", type)); EditorGUILayout.LabelField(string.Format("Source frames count:{0}", t.Clips[i].PostImport.FileFramesCount)); EditorGUILayout.LabelField(string.Format("Motion path count:{0}", t.Clips[i].MotionPathsCount)); EditorGUI.indentLevel--; GUILayout.Space(4); } EditorGUILayout.LabelField(string.Format("{0} constraints", t.PostConstraints.Length)); EditorGUILayout.LabelField(string.Format("Imported at: {0}", t.ImportingDate)); EditorGUILayout.LabelField(string.Format("Asset file size: {0} MB", t.AssetFileSize.ToString("F4"))); } if (GUILayout.Button("Create Point Cache Player")) { Selection.activeGameObject = t.CreatePlayer(); } //DrawDefaultInspector(); }
public PointCacheData(PointCache.Clip _clip, PointCache _pointCache, int _geometryVerticesCount) { clip = _clip; cis = clip.PreImport; pointCache = _pointCache; geometryVerticesCount = _geometryVerticesCount; IsMeshSequence = Path.GetExtension(cis.FilePath) == ".obj"; tstack = new TasksStack(string.Format("Build clip {0} data", cis.Name)); if (IsMeshSequence) { MeshSequenceInfo msi = new MeshSequenceInfo(cis.FilePath, MeshSequenceInfo.SortModeEnum.ByNumber); tstack.Add("Read .obj sequence", msi.infos.Length + cis.TransitionFramesCount, 3f); } else { tstack.Add("Read .pc2 file", cis.ImportRangeLength + cis.TransitionFramesCount); } if (cis.ChangeFramesCount) { tstack.Add("Change frames count", cis.ClampedCustomFramesCount); } if (cis.EnableMotionSmoothing) { tstack.Add("Motion smoothing", geometryVerticesCount); } if (cis.EnableNormalizeSpeed) { tstack.Add("Normalize speed", geometryVerticesCount); } if (cis.GenerageMotionPaths) { tstack.Add("Generage Motion Paths", geometryVerticesCount); } tstack.Normalize(); }
void SetIndexFormat(ObjData od, PointCache pc) { #if UNITY_2017_3_OR_NEWER od.IndexFormat = pc.PreImport.IndexFormat; #endif }
public IEnumerable <TaskInfo> ImportIE() { yield return(new TaskInfo("Preparing import", 0)); smr = GetComponent <SkinnedMeshRenderer>(); if (smr == null) { yield return(new TaskInfo("Missing Skinned Mesh Render component", -1)); yield break; } PointCache pc = pointCache; pc.SetMaterialsUnused(); if (ProjectionSamples.Get == null) { yield return(new TaskInfo("Missing Projection Samples asset. Reinstal Vertex Animation Tools package", -1)); yield break; } #region BUILD_TASK_STACK TasksStack ts = new TasksStack(string.Format("Importing {0}", pc.name)); for (int i = 0; i < pointCache.PreImport.UsedMeshesCount; i++) { ts.Add(string.Format("Building mesh #{0}", i), 1, 0.01f); } ts.Add("Building binding helper", 1, 0.05f); ts.Add("Binding constraints", pc.PreConstraints.Count, 0.01f); for (int m = 0; m < pc.PreImport.UsedMeshesCount; m++) { ts.Add(string.Format("Mesh #{0} binding", m), 1, 0.75f); } for (int c = 0; c < pc.PreImport.UsedClipsCount; c++) { ts.Add(string.Format("Building clip #{0}", c), 1, 2f); ts.Add(string.Format("Applying clip #{0} frames", c), 1, 0.2f); } ts.Add("Set meshes compression", pc.PreImport.UsedMeshesCount, 0.1f); ts.Add("Optimize meshes", pc.PreImport.UsedMeshesCount, 0.1f); ts.Add("Storing changes and cleanup", 1, 0.1f); ts.Normalize(); //ts.PrintDebugInfo(); #endregion #region VALIDATE_MAIN_MESH if (!pc.Meshes[0].CheckAndUpdateInfo()) { yield return(new TaskInfo(string.Format("Main mesh not valid: {0}", pc.Meshes[0].Info), -1f)); } #endregion #region VALIDATE_CLIPS for (int c = 0; c < pc.PreImport.UsedClipsCount; c++) { if (!pc.Clips[c].PreImport.CheckAndUpdateInfo(pc.Meshes[0].VertsCount)) { yield return(new TaskInfo(string.Format("Clip {0} not valid: {1}", c, pc.Clips[c].PreImport.FileInfo), -1f)); yield break; } } #endregion #region LOAD_MESHES for (int i = 0; i < pointCache.PreImport.UsedMeshesCount; i++) { pointCache.Meshes[i].CheckAndUpdateInfo(); if (pointCache.Meshes[i].VertsCount < 0) { yield return(new TaskInfo(string.Format("LODs {0} not valid {1}", i, pointCache.Meshes[i].Info), -1f)); yield break; } if (pointCache.Meshes[i].mesh == null) { Mesh newMesh = new Mesh(); newMesh.name = string.Format("LOD{0}", i); pointCache.Meshes[i].mesh = newMesh; } PointCache.PolygonMesh lod = pointCache.Meshes[i]; lod.od = new ObjData(lod.Path); SetIndexFormat(pointCache.Meshes[i].od, pc); lod.od.FlipNormals = pc.PreImport.FlipNormals; lod.od.SmoothingGroupsMode = pc.PreImport.SmoothingGroupImportMode; lod.od.NormalsRecalculationMode = pc.PreImport.NormalRecalculationMode; lod.od.ImportUV = true; lod.od.CalculateNormals = true; lod.od.CalculateTangents = true; SetIndexFormat(lod.od, pc); lod.od.Build(); lod.od.Apply(pc.PreImport.SwapYZAxis, pc.PreImport.ScaleFactor); lod.od.CopyTo(lod.mesh); if (pc.PreImport.GenerateMaterials) { lod.Materials = pc.GetPolygonalMeshMaterials(lod.od.SubMeshes.GetNames()); } lod.od.SetBindPoseFrameVertices(); yield return(ts[string.Format("Building mesh #{0}", i)].GetInfo(1)); } #endregion PointCache.PolygonMesh lod0 = pointCache.Meshes[0]; Bounds bindPoseBounds = lod0.od.UM_Bounds; #region BUILD_BINDING_HELPER yield return(ts["Building binding helper"].GetInfo(0)); BindingHelper bh = new BindingHelper(pc.Meshes[0].mesh, transform); bh.SetVertices(pointCache.Meshes[0].od.UM_vertices, pointCache.Meshes[0].od.UM_normals, pointCache.Meshes[0].od.UM_v3tangents); #endregion #region BUILD_CONSTRAINTS pc.PostConstraints = new PointCache.PostImportConstraint[pc.PreConstraints.Count]; for (int co = 0; co < pc.PreConstraints.Count; co++) { yield return(ts["Binding constraints"].GetInfo(co)); PointCache.PreImportConstraint pre = pc.PreConstraints[co]; bh.Bind(pre.ObjSpace, ref pre.BI); pc.PostConstraints[co] = new PointCache.PostImportConstraint(); pc.PostConstraints[co].Name = pc.PreConstraints[co].Name; pc.PostConstraints[co].ObjSpace = pc.PreConstraints[co].ObjSpace; pc.PostConstraints[co].Clips = new ConstraintClip[pc.PreImport.UsedClipsCount]; } #endregion #region BIND_GEOMETRY for (int m = 1; m < pointCache.PreImport.UsedMeshesCount; m++) { PointCache.PolygonMesh lod = pointCache.Meshes[m]; string taskName = string.Format("Mesh #{0} binding", m); foreach (TaskInfo ti in lod.od.BindIE(bh)) { yield return(ts[taskName].GetInfo(ti.Persentage)); } } #endregion bool boundsIsCreated = false; Bounds bounds = new Bounds(); int blendshapesCounter = 0; for (int c = 0; c < pc.PreImport.UsedClipsCount; c++) { PointCache.Clip clip = pc.Clips[c]; string taskStackName = string.Format("Building clip #{0}", c); PointCacheData pcdata = new PointCacheData(clip, pc, lod0.od.Vertices.Count); foreach (TaskInfo ti in pcdata.Build()) { if (ti.Persentage < 0) { bh.Delete(); yield return(new TaskInfo(ti.Name, -1f)); yield break; } TaskInfo totalInfo = ts[taskStackName].GetInfo(ti.Persentage); totalInfo.Name = taskStackName + " / " + ti.Name; yield return(totalInfo); } taskStackName = string.Format("Applying clip #{0} frames", c); clip.PreImport.FrameIdxOffset = blendshapesCounter; for (int co = 0; co < pc.PreConstraints.Count; co++) { pc.PostConstraints[co].Clips[c] = new ConstraintClip(clip.PreImport.ImportRangeLength); } for (int f = 0; f < pcdata.Frames.Count; f++) { yield return(ts[taskStackName].GetInfo(f / (float)pcdata.Frames.Count)); lod0.od.VerticesToSet = pcdata.GetFrameVertices(f); lod0.od.Apply(false, 1); if (!boundsIsCreated) { bounds = lod0.od.UM_Bounds; boundsIsCreated = true; } else { bounds.Encapsulate(lod0.od.UM_Bounds); } Vector3[] posDelta = lod0.od.GetPosDeltas(); Vector3[] normDelta = lod0.od.GetNormsDeltas(); Vector3[] tanDelta = lod0.od.GetTansDeltas(); bh.SetVertices(lod0.od.UM_vertices, lod0.od.UM_normals, lod0.od.UM_v3tangents); string shapeName = string.Format("c{0}f{1}", c, f); lod0.mesh.AddBlendShapeFrame(shapeName, 100, posDelta, normDelta, tanDelta); for (int co = 0; co < pc.PreConstraints.Count; co++) { PFU frameObjSpace = pc.PreConstraints[co].GetFrame(bh); pc.PostConstraints[co].Clips[c].Frames[f] = frameObjSpace - pc.PreConstraints[co].ObjSpace; } for (int l = 1; l < pointCache.PreImport.UsedMeshesCount; l++) { pc.Meshes[l].od.ApplyBinded(bh); pc.Meshes[l].mesh.AddBlendShapeFrame(shapeName, 100, pc.Meshes[l].od.GetPosDeltas(), pc.Meshes[l].od.GetNormsDeltas(), pc.Meshes[l].od.GetTansDeltas()); } blendshapesCounter++; } } yield return(ts["Storing changes and cleanup"].GetInfo(0)); bh.Delete(); if (!boundsIsCreated) { bounds = bindPoseBounds; } smr.localBounds = bounds; for (int c = 0; c < pc.Clips.Length; c++) { pc.Clips[c].PostImport = pc.Clips[c].PreImport; } pc.PostImport = pc.PreImport; pc.ImportSettingsIsDirtyFlag = false; pc.ClearUnusedMaterials(); Init(); yield return(ts.Done); }
public override void Action(int instanceId, string pathName, string resourceFile){ PointCache data = PointCacheFactory.CreatePointCacheAssetAtPath(pathName); ProjectWindowUtil.ShowCreatedAsset(data); }