12using System.Collections;
24 [RequireComponent(typeof(Camera))]
25 [RequireComponent(typeof(LeapServiceProvider))]
36 [FormerlySerializedAs(
"gammaCorrection")]
37 private float _gammaCorrection = 1.0f;
46 private long _prevSequenceId;
47 private bool _needQueueReset;
51 return _eyeTextureData;
56 private Texture2D _combinedTexture =
null;
57 private byte[] _intermediateArray =
null;
61 return _combinedTexture;
66 if (_combinedTexture ==
null || _intermediateArray ==
null) {
70 if (image.
Width != _combinedTexture.width || image.
Height * 2 != _combinedTexture.height) {
74 if (_combinedTexture.format != getTextureFormat(image)) {
82 int combinedWidth = image.
Width;
83 int combinedHeight = image.
Height * 2;
85 TextureFormat format = getTextureFormat(image);
87 if (_combinedTexture !=
null) {
88 DestroyImmediate(_combinedTexture);
91 _combinedTexture =
new Texture2D(combinedWidth, combinedHeight, format,
false,
true);
92 _combinedTexture.wrapMode = TextureWrapMode.Clamp;
93 _combinedTexture.filterMode = FilterMode.Bilinear;
94 _combinedTexture.name = globalShaderName;
95 _combinedTexture.hideFlags = HideFlags.DontSave;
97 _intermediateArray =
new byte[combinedWidth * combinedHeight * bytesPerPixel(format)];
99 Shader.SetGlobalTexture(globalShaderName, _combinedTexture);
100 Shader.SetGlobalVector(pixelSizeName,
new Vector2(1.0f / image.
Width, 1.0f / image.
Height));
105 _combinedTexture.Apply();
108 private TextureFormat getTextureFormat(
Image image) {
111 return TextureFormat.Alpha8;
113 throw new Exception(
"Unexpected image format " + image.
Format +
"!");
117 private int bytesPerPixel(TextureFormat format) {
119 case TextureFormat.Alpha8:
122 throw new Exception(
"Unexpected texture format " + format);
128 private Texture2D _combinedTexture =
null;
132 return _combinedTexture;
137 return _combinedTexture ==
null;
144 if (_combinedTexture !=
null) {
145 DestroyImmediate(_combinedTexture);
148 Color32[] colorArray =
new Color32[combinedWidth * combinedHeight];
149 _combinedTexture =
new Texture2D(combinedWidth, combinedHeight, TextureFormat.RGBA32,
false,
true);
150 _combinedTexture.filterMode = FilterMode.Bilinear;
151 _combinedTexture.wrapMode = TextureWrapMode.Clamp;
152 _combinedTexture.hideFlags = HideFlags.DontSave;
154 addDistortionData(image, colorArray, 0);
156 _combinedTexture.SetPixels32(colorArray);
157 _combinedTexture.Apply();
159 Shader.SetGlobalTexture(shaderName, _combinedTexture);
162 private void addDistortionData(
Image image, Color32[] colors,
int startIndex) {
168 for (
int i = 0; i < distortionData.Length; i += 2) {
170 encodeFloat(distortionData[i], out b0, out b1);
171 encodeFloat(distortionData[i + 1], out b2, out b3);
172 colors[i / 2 + startIndex] =
new Color32(b0, b1, b2, b3);
176 private void encodeFloat(
float value, out
byte byte0, out
byte byte1) {
178 value = (value + 0.6f) / 2.3f;
180 float enc_1 = value * 255.0f;
182 enc_0 = enc_0 - (int)enc_0;
183 enc_1 = enc_1 - (int)enc_1;
185 enc_0 -= 1.0f / 255.0f * enc_1;
187 byte0 = (byte)(enc_0 * 256.0f);
188 byte1 = (byte)(enc_1 * 256.0f);
193 private const string GLOBAL_RAW_TEXTURE_NAME =
"_LeapGlobalRawTexture";
194 private const string GLOBAL_DISTORTION_TEXTURE_NAME =
"_LeapGlobalDistortion";
195 private const string GLOBAL_RAW_PIXEL_SIZE_NAME =
"_LeapGlobalRawPixelSize";
199 private bool _isStale =
false;
202 Texture2D empty =
new Texture2D(1, 1, TextureFormat.ARGB32,
false,
false);
203 empty.name =
"EmptyTexture";
204 empty.hideFlags = HideFlags.DontSave;
205 empty.SetPixel(0, 0,
new Color(0, 0, 0, 0));
207 Shader.SetGlobalTexture(GLOBAL_RAW_TEXTURE_NAME, empty);
208 Shader.SetGlobalTexture(GLOBAL_DISTORTION_TEXTURE_NAME, empty);
239 if (Application.isPlaying) {
242 EyeTextureData.ResetGlobalShaderValues();
247 private void Awake() {
248 _provider = GetComponent<LeapServiceProvider>();
249 if (_provider ==
null) {
250 _provider = GetComponentInChildren<LeapServiceProvider>();
259 private void OnEnable() {
260 subscribeToService();
263 private void OnDisable() {
264 unsubscribeFromService();
267 private void OnDestroy() {
270 if (controller !=
null) {
275 private void LateUpdate() {
280 if (_needQueueReset) {
282 _needQueueReset =
false;
292 Image potentialImage;
294 if (potentialImage.SequenceId > imageFrame.Id) {
303 private void OnPreRender() {
313 private void subscribeToService() {
314 if (_serviceCoroutine !=
null) {
318 _serviceCoroutine = StartCoroutine(serviceCoroutine());
321 private void unsubscribeFromService() {
322 if (_serviceCoroutine !=
null) {
323 StopCoroutine(_serviceCoroutine);
324 _serviceCoroutine =
null;
328 if (controller !=
null) {
330 controller.ImageReady -= onImageReady;
331 controller.DistortionChange -= onDistortionChange;
335 private Coroutine _serviceCoroutine =
null;
336 private IEnumerator serviceCoroutine() {
341 }
while (controller ==
null);
343 controller.SetPolicy(
Controller.PolicyFlag.POLICY_IMAGES);
344 controller.ImageReady += onImageReady;
345 controller.DistortionChange += onDistortionChange;
348 private void onImageReady(
object sender, ImageEventArgs args) {
349 Image image = args.image;
352 Debug.LogWarning(
"Image buffer filled up. This is unexpected and means images are being provided faster than " +
353 "LeapImageRetriever can consume them. This might happen if the application has stalled " +
354 "or we recieved a very high volume of images suddenly.");
355 _needQueueReset =
true;
358 if (image.SequenceId < _prevSequenceId) {
362 _needQueueReset =
true;
369 if (QualitySettings.activeColorSpace != ColorSpace.Linear) {
370 gamma = -Mathf.Log10(Mathf.GammaToLinearSpace(0.1f));
System.Drawing.Image Image
EventHandler< DistortionEventArgs > DistortionChange
Dispatched when the image distortion map changes. The distortion map can change when the Leap device ...
void ClearPolicy(PolicyFlag policy)
Requests clearing a policy.
The Image class represents a stereo image pair from the Leap Motion device.
int Height
The image height.
float[] Distortion(CameraType camera)
The distortion calibration map for this image.
int DistortionWidth
The stride of the distortion map.
int Width
The image width.
int DistortionHeight
The distortion map height. Currently fixed at 64.
byte[] Data(CameraType camera)
The buffer containing the image data.
FormatType Format
The image format.
Int64 SequenceId
The image sequence ID.
FormatType
Enumerates the possible image formats.
A generic object with no arguments beyond the event type.
void UpdateTextures(Image image)
bool CheckStale(Image image)
void Reconstruct(Image image)
static void ResetGlobalShaderValues()
readonly LeapTextureData TextureData
readonly LeapDistortionData Distortion
void Reconstruct(Image image, string shaderName)
Texture2D CombinedTexture
void Reconstruct(Image image, string globalShaderName, string pixelSizeName)
void UpdateTexture(Image image)
bool CheckStale(Image image)
Texture2D CombinedTexture
Acquires images from a LeapServiceProvider and uploads image data as shader global data for use by an...
const int LEFT_IMAGE_INDEX
const int RIGHT_IMAGE_INDEX
const string GLOBAL_GAMMA_CORRECTION_EXPONENT_NAME
const float IMAGE_SETTING_POLL_RATE
void ApplyGammaCorrectionValues()
ProduceConsumeBuffer< Image > _imageQueue
const int IMAGE_WARNING_WAIT
const string GLOBAL_CAMERA_PROJECTION_NAME
const string GLOBAL_COLOR_SPACE_GAMMA_NAME
EyeTextureData TextureData
The LeapServiceProvider provides tracked Leap Hand data and images from the device via the Leap servi...
Controller GetLeapController()
Returns the Leap Controller instance.
override Frame CurrentFrame
A Query object is a type of immutable ordered collection of elements that can be used to perform usef...