private void GetOrAddController(InteractionSourceState interactionSourceState) { using (GetOrAddControllerPerfMarker.Auto()) { // If this is a new detected controller, raise source detected event with input system // check needs to be here because GetOrAddController adds it to the activeControllers Dictionary // this could be cleaned up because that's not clear bool raiseSourceDetected = !activeControllers.ContainsKey(interactionSourceState.source.id); var controller = GetOrAddController(interactionSourceState.source); if (controller != null) { if (raiseSourceDetected) { Service?.RaiseSourceDetected(controller.InputSource, controller); } controller.UpdateController(interactionSourceState); } } }
void OnRenderedObjectInfosCalculated(int frameCount, NativeArray <RenderedObjectInfo> renderedObjectInfos) { if (!m_AsyncAnnotations.TryGetValue(frameCount, out var asyncAnnotation)) { return; } m_AsyncAnnotations.Remove(frameCount); using (s_BoundingBoxCallback.Auto()) { if (m_BoundingBoxValues == null || m_BoundingBoxValues.Length != renderedObjectInfos.Length) { m_BoundingBoxValues = new BoundingBoxValue[renderedObjectInfos.Length]; } for (var i = 0; i < renderedObjectInfos.Length; i++) { var objectInfo = renderedObjectInfos[i]; if (!idLabelConfig.TryGetLabelEntryFromInstanceId(objectInfo.instanceId, out var labelEntry)) { continue; } m_BoundingBoxValues[i] = new BoundingBoxValue { label_id = labelEntry.id, label_name = labelEntry.label, instance_id = objectInfo.instanceId, x = objectInfo.boundingBox.x, y = objectInfo.boundingBox.y, width = objectInfo.boundingBox.width, height = objectInfo.boundingBox.height, }; } asyncAnnotation.ReportValues(m_BoundingBoxValues); } }
protected virtual void OnGUI(int elementIndex) { using (s_OnGui.Auto()) { try { using (new Service <Database.DefaultDataFormatter> .ScopeService(new Database.DefaultDataFormatter())) { var rect = m_VisualElements[elementIndex].contentRect; if (float.IsNaN(rect.width) || float.IsNaN(rect.height)) { rect = new Rect(0, 0, 1, 1); } m_VisualElementsOnGUICalls[elementIndex](rect); } } catch (Exception) { throw; } } }
bool MoveEntities(EntityManager srcManager, Entity sceneEntity) { NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping; using (m_ExtractEntityRemapRefs.Auto()) { if (!ExtractEntityRemapRefs(srcManager, out entityRemapping)) { return(false); } } using (m_AddSceneSharedComponents.Auto()) { #if UNITY_EDITOR var data = new EditorRenderData() { SceneCullingMask = UnityEditor.SceneManagement.EditorSceneManager.DefaultSceneCullingMask | (1UL << 59), PickableObject = EntityManager.HasComponent <SubScene>(sceneEntity) ? EntityManager.GetComponentObject <SubScene>(sceneEntity).gameObject : null }; srcManager.AddSharedComponentData(srcManager.UniversalGroup, data); #endif srcManager.AddSharedComponentData(srcManager.UniversalGroup, new SceneTag { SceneEntity = sceneEntity }); } using (m_MoveEntitiesFrom.Auto()) { EntityManager.MoveEntitiesFrom(srcManager, entityRemapping); } entityRemapping.Dispose(); srcManager.PrepareForDeserialize(); return(true); }
/// <summary> /// Applies the configured observation extents. /// </summary> protected virtual void ConfigureObserverVolume() { if (SpatialAwarenessSystem == null || XRSubsystemHelpers.MeshSubsystem == null) { return; } using (ConfigureObserverVolumePerfMarker.Auto()) { // Update the observer switch (ObserverVolumeType) { case VolumeType.AxisAlignedCube: XRSubsystemHelpers.MeshSubsystem.SetBoundingVolume(ObserverOrigin, ObservationExtents); break; default: Debug.LogError($"Unsupported ObserverVolumeType value {ObserverVolumeType}"); break; } } }
private void DisableTrackingLostVisual() { using (DisableTrackingLostVisualPerfMarker.Auto()) { if (visual != null && visual.Enabled) { CameraCache.Main.cullingMask = cullingMaskOnTrackingLost; if (profile.HaltTimeWhileTrackingLost) { Time.timeScale = timeScaleOnTrackingLost; } if (profile.HaltAudioOnTrackingLost) { AudioListener.pause = false; } visual.Enabled = false; } } }
/// <summary> /// Update the menu button state. /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform.</param> private void UpdateMenuData(InteractionSourceState interactionSourceState, MixedRealityInteractionMapping interactionMapping) { using (UpdateMenuDataPerfMarker.Auto()) { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.menuPressed; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled if (interactionSourceState.menuPressed) { CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } } }
/// <inheritdoc/> public override void Suspend() { if (!IsRunning) { Debug.LogWarning("The XR SDK spatial observer is currently stopped."); return; } using (SuspendPerfMarker.Auto()) { if (meshSubsystem != null && meshSubsystem.running) { meshSubsystem.Stop(); } // UpdateObserver keys off of this value to stop observing. IsRunning = false; // Clear any pending work. meshWorkQueue.Clear(); } }
/// <summary> /// Update spatial grip data. /// </summary> protected virtual void UpdatePoseData(MixedRealityInteractionMapping interactionMapping, InputDevice inputDevice) { using (UpdatePoseDataPerfMarker.Auto()) { Debug.Assert(interactionMapping.AxisType == AxisType.SixDof); // Update the interaction data source switch (interactionMapping.InputType) { case DeviceInputType.SpatialGrip: interactionMapping.PoseData = CurrentControllerPose; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionMapping.PoseData); } break; } } }
/// <summary> /// Handles the SurfaceObserver's OnSurfaceChanged event. /// </summary> /// <param name="id">The identifier assigned to the surface which has changed.</param> /// <param name="changeType">The type of change that occurred on the surface.</param> /// <param name="bounds">The bounds of the surface.</param> /// <param name="updateTime">The date and time at which the change occurred.</param> private void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime) { if (!IsRunning) { return; } using (OnSurfaceChangedPerfMarker.Auto()) { switch (changeType) { case SurfaceChange.Added: case SurfaceChange.Updated: meshWorkQueue.Enqueue(id); break; case SurfaceChange.Removed: RemoveMeshObject(id.handle); break; } } }
/// <inheritdoc/> public override void Resume() { if (IsRunning) { Debug.LogWarning("The XR SDK spatial observer is currently running."); return; } using (ResumePerfMarker.Auto()) { if (meshSubsystem != null && !meshSubsystem.running) { meshSubsystem.Start(); } // We want the first update immediately. lastUpdated = 0; // UpdateObserver keys off of this value to start observing. IsRunning = true; } }
private static int MemoryItoA(int value, char[] stringBuffer, int bufferIndex) { using (MemoryItoAPerfMarker.Auto()) { int startIndex = bufferIndex; for (; value != 0; value /= 10) { stringBuffer[bufferIndex++] = (char)((char)(value % 10) + '0'); } char temp; for (int endIndex = bufferIndex - 1; startIndex < endIndex; ++startIndex, --endIndex) { temp = stringBuffer[startIndex]; stringBuffer[startIndex] = stringBuffer[endIndex]; stringBuffer[endIndex] = temp; } return(bufferIndex); } }
/// <inheritdoc /> public override void OnPreSceneQuery() { using (OnPreSceneQueryPerfMarker.Auto()) { Rays[0].CopyRay(TouchRay, PointerExtent); if (RayStabilizer != null) { RayStabilizer.UpdateStability(Rays[0].Origin, Rays[0].Direction); Rays[0].CopyRay(RayStabilizer.StableRay, PointerExtent); if (MixedRealityRaycaster.DebugEnabled) { Debug.DrawRay(RayStabilizer.StableRay.origin, RayStabilizer.StableRay.direction * PointerExtent, Color.green); } } else if (MixedRealityRaycaster.DebugEnabled) { Debug.DrawRay(TouchRay.origin, TouchRay.direction * PointerExtent, Color.yellow); } } }
internal static World CreateConversionWorld(GameObjectConversionSettings settings, Scene scene = default) { using (s_CreateConversionWorld.Auto()) { var gameObjectWorld = new World($"GameObject -> Entity Conversion '{settings.DebugConversionName}'", WorldFlags.Live | WorldFlags.Conversion | WorldFlags.Staging); var mappingSystem = new GameObjectConversionMappingSystem(settings); gameObjectWorld.AddSystem(mappingSystem); if (mappingSystem.IsLiveLink) { mappingSystem.PrepareForLiveLink(scene); } var systemTypes = settings.Systems ?? DefaultWorldInitialization.GetAllSystems(settings.FilterFlags); var includeExport = settings.SupportsExporting; AddConversionSystems(gameObjectWorld, systemTypes.Concat(settings.ExtraSystems), includeExport, mappingSystem.IsLiveLink); settings.ConversionWorldCreated?.Invoke(gameObjectWorld); return(gameObjectWorld); } }
/// <inheritdoc /> public override void Update() { base.Update(); using (UpdatePerfMarker.Auto()) { if (IsLeapConnected) { // if the number of tracked hands in frame has changed if (currentHandsDetectedByLeap.Count != trackedHands.Count) { UpdateLeapTrackedHands(leftAttachmentHand.isTracked, rightAttachmentHand.isTracked); } // Update the hand/hands that are in trackedhands foreach (KeyValuePair <Handedness, EskyLeapMotionArticulatedHand> hand in trackedHands) { hand.Value.UpdateState(); } } } }
/// <inheritdoc /> public override void OnPreSceneQuery() { using (OnPreSceneQueryPerfMarker.Auto()) { if (!IsInteractionEnabled) { return; } stabilizationRay.origin = transform.position; stabilizationRay.direction = transform.forward; stabilizedRay.AddSample(stabilizationRay); parabolicLineData.LineTransform.rotation = Quaternion.identity; parabolicLineData.Direction = stabilizedRay.StabilizedDirection; // when pointing straight up, angle should be close to 1. // when pointing straight down, angle should be close to -1. // when pointing straight forward in any direction, upDot should be 0. var angle = (Vector3.Angle(stabilizedRay.StabilizedDirection, Vector3.down) - 90.0f) / 90.0f; var sqr_angle = angle * angle; var velocity = minParabolaVelocity; var distance = minDistanceModifier; // If we're pointing below the horizon, always use the minimum modifiers. // We use square angle so that the velocity change is less noticeable the closer the teleport point // is to the user if (sqr_angle > 0) { velocity = Mathf.Lerp(minParabolaVelocity, maxParabolaVelocity, sqr_angle); distance = Mathf.Lerp(minDistanceModifier, maxDistanceModifier, sqr_angle); } parabolicLineData.Velocity = velocity; parabolicLineData.DistanceMultiplier = distance; base.OnPreSceneQuery(); } }
/// <inheritdoc /> protected override void UpdateDualAxisData(MixedRealityInteractionMapping interactionMapping, InputDevice inputDevice) { using (UpdateDualAxisDataPerfMarker.Auto()) { Debug.Assert(interactionMapping.AxisType == AxisType.DualAxis); InputFeatureUsage <Vector2> axisUsage; // These mappings are flipped from the base class, // where thumbstick is primary and touchpad is secondary. switch (interactionMapping.InputType) { case DeviceInputType.ThumbStick: axisUsage = CommonUsages.secondary2DAxis; break; case DeviceInputType.Touchpad: axisUsage = CommonUsages.primary2DAxis; break; default: base.UpdateDualAxisData(interactionMapping, inputDevice); return; } if (inputDevice.TryGetFeatureValue(axisUsage, out Vector2 axisData)) { // Update the interaction data source interactionMapping.Vector2Data = axisData; } // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled CoreServices.InputSystem?.RaisePositionInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionMapping.Vector2Data); } } }
/// <summary> /// Update the controller data from XR SDK. /// </summary> public virtual void UpdateController(InputDevice inputDevice) { using (UpdateControllerPerfMarker.Auto()) { if (!Enabled) { return; } if (Interactions == null) { Debug.LogError($"No interaction configuration for {GetType().Name}"); Enabled = false; } UpdateSixDofData(inputDevice); for (int i = 0; i < Interactions?.Length; i++) { switch (Interactions[i].AxisType) { case AxisType.None: break; case AxisType.Digital: UpdateButtonData(Interactions[i], inputDevice); break; case AxisType.SingleAxis: UpdateSingleAxisData(Interactions[i], inputDevice); break; case AxisType.DualAxis: UpdateDualAxisData(Interactions[i], inputDevice); break; } } } }
/// <inheritdoc /> public override void Update() { using (UpdatePerfMarker.Auto()) { if (!Application.isPlaying || Service == null || dictationRecognizer == null) { return; } if (!isTransitioning && IsListening && !Microphone.IsRecording(deviceName) && dictationRecognizer.Status == SpeechSystemStatus.Running) { // If the microphone stops as a result of timing out, make sure to manually stop the dictation recognizer. StopRecording(); } if (!hasFailed && dictationRecognizer.Status == SpeechSystemStatus.Failed) { hasFailed = true; Service.RaiseDictationError(inputSource, "Dictation recognizer has failed!"); } } }
/// <summary> /// Sends the observations using the mesh data contained within the configured 3D model. /// </summary> private void SendMeshObjects() { if (!sendObservations) { return; } using (SendMeshObjectsPerfMarker.Auto()) { if (spatialMeshObject != null) { MeshFilter[] meshFilters = spatialMeshObject.GetComponentsInChildren <MeshFilter>(); for (int i = 0; i < meshFilters.Length; i++) { SpatialAwarenessMeshObject meshObject = SpatialAwarenessMeshObject.Create( meshFilters[i].sharedMesh, MeshPhysicsLayer, $"Spatial Object Mesh {currentMeshId}", currentMeshId, ObservedObjectParent); meshObject.GameObject.transform.localPosition = meshFilters[i].transform.position; meshObject.GameObject.transform.localRotation = meshFilters[i].transform.rotation; ApplyMeshMaterial(meshObject); meshes.Add(currentMeshId, meshObject); meshEventData.Initialize(this, currentMeshId, meshObject); SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded); currentMeshId++; } } sendObservations = false; } }
void CaptureRgbData(Camera cam) { Profiler.BeginSample("CaptureDataFromLastFrame"); if (!captureRgbImages) { return; } var captureFilename = $"{Manager.Instance.GetDirectoryFor(RgbDirectory)}/{s_RgbFilePrefix}{Time.frameCount}.png"; var dxRootPath = $"{RgbDirectory}/{s_RgbFilePrefix}{Time.frameCount}.png"; SensorHandle.ReportCapture(dxRootPath, SensorSpatialData.FromGameObjects(m_EgoMarker == null ? null : m_EgoMarker.gameObject, gameObject), m_PersistentSensorData.Select(kvp => (kvp.Key, kvp.Value)).ToArray()); Func <AsyncRequest <CaptureCamera.CaptureState>, AsyncRequest.Result> colorFunctor; var width = cam.pixelWidth; var height = cam.pixelHeight; var flipY = ShouldFlipY(cam); colorFunctor = r => { using (s_WriteFrame.Auto()) { var dataColorBuffer = (byte[])r.data.colorBuffer; byte[] encodedData; using (s_EncodeAndSave.Auto()) { encodedData = ImageConversion.EncodeArrayToPNG(dataColorBuffer, GraphicsFormat.R8G8B8A8_UNorm, (uint)width, (uint)height); } return(!FileProducer.Write(captureFilename, encodedData) ? AsyncRequest.Result.Error : AsyncRequest.Result.Completed); } }; CaptureCamera.Capture(cam, colorFunctor, flipY: ShouldFlipY(cam)); Profiler.EndSample(); }
private void SetTargetSkin() { using (m_SetTargetSkinPerfMarker.Auto()) { var skinConstraints = GetConstraintsByType(Oni.ConstraintType.Skin) as ObiConstraints <ObiSkinConstraintsBatch>; var batch = skinConstraints.batches[0] as ObiSkinConstraintsBatch; using (m_SortSkinInputsPerfMarker.Auto()) { int pointCount = bakedVertices.Count; for (int i = 0; i < pointCount; ++i) { int welded = m_SkinnedClothBlueprint.topology.rawToWelded[i]; sortedPoints[welded] = bakedVertices[i]; sortedNormals[welded] = bakedNormals[i]; } } using (m_SetSkinInputsPerfMarker.Auto()) { Matrix4x4 skinToSolver = actorLocalToSolverMatrix; for (int i = 0; i < batch.activeConstraintCount; ++i) { int actorIndex = batch.particleIndices[i]; batch.skinPoints[i] = skinToSolver.MultiplyPoint3x4(sortedPoints[actorIndex]); batch.skinNormals[i] = skinToSolver.MultiplyVector(sortedNormals[actorIndex]); // Rigidly transform particles with zero skin radius and zero compliance: if (Mathf.Approximately(batch.skinRadiiBackstop[i * 3], 0) & Mathf.Approximately(batch.skinCompliance[i], 0)) { int solverIndex = solverIndices[actorIndex]; solver.invMasses[solverIndex] = 0; solver.positions[solverIndex] = batch.skinPoints[i]; } } } } }
/// <inheritdoc/> public override void Update() { using (UpdatePerfMarker.Auto()) { base.Update(); #if (UNITY_WSA && DOTNETWINRT_PRESENT) || WINDOWS_UWP if (mixedRealityGazeProviderHeadOverride != null && mixedRealityGazeProviderHeadOverride.UseHeadGazeOverride && WindowsMixedRealityUtilities.SpatialCoordinateSystem != null) { SpatialPointerPose pointerPose = SpatialPointerPose.TryGetAtTimestamp(WindowsMixedRealityUtilities.SpatialCoordinateSystem, PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now)); if (pointerPose != null) { HeadPose head = pointerPose.Head; if (head != null) { mixedRealityGazeProviderHeadOverride.OverrideHeadGaze(head.Position.ToUnityVector3(), head.ForwardDirection.ToUnityVector3()); } } } #endif // (UNITY_WSA && DOTNETWINRT_PRESENT) || WINDOWS_UWP UpdateInteractionManagerReading(); for (var i = 0; i < numInteractionManagerStates; i++) { // SourceDetected gets raised when a new controller is detected and, if previously present, // when OnEnable is called. Do not create a new controller here. var controller = GetOrAddController(interactionManagerStates[i].source, false); if (controller != null) { controller.UpdateController(interactionManagerStates[i]); } } LastInteractionManagerStateReading = interactionManagerStates; } }
/// <summary> /// Update the source input from the device. /// </summary> /// <param name="inputDevice">The InputDevice retrieved from the platform.</param> /// <returns>Whether position or rotation was successfully updated.</returns> public bool UpdateSourceData(InputDevice inputDevice) { using (UpdateSourceDataPerfMarker.Auto()) { TrackingState lastState = TrackingState; LastControllerPose = CurrentControllerPose; // Check for position and rotation. bool isPositionAvailable = inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 position); bool isRotationAvailable = inputDevice.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion rotation); if (isPositionAvailable || isRotationAvailable) { IsPositionAvailable = isPositionAvailable; IsPositionApproximate = false; IsRotationAvailable = isRotationAvailable; // Devices are considered tracked if we receive position OR rotation data from the sensors. TrackingState = (IsPositionAvailable || IsRotationAvailable) ? TrackingState.Tracked : TrackingState.NotTracked; CurrentControllerPosition = MixedRealityPlayspace.TransformPoint(position); CurrentControllerRotation = MixedRealityPlayspace.Rotation * rotation; CurrentControllerPose.Position = CurrentControllerPosition; CurrentControllerPose.Rotation = CurrentControllerRotation; // Raise input system events if it is enabled. if (lastState != TrackingState) { CoreServices.InputSystem?.RaiseSourceTrackingStateChanged(InputSource, this, TrackingState); } return(true); } return(false); } }
public virtual void RegisterPointers(IMixedRealityPointer[] pointers) { using (RegisterPointersPerfMarker.Auto()) { for (int i = 0; i < pointers.Length; i++) { IMixedRealityPointer pointer = pointers[i]; allPointers.Add(pointer); pointer.IsActive = true; if (pointer is IMixedRealityTeleportPointer) { teleportPointers.Add(pointer as IMixedRealityTeleportPointer); } else if (pointer is IMixedRealityNearPointer) { nearInteractPointers.Add(pointer as IMixedRealityNearPointer); } else { farInteractPointers.Add(pointer); } if (pointer.InputSourceParent != null) { HashSet <IMixedRealityPointer> children; if (!pointerByInputSourceParent.TryGetValue(pointer.InputSourceParent, out children)) { children = new HashSet <IMixedRealityPointer>(); pointerByInputSourceParent.Add(pointer.InputSourceParent, children); } children.Add(pointer); } } } }
public bool TryUpdate(out bool structuralChangeDetected) { if (!m_Cooldown.Update(DateTime.Now)) { structuralChangeDetected = false; return(false); } using (k_TryUpdateMarker.Auto()) { var handle = GetDiffSinceLastFrameAsync(); var sceneManagerDirty = m_SceneMapper.SceneManagerDirty; try { try { m_SceneMapper.Update(); // throws } finally { using (k_TryUpdateCompleteJobs.Auto()) { handle.Complete(); } } var strategyStateChanged = ApplyDiffResultsToStrategy(); structuralChangeDetected = sceneManagerDirty || strategyStateChanged; } finally { DisposeDifferResults(); } return(true); } }
private void AddTouchController(Touch touch, Ray ray) { using (AddTouchControllerPerfMarker.Auto()) { UnityTouchController controller; if (!ActiveTouches.TryGetValue(touch.fingerId, out controller)) { IMixedRealityInputSource inputSource = null; if (Service != null) { var pointers = RequestPointers(SupportedControllerType.TouchScreen, Handedness.Any); inputSource = Service.RequestNewGenericInputSource($"Touch {touch.fingerId}", pointers); } controller = new UnityTouchController(TrackingState.NotApplicable, Handedness.Any, inputSource); if (inputSource != null) { for (int i = 0; i < inputSource.Pointers.Length; i++) { inputSource.Pointers[i].Controller = controller; var touchPointer = (IMixedRealityTouchPointer)inputSource.Pointers[i]; touchPointer.TouchRay = ray; touchPointer.FingerId = touch.fingerId; } } ActiveTouches.Add(touch.fingerId, controller); } Service?.RaiseSourceDetected(controller.InputSource, controller); controller.TouchData = touch; controller.StartTouch(); } }
/// <summary> /// Reclaims the <see cref="SpatialAwareness.SpatialAwarenessMeshObject"/> to allow for later reuse. /// </summary> protected void ReclaimMeshObject(SpatialAwarenessMeshObject availableMeshObject) { using (ReclaimMeshObjectPerfMarker.Auto()) { if (spareMeshObject == null) { // Cleanup the mesh object. // Do not destroy the game object, destroy the meshes. SpatialAwarenessMeshObject.Cleanup(availableMeshObject, false); availableMeshObject.GameObject.name = "Unused Spatial Mesh"; availableMeshObject.GameObject.SetActive(false); spareMeshObject = availableMeshObject; } else { // Cleanup the mesh object. // Destroy the game object, destroy the meshes. SpatialAwarenessMeshObject.Cleanup(availableMeshObject); } } }
static unsafe void FlipImageY(byte[] dataColorBuffer, int height) { using (s_FlipY.Auto()) { var stride = dataColorBuffer.Length / height; var buffer = new NativeArray <byte>(stride, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); fixed(byte *colorBufferPtr = &dataColorBuffer[0]) { var unsafePtr = (byte *)buffer.GetUnsafePtr(); for (var row = 0; row < height / 2; row++) { var nearRowStartPtr = colorBufferPtr + stride * row; var oppositeRowStartPtr = colorBufferPtr + stride * (height - row - 1); UnsafeUtility.MemCpy(unsafePtr, oppositeRowStartPtr, stride); UnsafeUtility.MemCpy(oppositeRowStartPtr, nearRowStartPtr, stride); UnsafeUtility.MemCpy(nearRowStartPtr, unsafePtr, stride); } } buffer.Dispose(); } }
protected override GenericXRSDKController GetOrAddController(InputDevice inputDevice) { using (GetOrAddControllerPerfMarker.Auto()) { GenericXRSDKController detectedController = base.GetOrAddController(inputDevice); SupportedControllerType currentControllerType = GetCurrentControllerType(inputDevice); // Add the Motion Controller state if it's an HPMotionController if (currentControllerType == SupportedControllerType.HPMotionController) { lock (trackedMotionControllerStates) { uint controllerId = GetControllerId(inputDevice); if (trackedMotionControllerStates.ContainsKey(controllerId) && detectedController is HPMotionController hpController) { hpController.MotionControllerState = trackedMotionControllerStates[controllerId]; } } } return(detectedController); } }