001    /*
002    *
003    
004    Licensed under the Apache License, Version 2.0 (the "License");
005    you may not use this file except in compliance with the License.
006    You may obtain a copy of the License at
007    
008       http://www.apache.org/licenses/LICENSE-2.0
009    
010    Unless required by applicable law or agreed to in writing, software
011    distributed under the License is distributed on an "AS IS" BASIS,
012    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013    See the License for the specific language governing permissions and
014    limitations under the License.
015    */
016    
017    package railo.runtime.img.vecmath;
018    
019    /**
020     * Vector math package, converted to look similar to javax.vecmath.
021     */
022    public class Quat4f extends Tuple4f {
023    
024            public Quat4f() {
025                    this( 0, 0, 0, 0 );
026            }
027            
028            public Quat4f( float[] x ) {
029                    this.x = x[0];
030                    this.y = x[1];
031                    this.z = x[2];
032                    this.w = x[3];
033            }
034    
035            public Quat4f( float x, float y, float z, float w ) {
036                    this.x = x;
037                    this.y = y;
038                    this.z = z;
039                    this.w = w;
040            }
041    
042            public Quat4f( Quat4f t ) {
043                    this.x = t.x;
044                    this.y = t.y;
045                    this.z = t.z;
046                    this.w = t.w;
047            }
048    
049            public Quat4f( Tuple4f t ) {
050                    this.x = t.x;
051                    this.y = t.y;
052                    this.z = t.z;
053                    this.w = t.w;
054            }
055    
056            public void set( AxisAngle4f a ) {
057                    float halfTheta = a.angle * 0.5f;
058                    float cosHalfTheta = (float)Math.cos(halfTheta);
059                    float sinHalfTheta = (float)Math.sin(halfTheta);
060                    x = a.x * sinHalfTheta;
061                    y = a.y * sinHalfTheta;
062                    z = a.z * sinHalfTheta;
063                    w = cosHalfTheta;
064            }
065    
066    /*
067            public void EulerToQuaternion(float roll, float pitch, float yaw)
068            {
069                    float cr, cp, cy, sr, sp, sy, cpcy, spsy;
070                    cr = cos(roll/2);
071                    cp = cos(pitch/2);
072                    cy = cos(yaw/2);
073                    sr = sin(roll/2);
074                    sp = sin(pitch/2);
075                    sy = sin(yaw/2);
076                    cpcy = cp * cy;
077                    spsy = sp * sy;
078                    w = cr * cpcy + sr * spsy;
079                    x = sr * cpcy - cr * spsy;
080                    y = cr * sp * cy + sr * cp * sy;
081                    z = cr * cp * sy - sr * sp * cy;
082            }
083    */
084    
085            public void normalize() {
086                    float d = 1.0f/( x*x+y*y+z*z+w*w );
087                    x *= d;
088                    y *= d;
089                    z *= d;
090                    w *= d;
091            }
092    
093    /*
094            public void mul( Quat4f q ) {
095                    Quat4f q3 = new Quat4f();
096                    Vector3f vectorq1 = new Vector3f( x, y, z );
097                    Vector3f vectorq2 = new Vector3f( q.x, q.y, q.z );
098    
099                    Vector3f tempvec1 = new Vector3f( vectorq1 );
100                    Vector3f tempvec2;
101                    Vector3f tempvec3;
102                    q3.w = (w*q.w) - tempvec1.dot(vectorq2);
103                    tempvec1.cross(vectorq2);
104                    tempvec2.x = w * q.x;
105                    tempvec2.y = w * q.y;
106                    tempvec2.z = w * q.z;
107                    tempvec3.x = q.w * x;
108                    tempvec3.y = q.w * y;
109                    tempvec3.z = q.w * z;
110                    q3.x = tempvec1.x + tempvec2.x + tempvec3.x;
111                    q3.y = tempvec1.y + tempvec2.y + tempvec3.y;
112                    q3.z = tempvec1.z + tempvec2.z + tempvec3.z;
113                    set(q3);
114            }
115    */
116    
117            public void set( Matrix4f m ) {
118                    float s;
119                    int i;
120    
121                    float tr = m.m00 + m.m11 + m.m22;
122    
123                    if (tr > 0.0) {
124                            s = (float)Math.sqrt(tr + 1.0f);
125                            w = s / 2.0f;
126                            s = 0.5f / s;
127                            x = (m.m12 - m.m21) * s;
128                            y = (m.m20 - m.m02) * s;
129                            z = (m.m01 - m.m10) * s;
130                    } else {                
131                            i = 0;
132                            if ( m.m11 > m.m00 ) {
133                                    i = 1;
134                                    if ( m.m22 > m.m11 ) {
135                                            i = 2;
136                                    } else {
137                                    }
138                            } else {
139                                    if ( m.m22 > m.m00 ) {
140                                            i = 2;
141                                    } else {
142                                    }
143                            }
144    
145                            switch ( i ) {
146                            case 0:
147                                    s = (float)Math.sqrt ((m.m00 - (m.m11 + m.m22)) + 1.0f);
148                                    x = s * 0.5f;
149                                    if (s != 0.0)
150                                            s = 0.5f / s;
151                                    w = (m.m12 - m.m21) * s;
152                                    y = (m.m01 + m.m10) * s;
153                                    z = (m.m02 + m.m20) * s;
154                                    break;
155                            case 1:
156                                    s = (float)Math.sqrt ((m.m11 - (m.m22 + m.m00)) + 1.0f);
157                                    y = s * 0.5f;
158                                    if (s != 0.0)
159                                            s = 0.5f / s;
160                                    w = (m.m20 - m.m02) * s;
161                                    z = (m.m12 + m.m21) * s;
162                                    x = (m.m10 + m.m01) * s;
163                                    break;
164                            case 2:
165                                    s = (float)Math.sqrt ((m.m00 - (m.m11 + m.m22)) + 1.0f);
166                                    z = s * 0.5f;
167                                    if (s != 0.0)
168                                            s = 0.5f / s;
169                                    w = (m.m01 - m.m10) * s;
170                                    x = (m.m20 + m.m02) * s;
171                                    y = (m.m21 + m.m12) * s;
172                                    break;
173                            }
174    
175                    }
176            }
177    
178    }