1e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/*
2e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Copyright 2013 The Android Open Source Project
3e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
4e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Licensed under the Apache License, Version 2.0 (the "License");
5e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * you may not use this file except in compliance with the License.
6e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * You may obtain a copy of the License at
7e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
8e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *      http://www.apache.org/licenses/LICENSE-2.0
9e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
10e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Unless required by applicable law or agreed to in writing, software
11e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * distributed under the License is distributed on an "AS IS" BASIS,
12e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * See the License for the specific language governing permissions and
14e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * limitations under the License.
15e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
16e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
17e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot#ifndef VECMATH_H_
18e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot#define VECMATH_H_
19e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
20e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot#include <math.h>
21e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot#include "JNIHelper.h"
22e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
23e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotnamespace ndk_helper
24e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot{
25e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
26e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/******************************************************************
27e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Helper class for vector math operations
28e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Currently all implementations are in pure C++.
29e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Each class is an opaque class so caller does not have a direct access
30e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * to each element. This is for an ease of future optimization to use vector operations.
31e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
32e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
33e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
34e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Vec2;
35e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Vec3;
36e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Vec4;
37e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Mat4;
38e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
39e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/******************************************************************
40e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * 2 elements vector class
41e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
42e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
43e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Vec2
44e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot{
45e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotprivate:
46e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float x_;
47e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float y_;
48e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
49e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotpublic:
50e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec3;
51e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec4;
52e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Mat4;
53e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Quaternion;
54e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
55e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2()
56e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
57e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = y_ = 0.f;
58e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
59e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
60e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2( const float fX, const float fY )
61e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
62e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = fX;
63e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = fY;
64e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
65e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
66e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2( const Vec2& vec )
67e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
68e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = vec.x_;
69e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = vec.y_;
70e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
71e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
72e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2( const float* pVec )
73e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
74e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = (*pVec++);
75e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = (*pVec++);
76e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
77e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
78e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Operators
79e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 operator*( const Vec2& rhs ) const
80e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
81e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
82e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs.x_;
83e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ * rhs.y_;
84e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
85e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
86e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
87e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 operator/( const Vec2& rhs ) const
88e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
89e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
90e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ / rhs.x_;
91e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ / rhs.y_;
92e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
93e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
94e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
95e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 operator+( const Vec2& rhs ) const
96e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
97e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
98e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ + rhs.x_;
99e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ + rhs.y_;
100e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
101e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
102e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
103e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 operator-( const Vec2& rhs ) const
104e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
105e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
106e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ - rhs.x_;
107e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ - rhs.y_;
108e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
109e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
110e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
111e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2& operator+=( const Vec2& rhs )
112e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
113e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ += rhs.x_;
114e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ += rhs.y_;
115e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
116e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
117e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
118e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2& operator-=( const Vec2& rhs )
119e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
120e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ -= rhs.x_;
121e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ -= rhs.y_;
122e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
123e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
124e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
125e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2& operator*=( const Vec2& rhs )
126e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
127e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ *= rhs.x_;
128e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ *= rhs.y_;
129e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
130e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
131e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
132e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2& operator/=( const Vec2& rhs )
133e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
134e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ /= rhs.x_;
135e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ /= rhs.y_;
136e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
137e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
138e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
139e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //External operators
140e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec2 operator-( const Vec2& rhs )
141e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
142e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return Vec2( rhs ) *= -1;
143e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
144e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
145e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec2 operator*( const float lhs, const Vec2& rhs )
146e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
147e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
148e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = lhs * rhs.x_;
149e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = lhs * rhs.y_;
150e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
151e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
152e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
153e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec2 operator/( const float lhs, const Vec2& rhs )
154e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
155e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
156e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = lhs / rhs.x_;
157e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = lhs / rhs.y_;
158e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
159e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
160e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
161e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Operators with float
162e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 operator*( const float& rhs ) const
163e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
164e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
165e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs;
166e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ * rhs;
167e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
168e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
169e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
170e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2& operator*=( const float& rhs )
171e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
172e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ * rhs;
173e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ * rhs;
174e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
175e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
176e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
177e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 operator/( const float& rhs ) const
178e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
179e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec2 ret;
180e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ / rhs;
181e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ / rhs;
182e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
183e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
184e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
185e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2& operator/=( const float& rhs )
186e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
187e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ / rhs;
188e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ / rhs;
189e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
190e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
191e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
192e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Compare
193e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool operator==( const Vec2& rhs ) const
194e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
195e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( x_ != rhs.x_ || y_ != rhs.y_ )
196e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
197e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
198e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
199e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
200e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool operator!=( const Vec2& rhs ) const
201e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
202e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( x_ == rhs.x_ )
203e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
204e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
205e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
206e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
207e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
208e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float Length() const
209e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
210e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return sqrtf( x_ * x_ + y_ * y_ );
211e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
212e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
213e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec2 Normalize()
214e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
215e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float len = Length();
216e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ / len;
217e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ / len;
218e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
219e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
220e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
221e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float Dot( const Vec2& rhs )
222e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
223e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return x_ * rhs.x_ + y_ * rhs.y_;
224e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
225e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
226e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool Validate()
227e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
228e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( isnan( x_ ) || isnan( y_ ) )
229e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
230e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
231e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
232e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
233e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Value( float& fX, float& fY )
234e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
235e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fX = x_;
236e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fY = y_;
237e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
238e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
239e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Dump()
240e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
241e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        LOGI( "Vec2 %f %f", x_, y_ );
242e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
243e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot};
244e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
245e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/******************************************************************
246e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * 3 elements vector class
247e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
248e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
249e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Vec3
250e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot{
251e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotprivate:
252e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float x_, y_, z_;
253e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
254e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotpublic:
255e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec4;
256e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Mat4;
257e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Quaternion;
258e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
259e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3()
260e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
261e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = y_ = z_ = 0.f;
262e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
263e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
264e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3( const float fX, const float fY, const float fZ )
265e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
266e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = fX;
267e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = fY;
268e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = fZ;
269e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
270e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
271e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3( const Vec3& vec )
272e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
273e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = vec.x_;
274e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = vec.y_;
275e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = vec.z_;
276e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
277e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
278e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3( const float* pVec )
279e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
280e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = (*pVec++);
281e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = (*pVec++);
282e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = *pVec;
283e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
284e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
285e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3( const Vec2& vec, float f )
286e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
287e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = vec.x_;
288e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = vec.y_;
289e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = f;
290e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
291e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
292e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3( const Vec4& vec );
293e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
294e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Operators
295e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 operator*( const Vec3& rhs ) const
296e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
297e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
298e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs.x_;
299e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ * rhs.y_;
300e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ * rhs.z_;
301e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
302e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
303e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
304e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 operator/( const Vec3& rhs ) const
305e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
306e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
307e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ / rhs.x_;
308e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ / rhs.y_;
309e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ / rhs.z_;
310e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
311e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
312e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
313e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 operator+( const Vec3& rhs ) const
314e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
315e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
316e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ + rhs.x_;
317e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ + rhs.y_;
318e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ + rhs.z_;
319e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
320e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
321e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
322e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 operator-( const Vec3& rhs ) const
323e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
324e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
325e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ - rhs.x_;
326e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ - rhs.y_;
327e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ - rhs.z_;
328e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
329e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
330e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
331e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3& operator+=( const Vec3& rhs )
332e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
333e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ += rhs.x_;
334e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ += rhs.y_;
335e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ += rhs.z_;
336e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
337e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
338e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
339e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3& operator-=( const Vec3& rhs )
340e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
341e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ -= rhs.x_;
342e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ -= rhs.y_;
343e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ -= rhs.z_;
344e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
345e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
346e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
347e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3& operator*=( const Vec3& rhs )
348e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
349e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ *= rhs.x_;
350e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ *= rhs.y_;
351e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ *= rhs.z_;
352e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
353e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
354e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
355e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3& operator/=( const Vec3& rhs )
356e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
357e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ /= rhs.x_;
358e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ /= rhs.y_;
359e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ /= rhs.z_;
360e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
361e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
362e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
363e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //External operators
364e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec3 operator-( const Vec3& rhs )
365e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
366e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return Vec3( rhs ) *= -1;
367e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
368e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
369e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec3 operator*( const float lhs, const Vec3& rhs )
370e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
371e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
372e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = lhs * rhs.x_;
373e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = lhs * rhs.y_;
374e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = lhs * rhs.z_;
375e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
376e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
377e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
378e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec3 operator/( const float lhs, const Vec3& rhs )
379e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
380e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
381e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = lhs / rhs.x_;
382e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = lhs / rhs.y_;
383e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = lhs / rhs.z_;
384e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
385e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
386e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
387e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Operators with float
388e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 operator*( const float& rhs ) const
389e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
390e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
391e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs;
392e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ * rhs;
393e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ * rhs;
394e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
395e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
396e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
397e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3& operator*=( const float& rhs )
398e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
399e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ * rhs;
400e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ * rhs;
401e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = z_ * rhs;
402e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
403e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
404e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
405e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 operator/( const float& rhs ) const
406e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
407e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
408e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ / rhs;
409e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ / rhs;
410e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ / rhs;
411e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
412e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
413e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
414e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3& operator/=( const float& rhs )
415e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
416e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ / rhs;
417e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ / rhs;
418e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = z_ / rhs;
419e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
420e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
421e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
422e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Compare
423e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool operator==( const Vec3& rhs ) const
424e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
425e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ )
426e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
427e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
428e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
429e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
430e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool operator!=( const Vec3& rhs ) const
431e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
432e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( x_ == rhs.x_ )
433e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
434e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
435e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
436e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
437e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
438e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float Length() const
439e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
440e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ );
441e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
442e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
443e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 Normalize()
444e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
445e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float len = Length();
446e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ / len;
447e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ / len;
448e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = z_ / len;
449e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
450e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
451e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
452e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float Dot( const Vec3& rhs )
453e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
454e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
455e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
456e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
457e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 Cross( const Vec3& rhs )
458e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
459e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
460e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = y_ * rhs.z_ - z_ * rhs.y_;
461e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = z_ * rhs.x_ - x_ * rhs.z_;
462e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = x_ * rhs.y_ - y_ * rhs.x_;
463e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
464e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
465e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
466e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool Validate()
467e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
468e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) )
469e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
470e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
471e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
472e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
473e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Value( float& fX, float& fY, float& fZ )
474e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
475e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fX = x_;
476e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fY = y_;
477e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fZ = z_;
478e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
479e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
480e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Dump()
481e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
482e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        LOGI( "Vec3 %f %f %f", x_, y_, z_ );
483e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
484e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot};
485e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
486e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/******************************************************************
487e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * 4 elements vector class
488e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
489e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
490e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Vec4
491e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot{
492e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotprivate:
493e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float x_, y_, z_, w_;
494e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
495e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotpublic:
496e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec3;
497e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Mat4;
498e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Quaternion;
499e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
500e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4()
501e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
502e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = y_ = z_ = w_ = 0.f;
503e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
504e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
505e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4( const float fX, const float fY, const float fZ, const float fW )
506e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
507e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = fX;
508e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = fY;
509e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = fZ;
510e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = fW;
511e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
512e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
513e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4( const Vec4& vec )
514e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
515e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = vec.x_;
516e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = vec.y_;
517e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = vec.z_;
518e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = vec.w_;
519e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
520e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
521e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4( const Vec3& vec, const float fW )
522e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
523e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = vec.x_;
524e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = vec.y_;
525e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = vec.z_;
526e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = fW;
527e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
528e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
529e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4( const float* pVec )
530e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
531e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = (*pVec++);
532e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = (*pVec++);
533e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = *pVec;
534e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = *pVec;
535e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
536e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
537e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Operators
538e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator*( const Vec4& rhs ) const
539e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
540e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
541e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs.x_;
542e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ * rhs.y_;
543e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ * rhs.z_;
544e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = z_ * rhs.w_;
545e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
546e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
547e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
548e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator/( const Vec4& rhs ) const
549e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
550e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
551e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ / rhs.x_;
552e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ / rhs.y_;
553e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ / rhs.z_;
554e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = z_ / rhs.w_;
555e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
556e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
557e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
558e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator+( const Vec4& rhs ) const
559e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
560e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
561e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ + rhs.x_;
562e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ + rhs.y_;
563e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ + rhs.z_;
564e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = z_ + rhs.w_;
565e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
566e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
567e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
568e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator-( const Vec4& rhs ) const
569e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
570e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
571e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ - rhs.x_;
572e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ - rhs.y_;
573e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ - rhs.z_;
574e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = z_ - rhs.w_;
575e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
576e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
577e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
578e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4& operator+=( const Vec4& rhs )
579e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
580e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ += rhs.x_;
581e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ += rhs.y_;
582e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ += rhs.z_;
583e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ += rhs.w_;
584e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
585e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
586e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
587e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4& operator-=( const Vec4& rhs )
588e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
589e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ -= rhs.x_;
590e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ -= rhs.y_;
591e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ -= rhs.z_;
592e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ -= rhs.w_;
593e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
594e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
595e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
596e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4& operator*=( const Vec4& rhs )
597e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
598e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ *= rhs.x_;
599e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ *= rhs.y_;
600e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ *= rhs.z_;
601e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ *= rhs.w_;
602e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
603e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
604e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
605e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4& operator/=( const Vec4& rhs )
606e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
607e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ /= rhs.x_;
608e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ /= rhs.y_;
609e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ /= rhs.z_;
610e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ /= rhs.w_;
611e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
612e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
613e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
614e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //External operators
615e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec4 operator-( const Vec4& rhs )
616e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
617e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return Vec4( rhs ) *= -1;
618e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
619e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
620e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec4 operator*( const float lhs, const Vec4& rhs )
621e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
622e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
623e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = lhs * rhs.x_;
624e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = lhs * rhs.y_;
625e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = lhs * rhs.z_;
626e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = lhs * rhs.w_;
627e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
628e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
629e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
630e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend Vec4 operator/( const float lhs, const Vec4& rhs )
631e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
632e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
633e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = lhs / rhs.x_;
634e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = lhs / rhs.y_;
635e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = lhs / rhs.z_;
636e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = lhs / rhs.w_;
637e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
638e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
639e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
640e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Operators with float
641e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator*( const float& rhs ) const
642e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
643e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
644e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs;
645e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ * rhs;
646e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ * rhs;
647e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = w_ * rhs;
648e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
649e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
650e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
651e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4& operator*=( const float& rhs )
652e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
653e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ * rhs;
654e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ * rhs;
655e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = z_ * rhs;
656e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = w_ * rhs;
657e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
658e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
659e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
660e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator/( const float& rhs ) const
661e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
662e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec4 ret;
663e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ / rhs;
664e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = y_ / rhs;
665e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = z_ / rhs;
666e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = w_ / rhs;
667e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
668e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
669e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
670e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4& operator/=( const float& rhs )
671e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
672e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ / rhs;
673e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ / rhs;
674e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = z_ / rhs;
675e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = w_ / rhs;
676e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
677e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
678e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
679e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Compare
680e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool operator==( const Vec4& rhs ) const
681e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
682e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ || w_ != rhs.w_ )
683e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
684e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
685e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
686e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
687e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool operator!=( const Vec4& rhs ) const
688e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
689e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( x_ == rhs.x_ )
690e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
691e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
692e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
693e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
694e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
695e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator*( const Mat4& rhs ) const;
696e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
697e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float Length() const
698e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
699e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_ );
700e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
701e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
702e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 Normalize()
703e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
704e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float len = Length();
705e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = x_ / len;
706e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = y_ / len;
707e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = z_ / len;
708e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = w_ / len;
709e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
710e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
711e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
712e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float Dot( const Vec3& rhs )
713e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
714e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
715e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
716e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
717e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec3 Cross( const Vec3& rhs )
718e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
719e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Vec3 ret;
720e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = y_ * rhs.z_ - z_ * rhs.y_;
721e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = z_ * rhs.x_ - x_ * rhs.z_;
722e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = x_ * rhs.y_ - y_ * rhs.x_;
723e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
724e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
725e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
726e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    bool Validate()
727e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
728e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) || isnan( w_ ) )
729e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            return false;
730e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return true;
731e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
732e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
733e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Value( float& fX, float& fY, float& fZ, float& fW )
734e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
735e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fX = x_;
736e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fY = y_;
737e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fZ = z_;
738e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fW = w_;
739e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
740e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot};
741e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
742e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/******************************************************************
743e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * 4x4 matrix
744e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
745e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
746e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Mat4
747e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot{
748e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotprivate:
749e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float f_[16];
750e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
751e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotpublic:
752e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec3;
753e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec4;
754e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Quaternion;
755e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
756e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4();
757e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4( const float* );
758e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
759e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4 operator*( const Mat4& rhs ) const;
760e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Vec4 operator*( const Vec4& rhs ) const;
761e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
762e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4 operator+( const Mat4& rhs ) const
763e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
764e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Mat4 ret;
765e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
766e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
767e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            ret.f_[i] = f_[i] + rhs.f_[i];
768e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
769e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
770e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
771e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
772e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4 operator-( const Mat4& rhs ) const
773e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
774e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Mat4 ret;
775e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
776e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
777e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            ret.f_[i] = f_[i] - rhs.f_[i];
778e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
779e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
780e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
781e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
782e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4& operator+=( const Mat4& rhs )
783e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
784e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
785e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
786e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            f_[i] += rhs.f_[i];
787e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
788e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
789e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
790e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
791e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4& operator-=( const Mat4& rhs )
792e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
793e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
794e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
795e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            f_[i] -= rhs.f_[i];
796e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
797e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
798e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
799e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
800e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4& operator*=( const Mat4& rhs )
801e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
802e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Mat4 ret;
803e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[0] = f_[0] * rhs.f_[0] + f_[4] * rhs.f_[1] + f_[8] * rhs.f_[2]
804e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[12] * rhs.f_[3];
805e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[1] = f_[1] * rhs.f_[0] + f_[5] * rhs.f_[1] + f_[9] * rhs.f_[2]
806e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[13] * rhs.f_[3];
807e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[2] = f_[2] * rhs.f_[0] + f_[6] * rhs.f_[1] + f_[10] * rhs.f_[2]
808e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[14] * rhs.f_[3];
809e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[3] = f_[3] * rhs.f_[0] + f_[7] * rhs.f_[1] + f_[11] * rhs.f_[2]
810e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[15] * rhs.f_[3];
811e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
812e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[4] = f_[0] * rhs.f_[4] + f_[4] * rhs.f_[5] + f_[8] * rhs.f_[6]
813e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[12] * rhs.f_[7];
814e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[5] = f_[1] * rhs.f_[4] + f_[5] * rhs.f_[5] + f_[9] * rhs.f_[6]
815e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[13] * rhs.f_[7];
816e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[6] = f_[2] * rhs.f_[4] + f_[6] * rhs.f_[5] + f_[10] * rhs.f_[6]
817e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[14] * rhs.f_[7];
818e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[7] = f_[3] * rhs.f_[4] + f_[7] * rhs.f_[5] + f_[11] * rhs.f_[6]
819e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[15] * rhs.f_[7];
820e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
821e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[8] = f_[0] * rhs.f_[8] + f_[4] * rhs.f_[9] + f_[8] * rhs.f_[10]
822e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[12] * rhs.f_[11];
823e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[9] = f_[1] * rhs.f_[8] + f_[5] * rhs.f_[9] + f_[9] * rhs.f_[10]
824e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[13] * rhs.f_[11];
825e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[10] = f_[2] * rhs.f_[8] + f_[6] * rhs.f_[9] + f_[10] * rhs.f_[10]
826e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[14] * rhs.f_[11];
827e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[11] = f_[3] * rhs.f_[8] + f_[7] * rhs.f_[9] + f_[11] * rhs.f_[10]
828e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[15] * rhs.f_[11];
829e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
830e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[12] = f_[0] * rhs.f_[12] + f_[4] * rhs.f_[13] + f_[8] * rhs.f_[14]
831e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[12] * rhs.f_[15];
832e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[13] = f_[1] * rhs.f_[12] + f_[5] * rhs.f_[13] + f_[9] * rhs.f_[14]
833e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[13] * rhs.f_[15];
834e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[14] = f_[2] * rhs.f_[12] + f_[6] * rhs.f_[13] + f_[10] * rhs.f_[14]
835e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[14] * rhs.f_[15];
836e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[15] = f_[3] * rhs.f_[12] + f_[7] * rhs.f_[13] + f_[11] * rhs.f_[14]
837e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot                + f_[15] * rhs.f_[15];
838e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
839e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        *this = ret;
840e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
841e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
842e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
843e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4 operator*( const float rhs )
844e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
845e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Mat4 ret;
846e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
847e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
848e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            ret.f_[i] = f_[i] * rhs;
849e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
850e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
851e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
852e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
853e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4& operator*=( const float rhs )
854e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
855e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
856e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
857e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            f_[i] *= rhs;
858e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
859e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
860e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
861e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
862e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4& operator=( const Mat4& rhs )
863e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
864e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        for( int32_t i = 0; i < 16; ++i )
865e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        {
866e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot            f_[i] = rhs.f_[i];
867e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        }
868e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
869e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
870e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
871e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4 Inverse();
872e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
873e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4 Transpose()
874e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
875e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Mat4 ret;
876e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[0] = f_[0];
877e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[1] = f_[4];
878e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[2] = f_[8];
879e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[3] = f_[12];
880e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[4] = f_[1];
881e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[5] = f_[5];
882e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[6] = f_[9];
883e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[7] = f_[13];
884e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[8] = f_[2];
885e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[9] = f_[6];
886e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[10] = f_[10];
887e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[11] = f_[14];
888e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[12] = f_[3];
889e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[13] = f_[7];
890e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[14] = f_[11];
891e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[15] = f_[15];
892e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        *this = ret;
893e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
894e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
895e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
896e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Mat4& PostTranslate( float tx, float ty, float tz )
897e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
898e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        f_[12] += (tx * f_[0]) + (ty * f_[4]) + (tz * f_[8]);
899e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        f_[13] += (tx * f_[1]) + (ty * f_[5]) + (tz * f_[9]);
900e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        f_[14] += (tx * f_[2]) + (ty * f_[6]) + (tz * f_[10]);
901e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        f_[15] += (tx * f_[3]) + (ty * f_[7]) + (tz * f_[11]);
902e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
903e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
904e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
905e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float* Ptr()
906e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
907e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return f_;
908e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
909e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
910e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //--------------------------------------------------------------------------------
911e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    // Misc
912e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //--------------------------------------------------------------------------------
913e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 Perspective( float width, float height, float nearPlane, float farPlane );
914e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
915e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 LookAt( const Vec3& vEye, const Vec3& vAt, const Vec3& vUp );
916e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
917e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 Translation( const float fX, const float fY, const float fZ );
918e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 Translation( const Vec3 vec );
919e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
920e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 RotationX( const float angle );
921e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
922e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 RotationY( const float angle );
923e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
924e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 RotationZ( const float angle );
925e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
926e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Mat4 Identity()
927e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
928e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Mat4 ret;
929e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[0] = 1.f;
930e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[1] = 0;
931e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[2] = 0;
932e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[3] = 0;
933e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[4] = 0;
934e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[5] = 1.f;
935e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[6] = 0;
936e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[7] = 0;
937e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[8] = 0;
938e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[9] = 0;
939e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[10] = 1.f;
940e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[11] = 0;
941e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[12] = 0;
942e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[13] = 0;
943e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[14] = 0;
944e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.f_[15] = 1.f;
945e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
946e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
947e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
948e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Dump()
949e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
950e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        LOGI( "%f %f %f %f", f_[0], f_[1], f_[2], f_[3] );
951e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        LOGI( "%f %f %f %f", f_[4], f_[5], f_[6], f_[7] );
952e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        LOGI( "%f %f %f %f", f_[8], f_[9], f_[10], f_[11] );
953e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        LOGI( "%f %f %f %f", f_[12], f_[13], f_[14], f_[15] );
954e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
955e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot};
956e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
957e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot/******************************************************************
958e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot * Quaternion class
959e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot *
960e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot */
961e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotclass Quaternion
962e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot{
963e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotprivate:
964e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    float x_, y_, z_, w_;
965e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
966e779e31468999c7ef69f424a2b8271969833df2android-build-team Robotpublic:
967e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec3;
968e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Vec4;
969e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    friend class Mat4;
970e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
971e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion()
972e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
973e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = 0.f;
974e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = 0.f;
975e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = 0.f;
976e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = 1.f;
977e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
978e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
979e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion( const float fX, const float fY, const float fZ, const float fW )
980e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
981e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = fX;
982e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = fY;
983e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = fZ;
984e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = fW;
985e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
986e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
987e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion( const Vec3 vec, const float fW )
988e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
989e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = vec.x_;
990e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = vec.y_;
991e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = vec.z_;
992e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = fW;
993e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
994e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
995e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion( const float* p )
996e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
997e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = *p++;
998e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = *p++;
999e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = *p++;
1000e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        w_ = *p++;
1001e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1002e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1003e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion operator*( const Quaternion rhs )
1004e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1005e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Quaternion ret;
1006e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_;
1007e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_;
1008e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_;
1009e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_;
1010e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
1011e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1012e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1013e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion& operator*=( const Quaternion rhs )
1014e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1015e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Quaternion ret;
1016e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_;
1017e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_;
1018e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_;
1019e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_;
1020e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        *this = ret;
1021e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
1022e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1023e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1024e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion Conjugate()
1025e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1026e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        x_ = -x_;
1027e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        y_ = -y_;
1028e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        z_ = -z_;
1029e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return *this;
1030e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1031e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1032e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    //Non destuctive version
1033e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    Quaternion Conjugated()
1034e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1035e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Quaternion ret;
1036e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = -x_;
1037e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = -y_;
1038e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = -z_;
1039e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = w_;
1040e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
1041e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1042e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1043e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void ToMatrix( Mat4& mat )
1044e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1045e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float x2 = x_ * x_ * 2.0f;
1046e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float y2 = y_ * y_ * 2.0f;
1047e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float z2 = z_ * z_ * 2.0f;
1048e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float xy = x_ * y_ * 2.0f;
1049e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float yz = y_ * z_ * 2.0f;
1050e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float zx = z_ * x_ * 2.0f;
1051e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float xw = x_ * w_ * 2.0f;
1052e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float yw = y_ * w_ * 2.0f;
1053e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float zw = z_ * w_ * 2.0f;
1054e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1055e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[0] = 1.0f - y2 - z2;
1056e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[1] = xy + zw;
1057e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[2] = zx - yw;
1058e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[4] = xy - zw;
1059e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[5] = 1.0f - z2 - x2;
1060e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[6] = yz + xw;
1061e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[8] = zx + yw;
1062e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[9] = yz - xw;
1063e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[10] = 1.0f - x2 - y2;
1064e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1065e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[3] = mat.f_[7] = mat.f_[11] = mat.f_[12] = mat.f_[13] = mat.f_[14] = 0.0f;
1066e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[15] = 1.0f;
1067e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1068e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1069e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void ToMatrixPreserveTranslate( Mat4& mat )
1070e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1071e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float x2 = x_ * x_ * 2.0f;
1072e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float y2 = y_ * y_ * 2.0f;
1073e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float z2 = z_ * z_ * 2.0f;
1074e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float xy = x_ * y_ * 2.0f;
1075e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float yz = y_ * z_ * 2.0f;
1076e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float zx = z_ * x_ * 2.0f;
1077e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float xw = x_ * w_ * 2.0f;
1078e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float yw = y_ * w_ * 2.0f;
1079e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float zw = z_ * w_ * 2.0f;
1080e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1081e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[0] = 1.0f - y2 - z2;
1082e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[1] = xy + zw;
1083e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[2] = zx - yw;
1084e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[4] = xy - zw;
1085e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[5] = 1.0f - z2 - x2;
1086e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[6] = yz + xw;
1087e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[8] = zx + yw;
1088e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[9] = yz - xw;
1089e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[10] = 1.0f - x2 - y2;
1090e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1091e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[3] = mat.f_[7] = mat.f_[11] = 0.0f;
1092e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        mat.f_[15] = 1.0f;
1093e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1094e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1095e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    static Quaternion RotationAxis( const Vec3 axis, const float angle )
1096e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1097e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        Quaternion ret;
1098e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        float s = sinf( angle / 2 );
1099e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.x_ = s * axis.x_;
1100e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.y_ = s * axis.y_;
1101e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.z_ = s * axis.z_;
1102e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        ret.w_ = cosf( angle / 2 );
1103e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        return ret;
1104e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1105e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1106e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    void Value( float& fX, float& fY, float& fZ, float& fW )
1107e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    {
1108e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fX = x_;
1109e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fY = y_;
1110e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fZ = z_;
1111e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot        fW = w_;
1112e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot    }
1113e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot};
1114e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot
1115e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot} //namespace ndk_helper
1116e779e31468999c7ef69f424a2b8271969833df2android-build-team Robot#endif /* VECMATH_H_ */
1117