VR Development Framework
v 1.0.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
AVR_PoseNaturalizationFilter.cs
1 using System.Collections;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using UnityEngine;
5 using System.Linq;
6 
7 using AVR.Core;
8 
9 /// <summary>
10 /// Namespace of the arc-vr-avatar package
11 /// </summary>
12 namespace AVR.Avatar {
13  /// <summary>
14  /// A PoseNaturalizationFilter "naturalizes" a pose. For instance, when a player places the controllers on the ground or to the side, the resulting pose will look bizarre and unnatural.
15  /// These filters will turn the resulting pose into one that seems more natural.
16  ///
17  /// The filter is based on a recorded point-cloud. The cloud consists of locations relative to the HMD that are "normal". The filter uses a simple weighted average (similar to the kNN algorithm) to produce a more natural result.
18  /// </summary>
19  [AVR.Core.Attributes.DocumentationUrl("class_a_v_r_1_1_avatar_1_1_a_v_r___pose_naturalization_filter.html")]
20  [CreateAssetMenu(fileName = "PoseNaturalizationFilter", menuName = "arc-vr/avatar/PoseNaturalizationFilter", order = 1)]
21  public class AVR_PoseNaturalizationFilter : ScriptableObject
22  {
23  /// <summary>
24  /// The amount of points from the point-cloud to use
25  /// </summary>
26  public int reference_amount = 30;
27 
28  /// <summary>
29  /// How many points to incorporate into the weighted average.
30  /// </summary>
31  public int take_k = 4;
32 
33  /// <summary>
34  /// how much to smooth motion by
35  /// </summary>
36  public float smoothing_speed = 10.0f;
37 
38  /// <summary>
39  /// interp = 0 means we dont naturalize at all, interp = 0.5 means the output is 50% input and 50% naturalized position
40  /// </summary>
41  public float interp = 1.0f;
42 
43  /// <summary>
44  /// Pointcloud
45  /// </summary>
46  public List<Vector3> refpoints;
47 
48  private List<Vector3> _refpoints;
49 
50  protected Vector3 outpos = Vector3.zero;
51 
52  void OnEnable() {
53  if(refpoints==null) _refpoints = new List<Vector3>();
54  else _refpoints = refpoints.Take(Mathf.Min(refpoints.Count, reference_amount)).ToList();
55  }
56 
57  public Vector3 naturalize_point(Vector3 wpos) {
58  try {
59  // Transform worldspace -> local space (relative to the PlayerRigs camera)
60  Vector3 cpos = AVR.Core.AVR_PlayerRig.Instance.MainCamera.transform.InverseTransformPoint(wpos);
61 
62  // Get a weighted average of reference points that are closest to this location
63  Vector3 closest = get_weighted_average_reference(cpos);
64 
65  // Smooth over time
66  outpos = Vector3.Lerp(outpos, closest, Time.deltaTime * smoothing_speed);
67 
68  // Interpolate by given value
69  return AVR.Core.AVR_PlayerRig.Instance.MainCamera.transform.TransformPoint(Vector3.Lerp(wpos, outpos, interp));
70  }
71  catch(System.Exception) {
72  AVR_DevConsole.cerror("PoseNaturalizationFilter failed! Is AVR_PlayerRig.Instance set correctly?", "AVR_PoseNaturalizationFilter");
73  return wpos;
74  }
75  }
76 
77  Vector3 get_weighted_average_reference(Vector3 p)
78  {
79  // TODO: we are sorting the whole list here but only want the first k items. -> Needless performance cost.
80  List<Vector3> kn = _refpoints.OrderBy(item => Vector3.Distance(item, p)).Take(Mathf.Min(take_k, _refpoints.Count)).ToList();
81 
82  Vector3 sum = Vector3.zero;
83  float wsum = 0;
84  foreach (var v in kn)
85  {
86  float w = 1.0f / (0.0001f + Vector3.Distance(v, p));
87  wsum += w;
88  sum += w * v;
89  }
90 
91  sum /= wsum;
92 
93  return sum;
94  }
95  }
96 }
A PoseNaturalizationFilter "naturalizes" a pose. For instance, when a player places the controllers o...
Sets the documentation html file inside of Packages/com.avr.core/Documentation/html of a given class...