/// Converts TiltBrush brush strokes into linear USD BasisCurves. static BrushCurvesSample GetCurvesSample(ExportUtils.SceneStatePayload payload, List <Stroke> strokes, Matrix4x4 mat44) { var sample = new BrushCurvesSample(); var times = new List <float>(); var pressures = new List <float>(); sample.doubleSided = true; sample.orientation = USD.NET.Orientation.LeftHanded; sample.basis = BasisCurvesSample.Basis.Bezier; sample.type = BasisCurvesSample.CurveType.Linear; sample.wrap = BasisCurvesSample.WrapMode.Nonperiodic; sample.curveVertexCounts = strokes.Select(x => x.m_ControlPoints.Length).ToArray(); sample.transform = mat44; int numCPs = sample.curveVertexCounts.Sum(); sample.points = new Vector3[numCPs]; sample.normals = new Vector3[numCPs]; sample.colors = new Color[numCPs]; int iKnot = 0; foreach (Stroke stroke in strokes) { foreach (var cp in stroke.m_ControlPoints) { times.Add(cp.m_TimestampMs / 1000.0f); pressures.Add(cp.m_Pressure); } foreach (var cp in stroke.m_ControlPoints) { // Normals in USD are stored in object/local space, just as points are. sample.normals[iKnot] = cp.m_Orient * Vector3.up; sample.points[iKnot] = cp.m_Pos; sample.colors[iKnot] = stroke.m_Color.linear; iKnot++; } } { Matrix4x4 basis = ExportUtils.GetFromUnity_Axes(payload); Matrix4x4 units = Matrix4x4.Scale(Vector3.one * payload.exportUnitsFromAppUnits); MathUtils.TransformVector3AsPoint(units * basis, 0, sample.points.Length, sample.points); MathUtils.TransformVector3AsVector(basis, 0, sample.normals.Length, sample.normals); } sample.extent = new Bounds(sample.points[0], Vector3.zero); for (int i = 0; i < sample.points.Length; i++) { sample.extent.Encapsulate(sample.points[i]); } sample.times = times.ToArray(); sample.pressures = pressures.ToArray(); return(sample); }