FileDocCategorySizeDatePackage
MotionTraitAnim.javaAPI DocphoneME MR2 API (J2ME)14583Wed May 02 18:00:34 BST 2007com.sun.perseus.model

MotionTraitAnim

public class MotionTraitAnim extends TransformTraitAnim
version
$Id: MotionTraitAnim.java,v 1.4 2006/06/29 10:47:33 ln156897 Exp $

Fields Summary
Constructors Summary
public MotionTraitAnim(ElementNode targetElement, String traitName)
Constructs a new TransformTraitAnim for a given ElementNode trait.

param
targetElement the ElementNode whose trait is animated.
param
targetTrait the name of the animated trait.

        super(targetElement, traitName);
    
Methods Summary
LeafMotionSegmentaddCubicSegment(AnimateMotion motion, float[][] curve, java.util.Vector segments, java.util.Vector motionCoords, LeafMotionSegment prevSegment)
Adds the input curve as a CompositeSegment to the segments vector.

param
motion the AnimateMotion element for which the curve is added.
param
curve a float array with the curve definition.
param
segments the vector holding all the animation segments.
param
motionCoords a working vector where coordinates for the various linear approximations can be stored.
param
prevSegment the previous LeafMotionSegment. May be null.
return
the last LeafMotionSegment added to into the segments vector.

        motionCoords.removeAllElements();
        motionCoords.addElement(new float[] {
                                    curve[0][0], 
                                    curve[0][1]
                                }); // Adds the current position.
        AbstractAnimate.toRefSpline(curve, motionCoords);
        
        int nPoints = motionCoords.size();
        float[] curPos = (float[]) motionCoords.elementAt(0);
        LeafMotionSegment[] subSegments = new LeafMotionSegment[nPoints - 1];

        if (nPoints > 1) {
            float[] endPos = (float[]) motionCoords.elementAt(1);
            if (prevSegment == null) {
                subSegments[0] = new LeafMotionSegment(curPos[0],
                                                       curPos[1],
                                                       endPos[0],
                                                       endPos[1],
                                                       motion);
            } else {
                subSegments[0] = new LeafMotionSegment(prevSegment,
                                                       endPos[0],
                                                       endPos[1],
                                                       motion);
            }
            curPos = endPos;
            prevSegment = subSegments[0];
        }

        for (int i = 2; i < nPoints; i++) {
            float[] endPos = (float[]) motionCoords.elementAt(i);
            subSegments[i - 1] = new LeafMotionSegment(prevSegment,
                                                       endPos[0],
                                                       endPos[1],
                                                       motion);
            curPos = endPos;
            prevSegment = subSegments[i - 1];
        }
        
        CompositeMotionSegment cSeg = new CompositeMotionSegment();
        cSeg.segments = subSegments;
        segments.addElement(cSeg);
        return prevSegment;
    
RefValuestoRefValues(Animation anim, java.lang.String[] values, java.lang.String reqTraitNamespace, java.lang.String reqTraitName)
Converts the input values set to a RefValues object. For a MotionTraitAnim, the input values may be the to/from/by/values values or the path attribute value.

param
anim the Animation for which the values should be converted.
param
values a semi-colon seperated list of values which need to be validated.
param
reqTraitNamespace the namespace of the trait which has the values value on the requesting element.
param
reqTraitName the name of the trait which has the values value on the requesting element.
throws
DOMException with error code INVALID_ACCESS_ERR if the input value is incompatible with the given trait.
throws
NullPointerException if values is null.

        AnimateMotion motion = (AnimateMotion) anim;

        // The interpretation of values depends on the attribute type.
        MotionRefValues refValues = new MotionRefValues(motion);
        
        if (values.length < 1) {
            throw new IllegalArgumentException();
        }

        if (!SVGConstants.SVG_PATH_ATTRIBUTE.equals(reqTraitName) &&
            !SVGConstants.SVG_D_ATTRIBUTE.equals(reqTraitName)) {

            //
            // We are dealing with a to/from/by or values attribute
            //

            if (values.length == 1) {
                String[] tmpValues = new String[2];
                tmpValues[0] = values[0];
                tmpValues[1] = values[0];
                values = tmpValues;
            }
            
            int nSegments = values.length - 1;
            refValues.segments = new MotionSegment[nSegments];
            
            // Build the first segment.
            float[] startPt = new float[2];
            float[] endPt = new float[2];
            
            validateCoordinate(anim, 
                               reqTraitNamespace,
                               reqTraitName,
                               values[0],
                               startPt);

            validateCoordinate(anim, 
                               reqTraitNamespace,
                               reqTraitName,
                               values[1],
                               endPt);

            refValues.segments[0] = new LeafMotionSegment(startPt[0],
                                                          startPt[1],
                                                          endPt[0],
                                                          endPt[1],
                                                          motion);
            
            for (int i = 1; i < nSegments; i++) {
                validateCoordinate(anim,
                                   reqTraitNamespace,
                                   reqTraitNamespace,
                                   values[i + 1],
                                   endPt);
                refValues.segments[i] = 
                    new LeafMotionSegment
                    ((LeafMotionSegment) refValues.segments[i - 1],
                     endPt[0],
                     endPt[1],
                     motion);
            }
        } else {
            //
            // We are dealing with the path attribute on animateMotion
            // or with the d attribute on a path element referenced from
            // an mpath element.
            //

            // a) convert the path attribute to a Path
            Path path = anim.parsePathTrait(anim.traitName, values[0]);

            // b) turn the path into a set of segments after linear 
            //    approximation.
            int type = 0;
            float[] coords = new float[6];
            float[] curPos = new float[2];
            float[] endPos = new float[2];
            float[][] curve = new float[4][2];
            float[] lastMove = new float[2];

            Vector segments = new Vector();
            Vector curves = new Vector();
            LeafMotionSegment prevSegment = null;
            
            int nSegments = path.getNumberOfSegments();
            for (int i = 0; i < nSegments; i++) {
                type = path.getSegment(i);
                switch (type) {
                case Path.MOVE_TO:
                    curPos[0] = path.getSegmentParam(i, 0);
                    curPos[1] = path.getSegmentParam(i, 1);
                    lastMove[0] = curPos[0];
                    lastMove[1] = curPos[1];
                    break;
                case Path.LINE_TO:
                    if (prevSegment == null) {
                        prevSegment = new LeafMotionSegment(
                                curPos[0],
                                curPos[1],
                                path.getSegmentParam(i, 0),
                                path.getSegmentParam(i, 1),
                                motion);
                    } else {
                        prevSegment = new LeafMotionSegment(
                                prevSegment,
                                path.getSegmentParam(i, 0),
                                path.getSegmentParam(i, 1),
                                motion);
                    }
                    segments.addElement(prevSegment);
                    curPos[0] = path.getSegmentParam(i, 0);
                    curPos[1] = path.getSegmentParam(i, 1);
                    break;
                case Path.QUAD_TO:
                    // First, linearize the curve.
                    // This is an overkill because we use the same code for
                    // quad curves as for cubic curves.
                    curve[0][0] = curPos[0];
                    curve[0][1] = curPos[1];
                    curve[1][0] = path.getSegmentParam(i, 0);
                    curve[1][1] = path.getSegmentParam(i, 1);
                    curve[2][0] = path.getSegmentParam(i, 0);
                    curve[2][1] = path.getSegmentParam(i, 1);
                    curve[3][0] = path.getSegmentParam(i, 2);
                    curve[3][1] = path.getSegmentParam(i, 3);
                    prevSegment = addCubicSegment(motion, curve, segments, 
                                                  curves, prevSegment);
                    curPos[0] = path.getSegmentParam(i, 2);
                    curPos[1] = path.getSegmentParam(i, 3);
                    break;
                case Path.CURVE_TO:
                    curve[0][0] = curPos[0];
                    curve[0][1] = curPos[1];
                    curve[1][0] = path.getSegmentParam(i, 0);
                    curve[1][1] = path.getSegmentParam(i, 1);
                    curve[2][0] = path.getSegmentParam(i, 2);
                    curve[2][1] = path.getSegmentParam(i, 3);
                    curve[3][0] = path.getSegmentParam(i, 4);
                    curve[3][1] = path.getSegmentParam(i, 5);
                    prevSegment = addCubicSegment(motion, curve, segments, 
                                                  curves, prevSegment);
                    curPos[0] = path.getSegmentParam(i, 4);
                    curPos[1] = path.getSegmentParam(i, 5);
                    break;
                case Path.CLOSE:
                default:
                    if (prevSegment == null) {
                        prevSegment = new LeafMotionSegment(curPos[0],
                                                            curPos[1],
                                                            lastMove[0],
                                                            lastMove[1],
                                                            motion);
                    } else {
                        prevSegment = new LeafMotionSegment(prevSegment,
                                                            lastMove[0],
                                                            lastMove[1],
                                                            motion);
                    }
                    segments.addElement(prevSegment);
                    curPos[0] = lastMove[0];
                    curPos[1] = lastMove[1];
                    break;
                }
            }

            if (segments.size() == 0) {
                // This is a degenerate case, for a path with only a moveto or 
                // empty.
                segments.addElement(new LeafMotionSegment(curPos[0],
                                                          curPos[1],
                                                          curPos[0],
                                                          curPos[1],
                                                          motion));
            } 

            refValues.segments = new MotionSegment[segments.size()];
            segments.copyInto(refValues.segments);
        }

        return refValues;
    
public voidvalidateCoordinate(Animation anim, java.lang.String traitNamespace, java.lang.String traitName, java.lang.String value, float[] pt)
Parses a coordinate pair.

throws
DOMException with error code INVALID_ACCESS_ERR if the input value is incompatible with the given trait.

        float[] v = anim.parseFloatArrayTrait(traitName, value);
        if (v.length < 1 || v.length > 2) {
            throw anim.illegalTraitValue(traitName, value);
        }
        
        // x
        pt[0] = v[0];
        
        // translate y
        if (v.length > 1) {
            pt[1] = v[1];
        } else {
            pt[1] = v[0];
        }