Beispiel #1
0
            protected override TrTransform CalculateChildXf(List <PbKnot> parentKnots)
            {
                TrTransform actionInCanvasSpace;
                {
                    PbKnot      knot            = GetAttachKnot(parentKnots);
                    float       rotationDegrees = knot.m_distance * App.UNITS_TO_METERS * m_twist;
                    TrTransform offset          = m_offset;

                    // It's cleaner to tack a TrTransform.S(size) onto the action, but that
                    // would modify .scale, which is currently interpreted as "pointer size"
                    // (affecting control point density) and which is also assumed by most
                    // brushes to be constant.
                    if (m_pressureAffectsOffset)
                    {
                        offset.translation *= knot.m_pressuredSize;
                    }
                    else
                    {
                        offset.translation *= m_brush.BaseSize_LS;
                    }

                    TrTransform action =
                        TrTransform.R(Quaternion.AngleAxis(rotationDegrees, Vector3.forward))
                        * offset;
                    actionInCanvasSpace = action.TransformBy(knot.GetFrame(m_frame));
                }

                var cur = parentKnots[parentKnots.Count - 1];

                return(actionInCanvasSpace * cur.m_pointer);
            }
Beispiel #2
0
        //
        // BaseBrushScript api
        //

        protected override bool UpdatePositionImpl(
            Vector3 translation, Quaternion rotation, float pressure)
        {
            TrTransform parentXf = TrTransform.TR(translation, rotation);

            // Update m_knots
            {
                Debug.Assert(m_knots.Count > 1, "There should always be at least 2 knots");
                PbKnot  cur  = m_knots[m_knots.Count - 1];
                PbKnot  prev = m_knots[m_knots.Count - 2];
                Vector3 move = parentXf.translation - prev.m_pointer.translation;

                cur.m_pointer = parentXf;
                float moveLen = move.magnitude;
                cur.m_tangentFrame = (moveLen > 1e-5f)
                    ? MathUtils.ComputeMinimalRotationFrame(
                    move / moveLen, prev.m_tangentFrame, cur.m_pointer.rotation)
                    : prev.m_tangentFrame;
                cur.m_distance      = prev.m_distance + moveLen;
                cur.m_pressuredSize = PressuredSize(pressure);
            }

            MaybeCreateChildren();

            bool createdControlPoint = false;

            for (int i = 0; i < m_children.Count; ++i)
            {
                PbChild child   = m_children[i];
                var     childXf = child.CalculateChildXfFixedScale(m_knots);
                if (child.m_brush.UpdatePosition_LS(childXf, pressure))
                {
                    // Need to save off any control point which is applicable to any of our children.
                    // This does mean that if we have a giant tree of children, we might be saving
                    // off every control point.
                    // TODO: maybe there's a way for the parent to impose some order on this;
                    // like it doesn't always send positions to its children? But that would make
                    // interactive drawing less pretty.
                    createdControlPoint = true;
                }
            }

            if (createdControlPoint)
            {
                m_knots.Add(m_knots[m_knots.Count - 1].Clone());
            }

            return(createdControlPoint);
        }
Beispiel #3
0
        // Looks through children to find ones that are attached to a knot.
        // Returns the distance to the most recent knot with a child.
        // If there are no such children, returns distance to the start of stroke.
        protected float DistanceSinceLastKnotBasedChild()
        {
            PbKnot cur         = m_knots[m_knots.Count - 1];
            float  minDistance = cur.m_distance;

            foreach (var child_ in m_children)
            {
                var child = child_ as PbChildWithOffset;
                if (child != null)
                {
                    float distanceFromChildToTip = cur.m_distance - child.GetAttachKnot(m_knots).m_distance;
                    minDistance = Mathf.Min(minDistance, distanceFromChildToTip);
                }
            }
            return(minDistance);
        }
Beispiel #4
0
            protected override TrTransform CalculateChildXf(List <PbKnot> parentKnots)
            {
                PbKnot lastKnot = parentKnots[parentKnots.Count - 1];

                float distanceMeters = lastKnot.m_distance * App.UNITS_TO_METERS;
                float t = O.CyclesPerMeter * distanceMeters + (float)m_strand / O.NumStrands;
                // Our periodic function makes the plait look pretty square; maybe add
                // some rotation to break things up a bit?
                float rotations = (O.CyclesPerMeter * distanceMeters) * O.RotationsPerCycle;

                float       amplitude = lastKnot.m_pressuredSize / 2; // /2 because size is diameter, not radius.
                TrTransform action    =
                    TrTransform.R(rotations * 360, Vector3.forward) *
                    TrTransform.T(SomePeriodicFunction(t) * amplitude);

                TrTransform actionInCanvasSpace = action.TransformBy(lastKnot.GetFrame(AttachFrame.LineTangent));

                return(actionInCanvasSpace * lastKnot.m_pointer);
            }