public static void ExportFbx([DefaultVar]UnityParser parser, object[] skinnedMeshRendererIDs, object[] animationParsers, int startKeyframe, int endKeyframe, bool linear, bool EulerFilter, double filterPrecision, string path, string exportFormat, bool allFrames, bool allBones, bool skins, bool compatibility) { List<double> sMeshIDList = new List<double>(Utility.Convert<double>(skinnedMeshRendererIDs)); List<MeshRenderer> sMeshes = new List<MeshRenderer>(sMeshIDList.Count); for (int i = 0; i < sMeshIDList.Count; i++) { int sMeshID = (int)sMeshIDList[i]; if (i > 0 && sMeshID < 0) { for (sMeshID = (int)sMeshIDList[i - 1] + 1; sMeshID < -(int)sMeshIDList[i]; sMeshID++) { SkinnedMeshRenderer sMesh = parser.Cabinet.LoadComponent(sMeshID); if (sMesh == null) { continue; } sMeshes.Add(sMesh); } } else { SkinnedMeshRenderer sMesh = parser.Cabinet.LoadComponent(sMeshID); if (sMesh == null) { continue; } sMeshes.Add(sMesh); } } UnityConverter imp = new UnityConverter(parser, sMeshes, skins); FbxUtility.Export(path, imp, startKeyframe, endKeyframe, linear, EulerFilter, (float)filterPrecision, exportFormat, allFrames, allBones, skins, compatibility); }
public static void ExportFbx([DefaultVar] UnityParser parser, object[] skinnedMeshRendererIDs, object[] animationParsers, int startKeyframe, int endKeyframe, bool linear, bool EulerFilter, double filterPrecision, string path, string exportFormat, bool allFrames, bool allBones, bool skins, bool compatibility) { List <double> sMeshIDList = new List <double>(Utility.Convert <double>(skinnedMeshRendererIDs)); List <MeshRenderer> sMeshes = new List <MeshRenderer>(sMeshIDList.Count); for (int i = 0; i < sMeshIDList.Count; i++) { int sMeshID = (int)sMeshIDList[i]; if (i > 0 && sMeshID < 0) { for (sMeshID = (int)sMeshIDList[i - 1] + 1; sMeshID < -(int)sMeshIDList[i]; sMeshID++) { SkinnedMeshRenderer sMesh = parser.Cabinet.LoadComponent(sMeshID); if (sMesh == null) { continue; } sMeshes.Add(sMesh); } } else { SkinnedMeshRenderer sMesh = parser.Cabinet.LoadComponent(sMeshID); if (sMesh == null) { continue; } sMeshes.Add(sMesh); } } UnityConverter imp = new UnityConverter(parser, sMeshes, skins); FbxUtility.Export(path, imp, startKeyframe, endKeyframe, linear, EulerFilter, (float)filterPrecision, exportFormat, allFrames, allBones, skins, compatibility); }
/// <summary> /// draw a specific person /// </summary> /// <param name="personIndex">the person to draw</param> /// <param name="state">the person state</param> void DrawPerson(uint personIndex, PlayerSelection.PersonIDState state) { OmekFramework.Common.BasicTypes.SpaceTypes.Vector3 personPositionFrmk; BeckonData.Persons[personIndex].CenterOfMass3D.Get(out personPositionFrmk); Vector3 personPosition = UnityConverter.ToUnity(personPositionFrmk); Vector2 screenPosition = WorldToScreenProjection(personPosition); int playerRectHalfSize = m_personRectSize / 2; if (UnityPlayerColorThemes.Instance != null) { GUI.color = UnityPlayerColorThemes.Instance.GetPlayerColorTheme((int)personIndex).m_radar; } else { GUI.color = BeckonManager.BeckonInstance.PersonProperties.GetPropertyOfPerson <Color32>(personIndex, m_radarColors, UnityPlayerManagement.IndexingScheme); } Rect playerRect = new Rect(screenPosition.x - playerRectHalfSize, screenPosition.y - playerRectHalfSize, m_personRectSize, m_personRectSize); if (m_personTexture != null) { GUI.DrawTexture(playerRect, m_personTexture, ScaleMode.ScaleToFit, true); } else { GUI.Label(playerRect, "", m_playerRectStyle); } }
public static void ExportMorphFbx([DefaultVar] Animator animator, object[] meshes, string path, string exportFormat, bool oneBlendShape, bool compatibility) { MeshRenderer[] meshArray = Utility.Convert <MeshRenderer>(meshes); List <MeshRenderer> meshList = new List <MeshRenderer>(meshArray); UnityConverter imp = new UnityConverter(animator, meshList, false, true); FbxUtility.ExportMorph(path, imp, exportFormat, oneBlendShape, compatibility); }
private Vector3 ConstrainPosition(OmekFramework.Common.BasicTypes.SpaceTypes.Vector3 pointerPosition) { Vector2 unityCurPosition = UnityConverter.ToUnity(pointerPosition); Vector2 constrainedPosition = new Vector2(m_relativeActiveScreenArea.x + Mathf.Clamp01(unityCurPosition.x) * m_relativeActiveScreenArea.width, m_relativeActiveScreenArea.y + Mathf.Clamp01(unityCurPosition.y) * m_relativeActiveScreenArea.height); return(constrainedPosition); }
public static void ExportMorphFbx([DefaultVar]Animator animator, object[] meshes, string path, string exportFormat, bool oneBlendShape, bool compatibility) { MeshRenderer[] meshArray = Utility.Convert<MeshRenderer>(meshes); List<MeshRenderer> meshList = new List<MeshRenderer>(meshArray); UnityConverter imp = new UnityConverter(animator, meshList, false, true); FbxUtility.ExportMorph(path, imp, exportFormat, oneBlendShape, compatibility); }
private void Start() { _originalMeshes = new List <Mesh>(); _meshes = new List <Mesh>(); _slider = GetComponent <Slider>(); _slider.onValueChanged.AddListener(OnValueChanged); Renderer[] renderers = original.GetComponentsInChildren <Renderer>(); HashSet <Mesh> uniqueMeshes = new HashSet <Mesh>(); foreach (Renderer renderer in renderers) { if (renderer is MeshRenderer meshRenderer) { var meshFilter = renderer.gameObject.GetComponent <MeshFilter>(); if (!meshFilter) { continue; } var mesh = meshFilter.sharedMesh; _polycount += mesh.triangles.Length; if (!uniqueMeshes.Add(mesh)) { continue; } _originalMeshes.Add(mesh); // Clone mesh mesh = meshFilter.sharedMesh = UnityConverter.ToSharedMesh(mesh).ToUnityMesh(); _meshes.Add(mesh); } else if (renderer is SkinnedMeshRenderer skinnedMeshRenderer) { var mesh = skinnedMeshRenderer.sharedMesh; _polycount += mesh.triangles.Length; if (!uniqueMeshes.Add(mesh)) { continue; } _originalMeshes.Add(mesh); // Clone mesh mesh = skinnedMeshRenderer.sharedMesh = mesh.ToSharedMesh().ToUnityMesh(); _meshes.Add(mesh); } } OnValueChanged(1); }
public static void ExportFbx([DefaultVar]Animator animator, object[] meshes, object[] animationParsers, int startKeyframe, int endKeyframe, bool linear, bool EulerFilter, double filterPrecision, string path, string exportFormat, bool allFrames, bool allBones, bool skins, bool compatibility) { MeshRenderer[] meshArray = Utility.Convert<MeshRenderer>(meshes); List<MeshRenderer> meshList = new List<MeshRenderer>(meshArray); UnityConverter imp = new UnityConverter(animator, meshList, skins, false); FbxUtility.Export(path, imp, startKeyframe, endKeyframe, linear, EulerFilter, (float)filterPrecision, exportFormat, allFrames, allBones, skins, compatibility); }
public static void ExportFbx([DefaultVar] Animator animator, object[] meshes, object[] animationParsers, int startKeyframe, int endKeyframe, bool linear, bool EulerFilter, double filterPrecision, string path, string exportFormat, bool allFrames, bool allBones, bool skins, bool compatibility) { MeshRenderer[] meshArray = Utility.Convert <MeshRenderer>(meshes); List <MeshRenderer> meshList = new List <MeshRenderer>(meshArray); UnityConverter imp = new UnityConverter(animator, meshList, skins, false); FbxUtility.Export(path, imp, startKeyframe, endKeyframe, linear, EulerFilter, (float)filterPrecision, exportFormat, allFrames, allBones, skins, compatibility); }
public void OnDrawGizmosSelected() { if (!enabled || !Application.isPlaying) { return; } // find who has most pointers int maxPointerHolder = GetMaxPointerHolder(); if (maxPointerHolder == -1) { return; } Gizmos.color = Color.blue; foreach (Omek.JointID joint in System.Enum.GetValues(typeof(Omek.JointID))) { if (joint == Omek.JointID.unknown) { continue; } Omek.JointID commonJoint = (Omek.JointID)joint; OmekFramework.Common.BasicTypes.SpaceTypes.Vector3 frameworkPos; OmekFramework.Common.BasicTypes.ReturnCode rc = BeckonData.Persons[(uint)maxPointerHolder].Skeleton[commonJoint].Position.World.Get(out frameworkPos); if (!rc.IsError()) { frameworkPos.x = -frameworkPos.x; //Debug.Log(joint + " pos = " + jointPos); Gizmos.DrawSphere(transform.position + UnityConverter.ToUnitySpace(frameworkPos) * 0.01f, 0.05f); } } foreach (PointerData pd in m_currentPointers) { if (pd.m_personID != maxPointerHolder || pd.m_pointer == null) { continue; } Vector3 boxCenter = UnityConverter.ToUnitySpace(pd.m_pointer.ActualMovementBox.CenterOffset) * 0.01f; boxCenter.x = -boxCenter.x; boxCenter += transform.position; Gizmos.color = Color.red; Gizmos.DrawWireCube(boxCenter, UnityConverter.ToUnity(pd.m_pointer.ActualMovementBox.Dimensions) * 0.01f); Gizmos.color = Color.green; Vector3 jointPosition = UnityConverter.ToUnitySpace(pd.m_pointer.NoiseReduceJointPosition) * 0.01f; jointPosition.x = -jointPosition.x; Gizmos.DrawSphere(transform.position + jointPosition, 0.05f); } }
private void SetDecimation(float value, Dictionary <string, float> variables) { ConnectedMesh[] connectedMeshes = _originalMeshes.Select(x => UnityConverter.ToSharedMesh(x).ToConnectedMesh()).ToArray(); foreach (ConnectedMesh connectedMesh in connectedMeshes) { for (int i = 0; i < connectedMesh.attributeDefinitions.Length; i++) { switch (connectedMesh.attributeDefinitions[i].type) { case AttributeType.Normals: connectedMesh.attributeDefinitions[i].weight = variables["NormalWeight"]; break; case AttributeType.UVs: connectedMesh.attributeDefinitions[i].weight = variables["UVsWeight"]; break; } } } foreach (ConnectedMesh connectedMesh in connectedMeshes) { // Important step : // We merge positions to increase chances of having correct topology information // We merge attributes in order to make interpolation properly operate on every face connectedMesh.MergePositions(0.0001f /*variables["MergeThreshold"]*/); connectedMesh.MergeAttributes(); connectedMesh.Compact(); } DecimateModifier.MergeNormalsThresholdDegrees = variables["MergeNormalsThreshold"]; //DecimateModifier.UpdateFarNeighbors = variables["UpdateFarNeighbors"] > 0.5; //DecimateModifier.UpdateMinsOnCollapse = variables["UpdateMinsOnCollapse"] > 0.5; //DecimateModifier.UseEdgeLength = variables["UseEdgeLength"] > 0.5; DecimateModifier.CollapseToMidpointPenalty = variables["CollapseToMidpointPenalty"]; ConnectedMesh.EdgeBorderPenalty = variables["EdgeBorderPenalty"]; SceneDecimator sceneDecimator = new SceneDecimator(); sceneDecimator.Initialize(connectedMeshes); sceneDecimator.DecimateToRatio(value); for (int i = 0; i < connectedMeshes.Length; i++) { _meshes[i].Clear(); connectedMeshes[i].ToSharedMesh().ToUnityMesh(_meshes[i]); _meshes[i].bindposes = _originalMeshes[i].bindposes; } }
/// <summary> /// Center the world box so the current position will be the center of the new box /// </summary> /// <param name="updateTargetBox">should the TargetBox be updated accordingly so the CurrentValue will stay in place</param> /// <param name="smoothChange">should the change in position be smoothed or should it happen abruptly</param> /// <returns>Return code that represent the status of the run</returns> public bool RecenterOnWorldPosition(bool updateTargetBox, bool smoothChange) { ReturnCode rc = m_transformer.RecenterOnWorldPosition(updateTargetBox, smoothChange); if (!rc.IsError()) { WorldBox.CenterOffset = UnityConverter.ToUnity(m_transformer.WorldBox.CenterOffset); WorldBox.Dimensions = UnityConverter.ToUnity(m_transformer.WorldBox.Dimensions); TargetBox.CenterOffset = UnityConverter.ToUnity(m_transformer.TargetBox.CenterOffset); TargetBox.Dimensions = UnityConverter.ToUnity(m_transformer.TargetBox.Dimensions); return(true); } else { Debug.LogError(rc); return(false); } }
/// <summary> /// Center the world box so the CurrentValue will be at targetPosition /// </summary> /// <param name="targetPosition">the wanted position for CurrentValue, must be inside TargetBox</param> /// <param name="smoothChange">should the change in position be smoothed or should it happen abruptly</param> /// <returns>Return code that represent the status of the run</returns> public bool RecenterOnTargetPosition(UnityEngine.Vector3 targetPosition, bool smoothChange = true) { ReturnCode rc = m_transformer.RecenterOnTargetPosition(UnityConverter.ToFramework(targetPosition), smoothChange); if (!rc.IsError()) { WorldBox.CenterOffset = UnityConverter.ToUnity(m_transformer.WorldBox.CenterOffset); WorldBox.Dimensions = UnityConverter.ToUnity(m_transformer.WorldBox.Dimensions); TargetBox.CenterOffset = UnityConverter.ToUnity(m_transformer.TargetBox.CenterOffset); TargetBox.Dimensions = UnityConverter.ToUnity(m_transformer.TargetBox.Dimensions); return(true); } else { Debug.LogError(rc); return(false); } }
private void OnValueChanged(float value) { polycountLabel.text = $"{Math.Round(100 * value)}% ({Math.Round(value * _polycount)}/{_polycount} triangles)"; Profiling.Start("Convert"); var connectedMeshes = _originalMeshes.Select(x => UnityConverter.ToSharedMesh(x).ToConnectedMesh()).ToArray(); Debug.Log(Profiling.End("Convert")); Profiling.Start("Clean"); foreach (var connectedMesh in connectedMeshes) { // Important step : // We merge positions to increase chances of having correct topology information // We merge attributes in order to make interpolation properly operate on every face connectedMesh.MergePositions(0.0001f); connectedMesh.MergeAttributes(); connectedMesh.Compact(); } Debug.Log(Profiling.End("Clean")); Profiling.Start("Decimate"); SceneDecimator sceneDecimator = new SceneDecimator(); sceneDecimator.Initialize(connectedMeshes); sceneDecimator.DecimateToRatio(value); Debug.Log(Profiling.End("Decimate")); Profiling.Start("Convert back"); for (int i = 0; i < connectedMeshes.Length; i++) { _meshes[i].Clear(); connectedMeshes[i].ToSharedMesh().ToUnityMesh(_meshes[i]); _meshes[i].bindposes = _originalMeshes[i].bindposes; } Debug.Log(Profiling.End("Convert back")); }
/// <summary> /// Copy changed parameters from unity to the framework /// </summary> private void SetParameterFromUnity() { m_transformer.TrackedObjectID = PersonOrPlayerID; m_transformer.UsePlayerID = UsePlayerID; m_transformer.SourceJoint = (Omek.JointID)SourceJoint; if (UseRelativeJoint) { m_transformer.SetBoxRelativeToJoint((Omek.JointID)JointRelativeTo); } else { m_transformer.SetBoxToAbsoluteCoordinates(); } m_transformer.WorldBox.CenterOffset = UnityConverter.ToFramework(WorldBox.CenterOffset); m_transformer.WorldBox.Dimensions = UnityConverter.ToFramework(WorldBox.Dimensions); m_transformer.TargetBox.CenterOffset = UnityConverter.ToFramework(TargetBox.CenterOffset); m_transformer.TargetBox.Dimensions = UnityConverter.ToFramework(TargetBox.Dimensions); m_transformer.MinConfidenceValue = (uint)MinConfidenceValue; m_transformer.SmoothFactor = SmoothFactor; m_transformer.InvertXAxis = InvertXAxis; m_transformer.InvertYAxis = !InvertYAxis; // y axis should be inverted between Unity and the Framework m_transformer.InvertZAxis = InvertZAxis; }
/// <summary> /// Returns an instance of a framework Movement box from this box's data /// </summary> /// <returns></returns> public OmekFramework.Common.BasicTypes.MovementBox ToFrameworkMovementBox() { return(new OmekFramework.Common.BasicTypes.MovementBox(UnityConverter.ToFramework(CenterOffset), UnityConverter.ToFramework(Dimensions))); }
/// <summary> /// Constructor from a framework movement box /// </summary> /// <param name="movementBox">Framework movement box</param> public MovementBox(OmekFramework.Common.BasicTypes.MovementBox movementBox) { CenterOffset = UnityConverter.ToUnity(movementBox.CenterOffset); Dimensions = UnityConverter.ToUnity(movementBox.Dimensions); }
// We use LateUpdate so the transforms will be updated by all other animation. // We'll compute the transform of the tracking animation and blend them together void LateUpdate() { CheckForPersonChange(); if (m_initalized) { m_weight = calcualteCurrentWeight(); if (m_weight > 0) { OMKStatus rc = OMKStatus.OMK_ERROR_SKELETON_NOT_FOUND; if (m_useRetargetSkeleton) { rc = BeckonManager.BeckonInstance.PersonAnalyzer.getRetargetedSkeleton(m_characterName, ref m_currentSkeleton); } else { Omek.IPerson person; rc = BeckonManager.BeckonInstance.PersonAnalyzer.getPerson((uint)m_lastPersonIndex, out person); if (rc == OMKStatus.OMK_SUCCESS) { rc = person.copySkeleton(m_currentSkeleton); } } if (rc != OMKStatus.OMK_SUCCESS) { return; } Quaternion baseRotation = m_transform.rotation; m_transform.rotation = Quaternion.identity; float[] beckonQuat = new float[4]; foreach (TransformWrapper transformWrapper in m_hierarchyList) { if (!transformWrapper.m_active || transformWrapper.m_transform == null) { continue; } Omek.JointID jointID = transformWrapper.m_jointID; if (m_mirror) { jointID = GetReflectedJointID(jointID); } rc = m_currentSkeleton.getJointOrientation((JointID)jointID, true, beckonQuat); if (rc == OMKStatus.OMK_SUCCESS) { // fixing quaternion handness Quaternion quat = UnityConverter.ToUnityQuaternion(beckonQuat); if (m_mirror) { quat.x = -quat.x; quat.w = -quat.w; } // add the original base T-pose rotation to the current rotation. quat = quat * transformWrapper.m_originalRotation; //Smoothly rotate towards the new quaternion based on the confidence UpdateConfidence(transformWrapper.m_confidanceParams, jointID); if (transformWrapper.m_confidanceParams.m_currentConfidence >= 70) { if (m_useSmoothing == true) { quat = RotateTowards(transformWrapper.m_lastRotation, quat, Time.deltaTime * m_animationSmoothing); } } else { quat = transformWrapper.m_lastRotation; } // save the current rotation for next frame transformWrapper.m_lastRotation = quat; // smoothly blend in, the orientation from tracking with the transform orientation from all other animations base on animation weight transformWrapper.m_transform.rotation = Quaternion.Slerp(transformWrapper.m_transform.rotation, quat, m_weight * transformWrapper.m_confidanceParams.m_confidenceWeight); if (transformWrapper.m_rollJoint != null && transformWrapper.m_rollJoint.m_transform != null && transformWrapper.m_rollJoint.m_active) { rollRotation(transformWrapper.m_rollJoint); } } } m_transform.rotation = baseRotation; } } }
private void Start() { _originalMeshes = new List <Mesh>(); _meshes = new List <Mesh>(); Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); HashSet <Mesh> uniqueMeshes = new HashSet <Mesh>(); foreach (Renderer renderer in renderers) { if (renderer is MeshRenderer meshRenderer) { MeshFilter meshFilter = renderer.gameObject.GetComponent <MeshFilter>(); if (!meshFilter) { continue; } Mesh mesh = meshFilter.sharedMesh; if (!uniqueMeshes.Add(mesh)) { continue; } _originalMeshes.Add(mesh); // Clone mesh mesh = meshFilter.sharedMesh = UnityConverter.ToSharedMesh(mesh).ToUnityMesh(); _meshes.Add(mesh); } else if (renderer is SkinnedMeshRenderer skinnedMeshRenderer) { Mesh mesh = skinnedMeshRenderer.sharedMesh; if (!uniqueMeshes.Add(mesh)) { continue; } _originalMeshes.Add(mesh); // Clone mesh mesh = skinnedMeshRenderer.sharedMesh = mesh.ToSharedMesh().ToUnityMesh(); _meshes.Add(mesh); } } Camera camera = Camera.main; Texture2D textureOriginal = CalibrationUtils.CaptureScreenshot(camera, 1000, 1000); File.WriteAllBytes(@"C:\Users\oginiaux\Downloads\trace\original.jpg", textureOriginal.EncodeToJPG()); Digest originalDigest = ImagePhash.ComputeDigest(CalibrationUtils.ToLuminanceImage(textureOriginal)); List <Dictionary <string, float> > results = new List <Dictionary <string, float> >(); float highestCorrelation = float.MinValue; for (int i = 0; i < iterations; i++) { Dictionary <string, float> values = new Dictionary <string, float>(); values["NormalWeight"] = Random.Range(0f, 100f); values["MergeThreshold"] = Random.Range(0.00001f, 0.1f); values["MergeNormalsThreshold"] = MathF.Cos(Random.Range(5f, 140f) * MathF.PI / 180f); values["UseEdgeLength"] = Random.Range(0f, 1f); values["UpdateFarNeighbors"] = Random.Range(0f, 0.75f); values["UpdateMinsOnCollapse"] = Random.Range(0.25f, 1f); values["EdgeBorderPenalty"] = Random.Range(0f, 1000f); values["Case"] = i; System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); SetDecimation(0.5f, values); sw.Stop(); values["Time"] = (float)sw.Elapsed.TotalMilliseconds; Texture2D textureDecimated = CalibrationUtils.CaptureScreenshot(camera, 1000, 1000); Digest modified = ImagePhash.ComputeDigest(CalibrationUtils.ToLuminanceImage(textureDecimated)); values["Correlation"] = ImagePhash.GetCrossCorrelation(originalDigest, modified); if (highestCorrelation < values["Correlation"]) { highestCorrelation = values["Correlation"]; File.WriteAllBytes($@"C:\Users\oginiaux\Downloads\trace\case_{i}.jpg", textureDecimated.EncodeToJPG()); } results.Add(values); } foreach (Dictionary <string, float> result in results.OrderByDescending(x => x["Correlation"]).Take(3)) { StringBuilder strbldr = new StringBuilder(); foreach (KeyValuePair <string, float> pair in result.OrderBy(x => x.Key)) { strbldr.Append($"{pair.Key} = {pair.Value}\n"); } Debug.Log(strbldr); } }
private void OnEnable() { SetParameterFromUnity(); m_transformer.SetInitialPosition(UnityConverter.ToFramework(transform.localPosition)); }
private void Start() { _originalMeshes = new List <Mesh>(); _meshes = new List <Mesh>(); Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); HashSet <Mesh> uniqueMeshes = new HashSet <Mesh>(); foreach (Renderer renderer in renderers) { if (renderer is MeshRenderer meshRenderer) { MeshFilter meshFilter = renderer.gameObject.GetComponent <MeshFilter>(); if (!meshFilter) { continue; } Mesh mesh = meshFilter.sharedMesh; if (!uniqueMeshes.Add(mesh)) { continue; } _originalMeshes.Add(mesh); // Clone mesh mesh = meshFilter.sharedMesh = UnityConverter.ToSharedMesh(mesh).ToUnityMesh(); _meshes.Add(mesh); } else if (renderer is SkinnedMeshRenderer skinnedMeshRenderer) { Mesh mesh = skinnedMeshRenderer.sharedMesh; if (!uniqueMeshes.Add(mesh)) { continue; } _originalMeshes.Add(mesh); // Clone mesh mesh = skinnedMeshRenderer.sharedMesh = mesh.ToSharedMesh().ToUnityMesh(); _meshes.Add(mesh); } } _camera = Camera.main; Texture2D textureOriginal = CalibrationUtils.CaptureScreenshot(_camera, 1000, 1000); _originalDigest = ImagePhash.ComputeDigest(CalibrationUtils.ToLuminanceImage(textureOriginal)); switch (metaHeuristicAlgo) { case MetaHeuristicAlgo.GeneticAlgorithm: _metaheuristicAlgorithm = new GeneticAlgorithm <Dictionary <string, float> >(Crossover); break; case MetaHeuristicAlgo.HillClimbing: _metaheuristicAlgorithm = new HillClimb <Dictionary <string, float> >(); break; } var config = new Configuration <Dictionary <string, float> >(); config.initializeSolutionFunction = GetInitialState; config.cloneFunction = Clone; config.mutationFunction = Mutate; config.movement = Search.Direction.Optimization; config.selectionFunction = Selection.RankBased; config.objectiveFunction = GetFitness; config.populationSize = populationSize; config.noOfIterations = iterations; config.writeToConsole = false; config.enforceHardObjective = false; _metaheuristicAlgorithm.Create(config); StartCoroutine(Run()); }