void Update() { if (_arWrapper != null && _isRunning) { // Update if (_arWrapper.arwCapture()) { // We need to change the threshold and debug mode here, otherwise a concurrent op can happen and UpdateAr will crash if (_arWrapperViewModel != null) { if (_arWrapper.arwGetVideoThresholdMode() != _arWrapperViewModel.SelectedThresholdMode.Mode) { _arWrapper.arwSetVideoThresholdMode(_arWrapperViewModel.SelectedThresholdMode.Mode); } if (_arWrapper.arwGetVideoDebugMode() != _arWrapperViewModel.UseDebugMode) { _arWrapper.arwSetVideoDebugMode(_arWrapperViewModel.UseDebugMode); } } // Update _arWrapper.arwUpdateAR(); if (!_wasStarted) { // Get video params int width, height, pixelSize; string pixelFormat; if (!_arWrapper.arwGetVideoParams(out width, out height, out pixelSize, out pixelFormat)) { throw new InvalidOperationException("ARToolkit arwGetVideoParams failed."); } Helper.Log("Video Params: {0} x {1}. Pixels size: {2} Format: {3}", width, height, pixelSize, pixelFormat); // Initialize buffer var bufferLen = width * height; const int bytesPerPixel = 4; if (_bufferAr == null || _bufferAr.Length != bufferLen) { _bufferAr = new uint[bufferLen]; } if (_bufferWb == null || _bufferWb.Length != bufferLen) { _bufferWb = new byte[bufferLen * bytesPerPixel]; Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { _writeableBitmap = new WriteableBitmap(width, height); PreviewElement.Source = _writeableBitmap; }); } _wasStarted = true; } // Get projection matrix _arWrapper.arwGetProjectionMatrix(_projectionMatrix); // Get marker modelView matrix and other properties _isMarkerVisisble = false; var confidence = -1f; if (!_isMarkerVisisble) { _isMarkerVisisble = _arWrapper.arwQueryMarkerVisibility(_markerId); _arWrapper.arwQueryMarkerTransformation(_markerId, _markerModelViewMatrix); confidence = _arWrapper.arwGetMarkerOptionFloat(_markerId, ArMarkerOption.SquareConfidence); } #if DEBUG if (_isMarkerVisisble) { Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { DbgTxt.Text = string.Format("Marker: {0} Confidence: {1:f02}\r\n" + "{2,7:f02} {3,7:f02} {4,7:f02} {5,7:f02}\r\n" + "{6,7:f02} {7,7:f02} {8,7:f02} {9,7:f02}\r\n" + "{10,7:f02} {11,7:f02} {12,7:f02} {13,7:f02}\r\n" + "{14,7:f02} {15,7:f02} {16,7:f02} {17,7:f02}\r\n", _markerId, confidence, _markerModelViewMatrix[00], _markerModelViewMatrix[04], _markerModelViewMatrix[08], _markerModelViewMatrix[12], _markerModelViewMatrix[01], _markerModelViewMatrix[05], _markerModelViewMatrix[09], _markerModelViewMatrix[13], _markerModelViewMatrix[02], _markerModelViewMatrix[06], _markerModelViewMatrix[10], _markerModelViewMatrix[14], _markerModelViewMatrix[03], _markerModelViewMatrix[07], _markerModelViewMatrix[11], _markerModelViewMatrix[15]); }); } #endif // Update video frame and render if (_writeableBitmap != null && UpdateVideoTexture()) { unsafe { fixed(uint *srcPtr = _bufferAr) { var b = 0; var len = _bufferWb.Length / 4; for (var i = 0; i < len; i++, b += 4) { // On a little-endian system, R occupies the lowest 8 bits, then G, then B, then A the highest 8 bits. // RGBA -> BGRA var p = srcPtr[i]; _bufferWb[b + 0] = (byte)((p >> 16) & 0xff); // R _bufferWb[b + 1] = (byte)((p >> 8) & 0xff); // G _bufferWb[b + 2] = (byte)((p >> 0) & 0xff); // B _bufferWb[b + 3] = (byte)((p >> 24) & 0xff); // A } } } // Update needs to run on the UI thread Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Show video buffer using (var stream = _writeableBitmap.PixelBuffer.AsStream()) { stream.Write(_bufferWb, 0, _bufferWb.Length); } _writeableBitmap.Invalidate(); // Compute XAML tranformation matrix if (_isMarkerVisisble) { // Center at origin of the controls var centerAtOrigin = Matrix3DFactory.CreateTranslation(-ControlPanel.ActualWidth * 0.5, -ControlPanel.ActualHeight * 0.5, 0); // Swap the y-axis and scale down by half var scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5); // Rotate around z var rotate = _shouldRotate ? Matrix3DFactory.CreateRotationZ(rotValue += 0.05) : Matrix3D.Identity; // Viewport transformation var viewport = Matrix3DFactory.CreateViewportTransformation(ContentPanel.ActualWidth, ContentPanel.ActualHeight); // Calculate the final transformation matrix by using the marker model view and camera projection matrix var m = Matrix3DFactory.CreateViewportProjection( centerAtOrigin * rotate * scale, _markerModelViewMatrix.ToMatrix3D(), _projectionMatrix.ToMatrix3D(), viewport); // Apply the matrix to the UI control ControlPanel.Projection = new Matrix3DProjection { ProjectionMatrix = m }; ControlPanel.Visibility = Visibility.Visible; } else { ControlPanel.Visibility = Visibility.Collapsed; } }); } } } }
void Update() { if (_arWrapper == null || !_isRunning) { return; } // Tell ARToolKit to capture a frame from the video camera if (!_arWrapper.arwCapture()) { return; } // We need to change the threshold and debug mode here, otherwise a concurrent op can happen and UpdateAr will crash if (_arWrapperViewModel != null) { if (_arWrapper.arwGetVideoThresholdMode() != _arWrapperViewModel.SelectedThresholdMode.Mode) { _arWrapper.arwSetVideoThresholdMode(_arWrapperViewModel.SelectedThresholdMode.Mode); } if (_arWrapper.arwGetVideoDebugMode() != _arWrapperViewModel.UseDebugMode) { _arWrapper.arwSetVideoDebugMode(_arWrapperViewModel.UseDebugMode); } } // Run marker detection and update results _arWrapper.arwUpdateAR(); // Run the initialization which only works after the first ARToolKit arwUpdateAR marker detection was completed if (!_wasStarted) { // Get video camera parameter int width, height, pixelSize; string pixelFormat; if (!_arWrapper.arwGetVideoParams(out width, out height, out pixelSize, out pixelFormat)) { throw new InvalidOperationException("ARToolkit arwGetVideoParams failed."); } Helper.Log("Video Params: {0} x {1}. Pixels size: {2} Format: {3}", width, height, pixelSize, pixelFormat); // Initialize video frame buffer with the same dimensions like a video frame var bufferLen = width * height; if (_bufferAr == null || _bufferAr.Length != bufferLen) { _bufferAr = new uint[bufferLen]; } // Initialize ArgsubD3D rendering of the D2D video frame bitmap and the cube if (!_videoImage.Setup(ArD3dPanel.Context, width, height, pixelFormat, pixelSize, ArD3dPanel.DpiX, ArD3dPanel.DpiY)) { throw new InvalidOperationException("Could not initialize D2D rendering."); } _cube.Setup(ArD3dPanel.Context); _wasStarted = true; } // Get projection matrix _arWrapper.arwGetProjectionMatrix(_projectionMatrix); // Get marker modelView matrix and other marker properties float confidence; var isMarkerVisisble = _arWrapper.arwQueryMarkerVisibility(_markerId); _arWrapper.arwQueryMarkerTransformation(_markerId, _markerModelViewMatrix); confidence = _arWrapper.arwGetMarkerOptionFloat(_markerId, ArMarkerOption.SquareConfidence); #if DEBUG if (isMarkerVisisble) { Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { DbgTxt.Text = string.Format("Marker: {0} Confidence: {1:f02}\r\n" + "{2,7:f02} {3,7:f02} {4,7:f02} {5,7:f02}\r\n" + "{6,7:f02} {7,7:f02} {8,7:f02} {9,7:f02}\r\n" + "{10,7:f02} {11,7:f02} {12,7:f02} {13,7:f02}\r\n" + "{14,7:f02} {15,7:f02} {16,7:f02} {17,7:f02}\r\n", _markerId, confidence, _markerModelViewMatrix[00], _markerModelViewMatrix[04], _markerModelViewMatrix[08], _markerModelViewMatrix[12], _markerModelViewMatrix[01], _markerModelViewMatrix[05], _markerModelViewMatrix[09], _markerModelViewMatrix[13], _markerModelViewMatrix[02], _markerModelViewMatrix[06], _markerModelViewMatrix[10], _markerModelViewMatrix[14], _markerModelViewMatrix[03], _markerModelViewMatrix[07], _markerModelViewMatrix[11], _markerModelViewMatrix[15]); }); } #endif // Copy camera video frame buffer into our own buffer if (_arWrapper.arwUpdateTexture32(_bufferAr)) { // Begin rendering with a clear ArD3dPanel.BeginDraw(true); // Pass the current video frame to the D2D bitmap and render it ArD3dPanel.DisplayImage(_videoImage, _bufferAr); // Rotate the cube if desired and render it at the marker position using the right modelView and projection matrix if (isMarkerVisisble) { if (_shouldRotateCube) { _cube.Roll += 0.05f; } ArD3dPanel.DisplayObject(_cube, _markerModelViewMatrix, _projectionMatrix); } // Present the rendering result ArD3dPanel.EndDraw(); } }
async void Update() { if (_arWrapper != null && _isRunning) { // Update if (_arWrapper.arwCapture()) { // We need to change the threshold and debug mode here, otherwise a concurrent op can happen and UpdateAr will crash if (_arWrapperViewModel != null) { if (_arWrapper.arwGetVideoThresholdMode() != _arWrapperViewModel.SelectedThresholdMode.Mode) { _arWrapper.arwSetVideoThresholdMode(_arWrapperViewModel.SelectedThresholdMode.Mode); } if (_arWrapper.arwGetVideoDebugMode() != _arWrapperViewModel.UseDebugMode) { _arWrapper.arwSetVideoDebugMode(_arWrapperViewModel.UseDebugMode); } } // Update _arWrapper.arwUpdateAR(); if (!_wasStarted) { // Get video params int width, height, pixelSize; string pixelFormat; if (!_arWrapper.arwGetVideoParams(out width, out height, out pixelSize, out pixelFormat)) { throw new InvalidOperationException("ARToolkit arwGetVideoParams failed."); } Helper.Log("Video Params: {0} x {1}. Pixels size: {2} Format: {3}", width, height, pixelSize, pixelFormat); // Initialize buffer var bufferLen = width * height; if (_bufferAr == null || _bufferAr.Length != bufferLen) { _bufferAr = new uint[bufferLen]; } // Initialize rendering if (!_videoImage.Setup(ArD3dPanel.Context, width, height, pixelFormat, pixelSize, ArD3dPanel.DpiX, ArD3dPanel.DpiY)) { throw new InvalidOperationException("Could not initialize D2D rendering."); } _cube.Setup(ArD3dPanel.Context); _markerMask.Setup(ArD3dPanel.Context); _wasStarted = true; } // Get projection matrix _arWrapper.arwGetProjectionMatrix(_projectionMatrix); // Get marker modelView matrix and other properties _isMarkerVisisble = false; var confidence = -1f; if (!_isMarkerVisisble) { _isMarkerVisisble = _arWrapper.arwQueryMarkerVisibility(_markerId); _arWrapper.arwQueryMarkerTransformation(_markerId, _markerModelViewMatrix); confidence = _arWrapper.arwGetMarkerOptionFloat(_markerId, ArMarkerOption.SquareConfidence); } #if DEBUG if (_isMarkerVisisble) { Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { DbgTxt.Text = string.Format("Marker: {0} Confidence: {1:f02}\r\n" + "{2,7:f02} {3,7:f02} {4,7:f02} {5,7:f02}\r\n" + "{6,7:f02} {7,7:f02} {8,7:f02} {9,7:f02}\r\n" + "{10,7:f02} {11,7:f02} {12,7:f02} {13,7:f02}\r\n" + "{14,7:f02} {15,7:f02} {16,7:f02} {17,7:f02}\r\n", _markerId, confidence, _markerModelViewMatrix[00], _markerModelViewMatrix[04], _markerModelViewMatrix[08], _markerModelViewMatrix[12], _markerModelViewMatrix[01], _markerModelViewMatrix[05], _markerModelViewMatrix[09], _markerModelViewMatrix[13], _markerModelViewMatrix[02], _markerModelViewMatrix[06], _markerModelViewMatrix[10], _markerModelViewMatrix[14], _markerModelViewMatrix[03], _markerModelViewMatrix[07], _markerModelViewMatrix[11], _markerModelViewMatrix[15]); }); } #endif // Update video frame and render if (UpdateVideoTexture()) { // Begin rendering with a clear ArD3dPanel.BeginDraw(true); // Render the current video frame ArD3dPanel.DisplayImage(_videoImage, _bufferAr); // Rotate the cube and render it at the marker position if (_isMarkerVisisble) { // Only update the depth buffer for the cube-shaped marker to mask out the actual virtual cube below ArD3dPanel.DisplayObject(_markerMask, _markerModelViewMatrix, _projectionMatrix, false, true); // Draw the virtual cube if (_shouldRotateCube) { _cube.Roll += 0.05f; } ArD3dPanel.DisplayObject(_cube, _markerModelViewMatrix, _projectionMatrix, true, true); } // Present the buffer ArD3dPanel.EndDraw(); } } } }
async void Update() { if (_arWrapper != null && _isRunning) { // Update if (_arWrapper.arwCapture()) { // Update _arWrapper.arwUpdateAR(); if (!_wasStarted) { // Get video params int width, height, pixelSize; string pixelFormat; if (!_arWrapper.arwGetVideoParams(out width, out height, out pixelSize, out pixelFormat)) { throw new InvalidOperationException("ARToolkit arwGetVideoParams failed."); } Helper.Log("Video Params: {0} x {1}. Pixels size: {2} Format: {3}", width, height, pixelSize, pixelFormat); // Get marker params float markerWidth, markerHeight; int imageSizeX, imageSizeY; _arWrapper.arwGetMarkerPatternConfig(_markerId, 0, _markerModelViewMatrix, out markerWidth, out markerHeight, out imageSizeX, out imageSizeY); Helper.Log("Marker {0} pattern config: {1} x {2} imageSize: {3} x {4}", _markerId, markerWidth, markerHeight, imageSizeX, imageSizeY); // Initialize buffer var bufferLen = width * height; if (_bufferAr == null || _bufferAr.Length != bufferLen) { _bufferAr = new uint[bufferLen]; } // Initialize rendering if (!_videoImage.Setup(ArD3dPanel.Context, width, height, pixelFormat, pixelSize, ArD3dPanel.DpiX, ArD3dPanel.DpiY)) { throw new InvalidOperationException("Could not initialize D2D rendering."); } _cube.Setup(ArD3dPanel.Context); Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ProgressRing.IsActive = false); _wasStarted = true; } // Get projection matrix _arWrapper.arwGetProjectionMatrix(_projectionMatrix); // Get marker modelView matrix and other properties _isMarkerVisisble = false; var confidence = -1f; if (!_isMarkerVisisble) { _isMarkerVisisble = _arWrapper.arwQueryMarkerVisibility(_markerId); _arWrapper.arwQueryMarkerTransformation(_markerId, _markerModelViewMatrix); confidence = _arWrapper.arwGetMarkerOptionFloat(_markerId, ArMarkerOption.SquareConfidence); } #if DEBUG if (_isMarkerVisisble) { Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { DbgTxt.Text = string.Format("Marker: {0} Confidence: {1:f02}\r\n" + "{2,7:f02} {3,7:f02} {4,7:f02} {5,7:f02}\r\n" + "{6,7:f02} {7,7:f02} {8,7:f02} {9,7:f02}\r\n" + "{10,7:f02} {11,7:f02} {12,7:f02} {13,7:f02}\r\n" + "{14,7:f02} {15,7:f02} {16,7:f02} {17,7:f02}\r\n", _markerId, confidence, _markerModelViewMatrix[00], _markerModelViewMatrix[04], _markerModelViewMatrix[08], _markerModelViewMatrix[12], _markerModelViewMatrix[01], _markerModelViewMatrix[05], _markerModelViewMatrix[09], _markerModelViewMatrix[13], _markerModelViewMatrix[02], _markerModelViewMatrix[06], _markerModelViewMatrix[10], _markerModelViewMatrix[14], _markerModelViewMatrix[03], _markerModelViewMatrix[07], _markerModelViewMatrix[11], _markerModelViewMatrix[15]); }); } #endif // Update video frame and render if (UpdateVideoTexture()) { // Begin rendering with a clear ArD3dPanel.BeginDraw(true); // Render the current video frame ArD3dPanel.DisplayImage(_videoImage, _bufferAr); // Rotate the cube and render it at the marker position if (_isMarkerVisisble) { // Draw the virtual cube if (_shouldRotateCube) { _cube.Roll += 0.05f; } ArD3dPanel.DisplayObject(_cube, _markerModelViewMatrix, _projectionMatrix); } // Present the buffer ArD3dPanel.EndDraw(); } } } }