FileDocCategorySizeDatePackage
MotionRefValues.javaAPI DocphoneME MR2 API (J2ME)7798Wed May 02 18:00:36 BST 2007com.sun.perseus.model

MotionRefValues

public class MotionRefValues extends Object implements RefValues
version
$Id: MotionRefValues.java,v 1.3 2006/06/29 10:47:33 ln156897 Exp $

Fields Summary
MotionSegment[]
segments
This RefValues Segments. They can be CompositeSegment or MotionSegment instances.
float[]
w
A working array to return a value from the compute method.
float
length
Used to store the length of this RefValues
float[]
nSegLength
Used to store the normalized length of each segment
float[]
segLength
Used to store the length of each segment
AnimateMotion
motion
The associated AnimateMotion
Constructors Summary
public MotionRefValues(AnimateMotion motion)
Builds a new MotionRefValues associated with the given AnimateMotion instance.

param
motion the associated AnimateMotion

        this.motion = motion;
    
Methods Summary
public java.lang.Object[]compute(int si, float p)
Computes the value for the input interpolated values. There should be as many entries in the return array as there are components in the RefValues.

param
si the current segment index
param
p the current penetration
param
the interpolated value.

        segments[si].compute(p, w);
        return w;
    
public intgetComponents()

return
the number of components. There is an array of float for each component.

        return segments[0].getStart().length;
    
public floatgetLength()
Computes the length of the RefValues. This is meant for paced timing computation.

return
the total length of refValues, along each component. Therefore, there are as many entries in the returned array as there are components in RefValues.

        return length;
    
public floatgetLength(int si)
Computes the length of segment at index si

param
si the segment index.

        return segLength[si];
    
public SegmentgetSegment(int i)

param
i requested segment index.
return
Segment at index i

        return segments[i];
    
public voidgetSegmentAtDist(float[] sisp, float dist)
Computes the segment index for the given normalized distance.

param
sisp a float array where the mapped si and sp values should be stored.
param
dist the distance for which the segment indices should be computed. This value is normalized to the [0, 1] interval.

        if (dist >= 1) {
            sisp[0] = segments.length - 1;
            sisp[1] = 1;
            return;
        }

        if (dist < 0) {
            sisp[0] = 0;
            sisp[1] = 0;
            return;
        }

        int i = 0;
        float prevSegLength = 0;
        for (; i < nSegLength.length - 1; i++) {
            if (dist < nSegLength[i]) {
                break;
            }
            prevSegLength = nSegLength[i];
        }
        
        // Now, compute the penetration in the segment.
        float p = 1;

        if (nSegLength[i] > prevSegLength) {
            p = 
                (dist - prevSegLength) 
                / 
                (nSegLength[i] - prevSegLength);
        }
        
        sisp[0] = i;
        sisp[1] = p;
    
public intgetSegments()

return
the number of segments in refValues

        return segments.length;
    
public voidinitialize()
Should be called after the RefValue's configuration is complete to give the implementation a chance to initialize internal data and cache values.

        // Initialize the working buffer
        final int nc = segments[0].getStart().length;
        w = new float[nc][];
        for (int ci = 0; ci < nc; ci++) {
            // There is one dimension per component for motion
            // values, which are matrix values.
            w[ci] = new float[1];
        }

        // Initialize sub-segments.        
        final int ns = segments.length;
        for (int si = 0; si < ns; si++) {
            segments[si].initialize();
        }

        // Initialize cached length values.
        nSegLength = new float[ns];
        segLength = new float[ns];
        
        for (int si = 0; si < segments.length; si++) {
            segLength[si] = segments[si].getLength();
            length += segLength[si];
        }

        // Now, initialize the normalized segment lengths array
        if (length > 0) {
            float curLength = 0;
            for (int si = 0; si < ns - 1; si++) {
                curLength += segLength[si];
                nSegLength[si] = curLength / length;
            }
        } else {
            for (int si = 0; si < ns - 1; si++) {
                nSegLength[si] = 0;
            }
        }
        
        // Make sure that, in all cases, the last value is 1.
        nSegLength[nSegLength.length - 1] = 1;        
    
public voidmakeDiscrete()
Adds a new time segment so accomodate for discreet behavior. If there is only one segment for discreet animations, the last value is never shown. To accomodate for that, this method should add a segment to the RefValues so that the last animation value is shown during the last value interval of a discreet animation.

        MotionSegment[] tmpSegments = new MotionSegment[segments.length + 1];
        System.arraycopy(segments, 0, tmpSegments, 0, segments.length);
        Segment lastSeg = segments[segments.length - 1];
        float[][] end = (float[][]) lastSeg.getEnd();
        LeafMotionSegment newSeg = new LeafMotionSegment(end[4][0],
                                                         end[5][0],
                                                         end[4][0],
                                                         end[5][0],
                                                         motion);
        tmpSegments[tmpSegments.length - 1] = newSeg;
        segments = tmpSegments;