159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.math;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.*;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>Matrix3f</code> defines a 3x3 matrix. Matrix data is maintained
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * internally and is accessible via the get and set methods. Convenience methods
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * are used for matrix operations as well as generating a matrix from a given
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * set of values.
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Mark Powell
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Joshua Slack
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic final class Matrix3f implements Savable, Cloneable, java.io.Serializable {
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    static final long serialVersionUID = 1;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Logger logger = Logger.getLogger(Matrix3f.class.getName());
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float m00, m01, m02;
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float m10, m11, m12;
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float m20, m21, m22;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final Matrix3f ZERO = new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0);
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final Matrix3f IDENTITY = new Matrix3f();
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Constructor instantiates a new <code>Matrix3f</code> object. The
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * initial values for the matrix is that of the identity matrix.
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f() {
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        loadIdentity();
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * constructs a matrix with the given values.
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m00
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            0x0 in the matrix.
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m01
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            0x1 in the matrix.
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m02
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            0x2 in the matrix.
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m10
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            1x0 in the matrix.
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m11
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            1x1 in the matrix.
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m12
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            1x2 in the matrix.
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m20
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            2x0 in the matrix.
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m21
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            2x1 in the matrix.
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param m22
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            2x2 in the matrix.
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f(float m00, float m01, float m02, float m10, float m11,
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float m12, float m20, float m21, float m22) {
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m00 = m00;
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m01 = m01;
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m02 = m02;
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m10 = m10;
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m11 = m11;
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m12 = m12;
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m20 = m20;
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m21 = m21;
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.m22 = m22;
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Copy constructor that creates a new <code>Matrix3f</code> object that
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * is the same as the provided matrix.
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mat
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to copy.
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f(Matrix3f mat) {
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        set(mat);
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Takes the absolute value of all matrix fields locally.
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void absoluteLocal() {
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = FastMath.abs(m00);
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = FastMath.abs(m01);
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = FastMath.abs(m02);
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = FastMath.abs(m10);
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 = FastMath.abs(m11);
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = FastMath.abs(m12);
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = FastMath.abs(m20);
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = FastMath.abs(m21);
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 = FastMath.abs(m22);
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>copy</code> transfers the contents of a given matrix to this
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * matrix. If a null matrix is supplied, this matrix is set to the identity
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * matrix.
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param matrix
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to copy.
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f set(Matrix3f matrix) {
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (null == matrix) {
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            loadIdentity();
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m00 = matrix.m00;
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m01 = matrix.m01;
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m02 = matrix.m02;
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m10 = matrix.m10;
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m11 = matrix.m11;
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m12 = matrix.m12;
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m20 = matrix.m20;
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m21 = matrix.m21;
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m22 = matrix.m22;
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>get</code> retrieves a value from the matrix at the given
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * position. If the position is invalid a <code>JmeException</code> is
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * thrown.
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the row index.
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param j
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the colum index.
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the value at (i, j).
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @SuppressWarnings("fallthrough")
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float get(int i, int j) {
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (i) {
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0:
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (j) {
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 0:
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m00;
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 1:
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m01;
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 2:
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m02;
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 1:
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (j) {
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 0:
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m10;
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 1:
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m11;
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 2:
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m12;
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 2:
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (j) {
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 0:
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m20;
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 1:
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m21;
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 2:
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return m22;
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("Invalid matrix index.");
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        throw new IllegalArgumentException("Invalid indices into matrix.");
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>get(float[])</code> returns the matrix in row-major or column-major order.
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param data
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *      The array to return the data into. This array can be 9 or 16 floats in size.
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *      Only the upper 3x3 are assigned to in the case of a 16 element array.
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param rowMajor
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *      True for row major storage in the array (translation in elements 3, 7, 11 for a 4x4),
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *      false for column major (translation in elements 12, 13, 14 for a 4x4).
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void get(float[] data, boolean rowMajor) {
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data.length == 9) {
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (rowMajor) {
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[0] = m00;
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[1] = m01;
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[2] = m02;
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[3] = m10;
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[4] = m11;
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[5] = m12;
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[6] = m20;
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[7] = m21;
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[8] = m22;
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[0] = m00;
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[1] = m10;
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[2] = m20;
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[3] = m01;
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[4] = m11;
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[5] = m21;
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[6] = m02;
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[7] = m12;
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[8] = m22;
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (data.length == 16) {
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (rowMajor) {
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[0] = m00;
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[1] = m01;
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[2] = m02;
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[4] = m10;
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[5] = m11;
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[6] = m12;
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[8] = m20;
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[9] = m21;
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[10] = m22;
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[0] = m00;
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[1] = m10;
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[2] = m20;
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[4] = m01;
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[5] = m11;
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[6] = m21;
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[8] = m02;
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[9] = m12;
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data[10] = m22;
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get().");
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>getColumn</code> returns one of three columns specified by the
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * parameter. This column is returned as a <code>Vector3f</code> object.
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the column to retrieve. Must be between 0 and 2.
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the column specified by the index.
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f getColumn(int i) {
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return getColumn(i, null);
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>getColumn</code> returns one of three columns specified by the
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * parameter. This column is returned as a <code>Vector3f</code> object.
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the column to retrieve. Must be between 0 and 2.
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector object to store the result in. if null, a new one
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            is created.
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the column specified by the index.
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f getColumn(int i, Vector3f store) {
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Vector3f();
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (i) {
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0:
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.x = m00;
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.y = m10;
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.z = m20;
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 1:
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.x = m01;
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.y = m11;
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.z = m21;
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 2:
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.x = m02;
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.y = m12;
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.z = m22;
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.warning("Invalid column index.");
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("Invalid column index. " + i);
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>getColumn</code> returns one of three rows as specified by the
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * parameter. This row is returned as a <code>Vector3f</code> object.
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the row to retrieve. Must be between 0 and 2.
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the row specified by the index.
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f getRow(int i) {
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return getRow(i, null);
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>getRow</code> returns one of three rows as specified by the
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * parameter. This row is returned as a <code>Vector3f</code> object.
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the row to retrieve. Must be between 0 and 2.
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector object to store the result in. if null, a new one
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            is created.
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the row specified by the index.
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f getRow(int i, Vector3f store) {
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Vector3f();
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (i) {
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0:
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.x = m00;
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.y = m01;
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.z = m02;
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 1:
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.x = m10;
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.y = m11;
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.z = m12;
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 2:
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.x = m20;
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.y = m21;
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                store.z = m22;
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.warning("Invalid row index.");
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("Invalid row index. " + i);
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>toFloatBuffer</code> returns a FloatBuffer object that contains
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the matrix data.
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return matrix data as a FloatBuffer.
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public FloatBuffer toFloatBuffer() {
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer fb = BufferUtils.createFloatBuffer(9);
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fb.put(m00).put(m01).put(m02);
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fb.put(m10).put(m11).put(m12);
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fb.put(m20).put(m21).put(m22);
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fb.rewind();
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return fb;
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * data.
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fb
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the buffer to fill, starting at current position. Must have
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            room for 9 more floats.
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return matrix data as a FloatBuffer. (position is advanced by 9 and any
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *         limit set is not changed).
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public FloatBuffer fillFloatBuffer(FloatBuffer fb, boolean columnMajor) {
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        if (columnMajor){
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            fb.put(m00).put(m10).put(m20);
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            fb.put(m01).put(m11).put(m21);
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            fb.put(m02).put(m12).put(m22);
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }else{
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            fb.put(m00).put(m01).put(m02);
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            fb.put(m10).put(m11).put(m12);
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            fb.put(m20).put(m21).put(m22);
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TempVars vars = TempVars.get();
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fillFloatArray(vars.matrixWrite, columnMajor);
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fb.put(vars.matrixWrite, 0, 9);
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vars.release();
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return fb;
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void fillFloatArray(float[] f, boolean columnMajor) {
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (columnMajor) {
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 0] = m00;
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 1] = m10;
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 2] = m20;
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 3] = m01;
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 4] = m11;
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 5] = m21;
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 6] = m02;
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 7] = m12;
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 8] = m22;
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 0] = m00;
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 1] = m01;
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 2] = m02;
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 3] = m10;
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 4] = m11;
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 5] = m12;
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 6] = m20;
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 7] = m21;
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            f[ 8] = m22;
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>setColumn</code> sets a particular column of this matrix to that
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * represented by the provided vector.
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the column to set.
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param column
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the data to set.
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f setColumn(int i, Vector3f column) {
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (column == null) {
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("Column is null. Ignoring.");
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return this;
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (i) {
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0:
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m00 = column.x;
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m10 = column.y;
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m20 = column.z;
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 1:
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m01 = column.x;
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m11 = column.y;
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m21 = column.z;
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 2:
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m02 = column.x;
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m12 = column.y;
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m22 = column.z;
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.warning("Invalid column index.");
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("Invalid column index. " + i);
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>setRow</code> sets a particular row of this matrix to that
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * represented by the provided vector.
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the row to set.
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param row
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the data to set.
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f setRow(int i, Vector3f row) {
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (row == null) {
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("Row is null. Ignoring.");
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return this;
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (i) {
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0:
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m00 = row.x;
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m01 = row.y;
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m02 = row.z;
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 1:
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m10 = row.x;
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m11 = row.y;
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m12 = row.z;
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 2:
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m20 = row.x;
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m21 = row.y;
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m22 = row.z;
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.warning("Invalid row index.");
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("Invalid row index. " + i);
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>set</code> places a given value into the matrix at the given
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * position. If the position is invalid a <code>JmeException</code> is
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * thrown.
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param i
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the row index.
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param j
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the colum index.
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param value
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the value for (i, j).
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @SuppressWarnings("fallthrough")
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f set(int i, int j, float value) {
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (i) {
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0:
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (j) {
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 0:
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m00 = value;
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 1:
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m01 = value;
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 2:
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m02 = value;
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 1:
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (j) {
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 0:
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m10 = value;
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 1:
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m11 = value;
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 2:
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m12 = value;
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 2:
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (j) {
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 0:
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m20 = value;
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 1:
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m21 = value;
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case 2:
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        m22 = value;
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        return this;
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("Invalid matrix index.");
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        throw new IllegalArgumentException("Invalid indices into matrix.");
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>set</code> sets the values of the matrix to those supplied by the
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * 3x3 two dimenion array.
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param matrix
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the new values of the matrix.
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws JmeException
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *             if the array is not of size 9.
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f set(float[][] matrix) {
58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (matrix.length != 3 || matrix[0].length != 3) {
58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException(
58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    "Array must be of size 9.");
59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = matrix[0][0];
59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = matrix[0][1];
59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = matrix[0][2];
59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = matrix[1][0];
59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 = matrix[1][1];
59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = matrix[1][2];
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = matrix[2][0];
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = matrix[2][1];
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 = matrix[2][2];
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Recreate Matrix using the provided axis.
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param uAxis
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            Vector3f
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vAxis
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            Vector3f
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param wAxis
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            Vector3f
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void fromAxes(Vector3f uAxis, Vector3f vAxis, Vector3f wAxis) {
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = uAxis.x;
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = uAxis.y;
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = uAxis.z;
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = vAxis.x;
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 = vAxis.y;
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = vAxis.z;
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = wAxis.x;
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = wAxis.y;
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 = wAxis.z;
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>set</code> sets the values of this matrix from an array of
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * values assuming that the data is rowMajor order;
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param matrix
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to set the value to.
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f set(float[] matrix) {
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return set(matrix, true);
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>set</code> sets the values of this matrix from an array of
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * values;
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param matrix
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to set the value to.
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param rowMajor
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            whether the incoming data is in row or column major order.
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f set(float[] matrix, boolean rowMajor) {
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (matrix.length != 9) {
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException(
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    "Array must be of size 9.");
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (rowMajor) {
65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m00 = matrix[0];
65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m01 = matrix[1];
66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m02 = matrix[2];
66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m10 = matrix[3];
66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m11 = matrix[4];
66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m12 = matrix[5];
66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m20 = matrix[6];
66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m21 = matrix[7];
66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m22 = matrix[8];
66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m00 = matrix[0];
66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m01 = matrix[3];
67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m02 = matrix[6];
67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m10 = matrix[1];
67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m11 = matrix[4];
67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m12 = matrix[7];
67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m20 = matrix[2];
67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m21 = matrix[5];
67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            m22 = matrix[8];
67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>set</code> defines the values of the matrix based on a supplied
68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>Quaternion</code>. It should be noted that all previous values
68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * will be overridden.
68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param quaternion
68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the quaternion to create a rotational matrix from.
68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f set(Quaternion quaternion) {
69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return quaternion.toRotationMatrix(this);
69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>loadIdentity</code> sets this matrix to the identity matrix.
69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Where all values are zero except those along the diagonal which are one.
69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void loadIdentity() {
70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = m02 = m10 = m12 = m20 = m21 = 0;
70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = m11 = m22 = 1;
70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return true if this matrix is identity
70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isIdentity() {
70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (m00 == 1 && m01 == 0 && m02 == 0)
71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                && (m10 == 0 && m11 == 1 && m12 == 0)
71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                && (m20 == 0 && m21 == 0 && m22 == 1);
71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>fromAngleAxis</code> sets this matrix4f to the values specified
71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * by an angle and an axis of rotation.  This method creates an object, so
71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * use fromAngleNormalAxis if your axis is already normalized.
71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param angle
72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the angle to rotate (in radians).
72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param axis
72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the axis of rotation.
72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void fromAngleAxis(float angle, Vector3f axis) {
72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f normAxis = axis.normalize();
72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fromAngleNormalAxis(angle, normAxis);
72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>fromAngleNormalAxis</code> sets this matrix4f to the values
73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * specified by an angle and a normalized axis of rotation.
73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param angle
73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the angle to rotate (in radians).
73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param axis
73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the axis of rotation (already normalized).
73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void fromAngleNormalAxis(float angle, Vector3f axis) {
73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fCos = FastMath.cos(angle);
74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fSin = FastMath.sin(angle);
74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fOneMinusCos = ((float) 1.0) - fCos;
74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fX2 = axis.x * axis.x;
74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fY2 = axis.y * axis.y;
74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fZ2 = axis.z * axis.z;
74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fXYM = axis.x * axis.y * fOneMinusCos;
74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fXZM = axis.x * axis.z * fOneMinusCos;
74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fYZM = axis.y * axis.z * fOneMinusCos;
74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fXSin = axis.x * fSin;
74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fYSin = axis.y * fSin;
75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fZSin = axis.z * fSin;
75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = fX2 * fOneMinusCos + fCos;
75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = fXYM - fZSin;
75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = fXZM + fYSin;
75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = fXYM + fZSin;
75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 = fY2 * fOneMinusCos + fCos;
75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = fYZM - fXSin;
75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = fXZM - fYSin;
75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = fYZM + fXSin;
76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 = fZ2 * fOneMinusCos + fCos;
76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>mult</code> multiplies this matrix by a given matrix. The result
76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * matrix is returned as a new object. If the given matrix is null, a null
76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * matrix is returned.
76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mat
76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to multiply this matrix by.
77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the result matrix.
77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f mult(Matrix3f mat) {
77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return mult(mat, null);
77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>mult</code> multiplies this matrix by a given matrix. The result
77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * matrix is returned as a new object.
77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mat
78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to multiply this matrix by.
78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param product
78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to store the result in. if null, a new matrix3f is
78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            created.  It is safe for mat and product to be the same object.
78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a matrix3f object containing the result of this operation
78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f mult(Matrix3f mat, Matrix3f product) {
78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float temp00, temp01, temp02;
79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float temp10, temp11, temp12;
79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float temp20, temp21, temp22;
79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (product == null) {
79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            product = new Matrix3f();
79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20;
79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21;
79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22;
79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp10 = m10 * mat.m00 + m11 * mat.m10 + m12 * mat.m20;
80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp11 = m10 * mat.m01 + m11 * mat.m11 + m12 * mat.m21;
80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp12 = m10 * mat.m02 + m11 * mat.m12 + m12 * mat.m22;
80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp20 = m20 * mat.m00 + m21 * mat.m10 + m22 * mat.m20;
80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp21 = m20 * mat.m01 + m21 * mat.m11 + m22 * mat.m21;
80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        temp22 = m20 * mat.m02 + m21 * mat.m12 + m22 * mat.m22;
80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m00 = temp00;
80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m01 = temp01;
80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m02 = temp02;
80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m10 = temp10;
81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m11 = temp11;
81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m12 = temp12;
81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m20 = temp20;
81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m21 = temp21;
81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.m22 = temp22;
81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return product;
81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>mult</code> multiplies this matrix by a given
82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>Vector3f</code> object. The result vector is returned. If the
82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * given vector is null, null will be returned.
82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vec
82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to multiply this matrix by.
82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the result vector.
82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f mult(Vector3f vec) {
82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return mult(vec, null);
83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in
83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * product.
83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vec
83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            The Vector3f to multiply.
83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param product
83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            The Vector3f to store the result, it is safe for this to be
84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the same as vec.
84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The given product vector.
84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f mult(Vector3f vec, Vector3f product) {
84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (null == product) {
84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            product = new Vector3f();
84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float x = vec.x;
85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float y = vec.y;
85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float z = vec.z;
85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.x = m00 * x + m01 * y + m02 * z;
85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.y = m10 * x + m11 * y + m12 * z;
85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        product.z = m20 * x + m21 * y + m22 * z;
85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return product;
85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>multLocal</code> multiplies this matrix internally by
86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * a given float scale factor.
86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale
86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the value to scale by.
86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this Matrix3f
86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f multLocal(float scale) {
86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 *= scale;
86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 *= scale;
87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 *= scale;
87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 *= scale;
87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 *= scale;
87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 *= scale;
87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 *= scale;
87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 *= scale;
87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 *= scale;
87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>multLocal</code> multiplies this matrix by a given
88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>Vector3f</code> object. The result vector is stored inside the
88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * passed vector, then returned . If the given vector is null, null will be
88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * returned.
88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vec
88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the vector to multiply this matrix by.
88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The passed vector after multiplication
88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f multLocal(Vector3f vec) {
89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vec == null) {
89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float x = vec.x;
89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float y = vec.y;
89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vec.x = m00 * x + m01 * y + m02 * vec.z;
89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vec.y = m10 * x + m11 * y + m12 * vec.z;
89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vec.z = m20 * x + m21 * y + m22 * vec.z;
89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return vec;
90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>mult</code> multiplies this matrix by a given matrix. The result
90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * matrix is saved in the current matrix. If the given matrix is null,
90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * nothing happens. The current matrix is returned. This is equivalent to
90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * this*=mat
90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mat
90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the matrix to multiply this matrix by.
91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return This matrix, after the multiplication
91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f multLocal(Matrix3f mat) {
91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return mult(mat, this);
91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Transposes this matrix in place. Returns this matrix for chaining
91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return This matrix after transpose
92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f transposeLocal() {
92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        float[] tmp = new float[9];
92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        get(tmp, false);
92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        set(tmp, true);
92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float tmp = m01;
92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = m10;
92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = tmp;
92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tmp = m02;
93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = m20;
93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = tmp;
93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tmp = m12;
93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = m21;
93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = tmp;
93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Inverts this matrix as a new Matrix3f.
94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The new inverse matrix
94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f invert() {
94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return invert(null);
94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Inverts this matrix and stores it in the given store.
95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The store
95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f invert(Matrix3f store) {
95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Matrix3f();
95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float det = determinant();
96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (FastMath.abs(det) <= FastMath.FLT_EPSILON) {
96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return store.zero();
96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m00 = m11 * m22 - m12 * m21;
96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m01 = m02 * m21 - m01 * m22;
96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m02 = m01 * m12 - m02 * m11;
96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m10 = m12 * m20 - m10 * m22;
96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m11 = m00 * m22 - m02 * m20;
97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m12 = m02 * m10 - m00 * m12;
97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m20 = m10 * m21 - m11 * m20;
97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m21 = m01 * m20 - m00 * m21;
97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m22 = m00 * m11 - m01 * m10;
97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.multLocal(1f / det);
97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
97859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
97959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
98059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Inverts this matrix locally.
98159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
98259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this
98359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
98459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f invertLocal() {
98559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float det = determinant();
98659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (FastMath.abs(det) <= 0f) {
98759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return zero();
98859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
98959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
99059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f00 = m11 * m22 - m12 * m21;
99159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f01 = m02 * m21 - m01 * m22;
99259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f02 = m01 * m12 - m02 * m11;
99359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f10 = m12 * m20 - m10 * m22;
99459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f11 = m00 * m22 - m02 * m20;
99559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f12 = m02 * m10 - m00 * m12;
99659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f20 = m10 * m21 - m11 * m20;
99759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f21 = m01 * m20 - m00 * m21;
99859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float f22 = m00 * m11 - m01 * m10;
99959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
100059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = f00;
100159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = f01;
100259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = f02;
100359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = f10;
100459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 = f11;
100559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = f12;
100659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = f20;
100759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = f21;
100859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 = f22;
100959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        multLocal(1f / det);
101159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
101259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
101359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
101559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a new matrix representing the adjoint of this matrix.
101659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
101759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The adjoint matrix
101859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
101959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f adjoint() {
102059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return adjoint(null);
102159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
102259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
102359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
102459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Places the adjoint of this matrix in store (creates store if null.)
102559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
102659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store
102759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            The matrix to store the result in.  If null, a new matrix is created.
102859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return store
102959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
103059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f adjoint(Matrix3f store) {
103159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
103259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Matrix3f();
103359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
103459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
103559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m00 = m11 * m22 - m12 * m21;
103659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m01 = m02 * m21 - m01 * m22;
103759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m02 = m01 * m12 - m02 * m11;
103859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m10 = m12 * m20 - m10 * m22;
103959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m11 = m00 * m22 - m02 * m20;
104059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m12 = m02 * m10 - m00 * m12;
104159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m20 = m10 * m21 - m11 * m20;
104259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m21 = m01 * m20 - m00 * m21;
104359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.m22 = m00 * m11 - m01 * m10;
104459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
104559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
104659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
104759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
104859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
104959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>determinant</code> generates the determinant of this matrix.
105059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
105159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the determinant
105259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
105359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float determinant() {
105459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fCo00 = m11 * m22 - m12 * m21;
105559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fCo10 = m12 * m20 - m10 * m22;
105659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fCo20 = m10 * m21 - m11 * m20;
105759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float fDet = m00 * fCo00 + m01 * fCo10 + m02 * fCo20;
105859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return fDet;
105959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
106059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
106159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
106259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Sets all of the values in this matrix to zero.
106359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
106459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this matrix
106559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
106659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f zero() {
106759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = m01 = m02 = m10 = m11 = m12 = m20 = m21 = m22 = 0.0f;
106859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this;
106959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
107059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
107159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
107259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>transpose</code> <b>locally</b> transposes this Matrix.
107359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This is inconsistent with general value vs local semantics, but is
107459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * preserved for backwards compatibility. Use transposeNew() to transpose
107559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to a new object (value).
107659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
107759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return this object for chaining.
107859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
107959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f transpose() {
108059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return transposeLocal();
108159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
108259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
108359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
108459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>transposeNew</code> returns a transposed version of this matrix.
108559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
108659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The new Matrix3f object.
108759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
108859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f transposeNew() {
108959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Matrix3f ret = new Matrix3f(m00, m10, m20, m01, m11, m21, m02, m12, m22);
109059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return ret;
109159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
109259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
109359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
109459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>toString</code> returns the string representation of this object.
109559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * It is in a format of a 3x3 matrix. For example, an identity matrix would
109659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be represented by the following string. com.jme.math.Matrix3f <br>[<br>
109759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * 1.0  0.0  0.0 <br>
109859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * 0.0  1.0  0.0 <br>
109959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * 0.0  0.0  1.0 <br>]<br>
110059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
110159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the string representation of this object.
110259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
110359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
110459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public String toString() {
110559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        StringBuilder result = new StringBuilder("Matrix3f\n[\n");
110659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(" ");
110759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m00);
110859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append("  ");
110959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m01);
111059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append("  ");
111159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m02);
111259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(" \n");
111359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(" ");
111459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m10);
111559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append("  ");
111659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m11);
111759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append("  ");
111859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m12);
111959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(" \n");
112059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(" ");
112159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m20);
112259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append("  ");
112359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m21);
112459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append("  ");
112559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(m22);
112659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        result.append(" \n]");
112759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return result.toString();
112859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
112959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
113059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
113159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
113259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>hashCode</code> returns the hash code value as an integer and is
113359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * supported for the benefit of hashing based collection classes such as
113459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Hashtable, HashMap, HashSet etc.
113559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
113659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the hashcode for this instance of Matrix4f.
113759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Object#hashCode()
113859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
113959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
114059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int hashCode() {
114159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int hash = 37;
114259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m00);
114359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m01);
114459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m02);
114559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
114659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m10);
114759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m11);
114859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m12);
114959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
115059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m20);
115159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m21);
115259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        hash = 37 * hash + Float.floatToIntBits(m22);
115359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
115459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return hash;
115559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
115659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
115759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
115859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * are these two matrices the same? they are is they both have the same mXX values.
115959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
116059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param o
116159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the object to compare for equality
116259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return true if they are equal
116359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
116459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
116559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean equals(Object o) {
116659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!(o instanceof Matrix3f) || o == null) {
116759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
116859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
116959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
117059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (this == o) {
117159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return true;
117259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
117359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
117459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Matrix3f comp = (Matrix3f) o;
117559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m00, comp.m00) != 0) {
117659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
117759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
117859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m01, comp.m01) != 0) {
117959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
118059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
118159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m02, comp.m02) != 0) {
118259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
118359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
118459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
118559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m10, comp.m10) != 0) {
118659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
118759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
118859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m11, comp.m11) != 0) {
118959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
119059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
119159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m12, comp.m12) != 0) {
119259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
119359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
119459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
119559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m20, comp.m20) != 0) {
119659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
119759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
119859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m21, comp.m21) != 0) {
119959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
120059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
120159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.compare(m22, comp.m22) != 0) {
120259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
120359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
120459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
120559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return true;
120659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
120759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
120859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void write(JmeExporter e) throws IOException {
120959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        OutputCapsule cap = e.getCapsule(this);
121059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m00, "m00", 1);
121159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m01, "m01", 0);
121259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m02, "m02", 0);
121359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m10, "m10", 0);
121459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m11, "m11", 1);
121559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m12, "m12", 0);
121659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m20, "m20", 0);
121759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m21, "m21", 0);
121859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cap.write(m22, "m22", 1);
121959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
122059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
122159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void read(JmeImporter e) throws IOException {
122259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        InputCapsule cap = e.getCapsule(this);
122359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 = cap.readFloat("m00", 1);
122459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 = cap.readFloat("m01", 0);
122559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 = cap.readFloat("m02", 0);
122659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 = cap.readFloat("m10", 0);
122759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 = cap.readFloat("m11", 1);
122859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 = cap.readFloat("m12", 0);
122959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 = cap.readFloat("m20", 0);
123059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 = cap.readFloat("m21", 0);
123159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 = cap.readFloat("m22", 1);
123259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
123359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
123459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
123559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * A function for creating a rotation matrix that rotates a vector called
123659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * "start" into another vector called "end".
123759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
123859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param start
123959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            normalized non-zero starting vector
124059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param end
124159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            normalized non-zero ending vector
124259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see "Tomas M�ller, John Hughes \"Efficiently Building a Matrix to Rotate \
124359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *      One Vector to Another\" Journal of Graphics Tools, 4(4):1-4, 1999"
124459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
124559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void fromStartEndVectors(Vector3f start, Vector3f end) {
124659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f v = new Vector3f();
124759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float e, h, f;
124859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
124959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        start.cross(end, v);
125059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        e = start.dot(end);
125159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        f = (e < 0) ? -e : e;
125259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
125359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // if "from" and "to" vectors are nearly parallel
125459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (f > 1.0f - FastMath.ZERO_TOLERANCE) {
125559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f u = new Vector3f();
125659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f x = new Vector3f();
125759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float c1, c2, c3; /* coefficients for later use */
125859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int i, j;
125959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
126059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            x.x = (start.x > 0.0) ? start.x : -start.x;
126159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            x.y = (start.y > 0.0) ? start.y : -start.y;
126259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            x.z = (start.z > 0.0) ? start.z : -start.z;
126359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
126459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (x.x < x.y) {
126559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (x.x < x.z) {
126659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.x = 1.0f;
126759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.y = x.z = 0.0f;
126859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
126959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.z = 1.0f;
127059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.x = x.y = 0.0f;
127159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
127259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
127359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (x.y < x.z) {
127459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.y = 1.0f;
127559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.x = x.z = 0.0f;
127659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
127759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.z = 1.0f;
127859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    x.x = x.y = 0.0f;
127959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
128059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
128159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
128259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            u.x = x.x - start.x;
128359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            u.y = x.y - start.y;
128459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            u.z = x.z - start.z;
128559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            v.x = x.x - end.x;
128659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            v.y = x.y - end.y;
128759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            v.z = x.z - end.z;
128859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
128959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            c1 = 2.0f / u.dot(u);
129059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            c2 = 2.0f / v.dot(v);
129159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            c3 = c1 * c2 * u.dot(v);
129259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
129359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (i = 0; i < 3; i++) {
129459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                for (j = 0; j < 3; j++) {
129559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    float val = -c1 * u.get(i) * u.get(j) - c2 * v.get(i)
129659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            * v.get(j) + c3 * v.get(i) * u.get(j);
129759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    set(i, j, val);
129859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
129959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                float val = get(i, i);
130059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                set(i, i, val + 1.0f);
130159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
130259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
130359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // the most common case, unless "start"="end", or "start"=-"end"
130459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float hvx, hvz, hvxy, hvxz, hvyz;
130559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            h = 1.0f / (1.0f + e);
130659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            hvx = h * v.x;
130759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            hvz = h * v.z;
130859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            hvxy = hvx * v.y;
130959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            hvxz = hvx * v.z;
131059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            hvyz = hvz * v.y;
131159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(0, 0, e + hvx * v.x);
131259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(0, 1, hvxy - v.z);
131359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(0, 2, hvxz + v.y);
131459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
131559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(1, 0, hvxy + v.z);
131659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(1, 1, e + h * v.y * v.y);
131759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(1, 2, hvyz - v.x);
131859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
131959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(2, 0, hvxz - v.y);
132059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(2, 1, hvyz + v.x);
132159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            set(2, 2, e + hvz * v.z);
132259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
132359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
132459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
132559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
132659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>scale</code> scales the operation performed by this matrix on a
132759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * per-component basis.
132859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
132959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale
133059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *         The scale applied to each of the X, Y and Z output values.
133159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
133259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void scale(Vector3f scale) {
133359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m00 *= scale.x;
133459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m10 *= scale.x;
133559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m20 *= scale.x;
133659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m01 *= scale.y;
133759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m11 *= scale.y;
133859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m21 *= scale.y;
133959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m02 *= scale.z;
134059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m12 *= scale.z;
134159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        m22 *= scale.z;
134259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
134359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
134459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    static boolean equalIdentity(Matrix3f mat) {
134559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m00 - 1) > 1e-4) {
134659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
134759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
134859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m11 - 1) > 1e-4) {
134959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
135059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
135159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m22 - 1) > 1e-4) {
135259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
135359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
135459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
135559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m01) > 1e-4) {
135659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
135759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
135859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m02) > 1e-4) {
135959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
136059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
136159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
136259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m10) > 1e-4) {
136359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
136459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
136559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m12) > 1e-4) {
136659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
136759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
136859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
136959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m20) > 1e-4) {
137059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
137159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
137259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(mat.m21) > 1e-4) {
137359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return false;
137459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
137559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
137659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return true;
137759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
137859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
137959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
138059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Matrix3f clone() {
138159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        try {
138259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (Matrix3f) super.clone();
138359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } catch (CloneNotSupportedException e) {
138459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new AssertionError(); // can not happen
138559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
138659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
138759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
1388