/** * Checks all points in an UltrasoundScanData point array against a list of possible organs * that can be contained in those points. The points are then appropriately shaded based * on the material properties of those organs. * * @param data An UltrasoundScanData populated with empty UltrasoundPoint objects. * @param organList A list of GameObjects to check against. */ private void ScanPointsForOrgans(ref UltrasoundScanData data, IList <GameObject> organList) { OnionLogger.globalLog.PushInfoLayer("Performing Scan"); int scanlineIndex = 0; int totalScanlines = data.GetProbeConfig().GetNumberOfScanlines(); foreach (UltrasoundScanline scanline in data) { // Reset the intensity when starting each scanline float pulseIntensity = data.GetProbeConfig().GetGain(); foreach (UltrasoundPoint point in scanline) { foreach (GameObject gameObject in organList) { Vector3 target = point.GetWorldSpaceLocation(); Collider collider = gameObject.collider; bool hit = UltrasoundCollisionUtils.IsContained(target, collider); if (hit) { HorayMaterialProperties organProperties = gameObject.GetComponent <HorayMaterialProperties>(); float pointIntensity = IntensityAtPoint(pulseIntensity, organProperties); point.SetBrightness(pointIntensity); pulseIntensity = PulseIntensityAfterPoint(pulseIntensity, organProperties, data.GetProbeConfig()); } } } } OnionLogger.globalLog.PopInfoLayer(); }
/** * Set up the data object with empty UltrasoundPoint%s representing the points * that need to be scanned. * * This is analagous to setting up the view frustum in traditional 3D graphics. */ private void EstablishScanningPlane(ref UltrasoundScanData data) { OnionLogger.globalLog.PushInfoLayer("Pre-populating data"); UltrasoundProbeConfiguration config = data.GetProbeConfig(); // nearZ and farZ represent near and far clipping "planes" (they're really arcs) float nearZ = config.GetMinScanDistance(); float farZ = config.GetMaxScanDistance(); float arcSizeDegrees = config.GetArcSizeInDegrees(); int scanlines = config.GetNumberOfScanlines(); int pointsPerScanline = config.GetPointsPerScanline(); for (int i = 0; i < scanlines; ++i) { UltrasoundScanline scanline = new UltrasoundScanline(config.GetPosition()); float angleInDegrees = -(arcSizeDegrees / 2) + i * arcSizeDegrees / (scanlines - 1); float angleInRadians = Mathf.Deg2Rad * angleInDegrees; Vector2 trajectory = new Vector2(Mathf.Sin(angleInRadians), Mathf.Cos(angleInRadians)); for (int j = 0; j < pointsPerScanline; ++j) { float d = nearZ + j * (farZ - nearZ) / (pointsPerScanline - 1); Vector2 positionOnPlane = d * trajectory; Vector3 positionInWorldSpace = WorldSpaceFromProjectedPosition(positionOnPlane, config); UltrasoundPoint point = new UltrasoundPoint(positionInWorldSpace, positionOnPlane); scanline.AddUltrasoundPoint(point); } data.AddScanline(scanline); } OnionLogger.globalLog.PopInfoLayer(); }
public virtual void RenderColorImageInBitmap(ref ColorBitmap bitmap) { OnionLogger.globalLog.PushInfoLayer("BModeOutputImageDecoder"); // Acquire data from the probe output. UltrasoundScanData data = probeOutput.SendScanData(); // Render the data to a bitmap OnionLogger.globalLog.PushInfoLayer("Rendering UltrasoundData to bitmap"); foreach (UltrasoundScanline scanline in data) { foreach (UltrasoundPoint point in scanline) { int index = MapScanningPlaneToPixelCoordinate(bitmap.height, bitmap.width, point.GetProjectedLocation(), data.GetProbeConfig()); DrawPoint(point, index, ref bitmap); } } OnionLogger.globalLog.PopInfoLayer(); // Apply post-processing effects OnionLogger.globalLog.PushInfoLayer("Post-processing"); foreach (IImagePostProcessor effect in imageEffects) { effect.ProcessBitmap(ref bitmap); } OnionLogger.globalLog.PopInfoLayer(); OnionLogger.globalLog.PopInfoLayer(); }
/** * Populates an UltrasoundScanData with scan data for this frame. * @param data The object into which to put the scan data. */ public void PopulateData(ref UltrasoundScanData data) { OnionLogger.globalLog.PushInfoLayer("HORAYProbe populating data"); #if UNITY_EDITOR UltrasoundDebug.Assert(null != data, "Null data object passed to HorayProbe's PopulateData method.", this); #endif EstablishScanningPlane(ref data); IList <GameObject> culledOrganList = culler.HitableOrgansOnScanlines(data.GetScanlines(), data.GetProbeConfig()); ScanPointsForOrgans(ref data, culledOrganList); OnionLogger.globalLog.PopInfoLayer(); }