1/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <math/vec2.h>
20#include <math/half.h>
21#include <stdint.h>
22#include <sys/types.h>
23
24#pragma clang diagnostic push
25#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
26#pragma clang diagnostic ignored "-Wnested-anon-types"
27
28namespace android {
29// -------------------------------------------------------------------------------------
30
31namespace details {
32
33template <typename T>
34class TVec3 :   public TVecProductOperators<TVec3, T>,
35                public TVecAddOperators<TVec3, T>,
36                public TVecUnaryOperators<TVec3, T>,
37                public TVecComparisonOperators<TVec3, T>,
38                public TVecFunctions<TVec3, T>,
39                public TVecDebug<TVec3, T> {
40public:
41    enum no_init { NO_INIT };
42    typedef T value_type;
43    typedef T& reference;
44    typedef T const& const_reference;
45    typedef size_t size_type;
46
47    union {
48        struct { T x, y, z; };
49        struct { T s, t, p; };
50        struct { T r, g, b; };
51        TVec2<T> xy;
52        TVec2<T> st;
53        TVec2<T> rg;
54    };
55
56    static constexpr size_t SIZE = 3;
57    inline constexpr size_type size() const { return SIZE; }
58
59    // array access
60    inline constexpr T const& operator[](size_t i) const {
61#if __cplusplus >= 201402L
62        // only possible in C++0x14 with constexpr
63        assert(i < SIZE);
64#endif
65        return (&x)[i];
66    }
67
68    inline T& operator[](size_t i) {
69        assert(i < SIZE);
70        return (&x)[i];
71    }
72
73    // -----------------------------------------------------------------------
74    // we want the compiler generated versions for these...
75    TVec3(const TVec3&) = default;
76    ~TVec3() = default;
77    TVec3& operator = (const TVec3&) = default;
78
79    // constructors
80    // leaves object uninitialized. use with caution.
81    explicit
82    constexpr TVec3(no_init) { }
83
84    // default constructor
85    constexpr TVec3() : x(0), y(0), z(0) { }
86
87    // handles implicit conversion to a tvec4. must not be explicit.
88    template<typename A, typename = typename std::enable_if<std::is_arithmetic<A>::value >::type>
89    constexpr TVec3(A v) : x(v), y(v), z(v) { }
90
91    template<typename A, typename B, typename C>
92    constexpr TVec3(A x, B y, C z) : x(x), y(y), z(z) { }
93
94    template<typename A, typename B>
95    constexpr TVec3(const TVec2<A>& v, B z) : x(v.x), y(v.y), z(z) { }
96
97    template<typename A>
98    explicit
99    constexpr TVec3(const TVec3<A>& v) : x(v.x), y(v.y), z(v.z) { }
100
101    // cross product works only on vectors of size 3
102    template <typename RT>
103    friend inline
104    constexpr TVec3 cross(const TVec3& u, const TVec3<RT>& v) {
105        return TVec3(
106                u.y*v.z - u.z*v.y,
107                u.z*v.x - u.x*v.z,
108                u.x*v.y - u.y*v.x);
109    }
110};
111
112}  // namespace details
113
114// ----------------------------------------------------------------------------------------
115
116typedef details::TVec3<double> double3;
117typedef details::TVec3<float> float3;
118typedef details::TVec3<float> vec3;
119typedef details::TVec3<half> half3;
120typedef details::TVec3<int32_t> int3;
121typedef details::TVec3<uint32_t> uint3;
122typedef details::TVec3<int16_t> short3;
123typedef details::TVec3<uint16_t> ushort3;
124typedef details::TVec3<int8_t> byte3;
125typedef details::TVec3<uint8_t> ubyte3;
126typedef details::TVec3<bool> bool3;
127
128// ----------------------------------------------------------------------------------------
129}  // namespace android
130
131#pragma clang diagnostic pop
132