1984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian/* 2984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Copyright (C) 2011 The Android Open Source Project 3984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 4984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * you may not use this file except in compliance with the License. 6984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * You may obtain a copy of the License at 7984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 8984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 10984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Unless required by applicable law or agreed to in writing, software 11984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * See the License for the specific language governing permissions and 14984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * limitations under the License. 15984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian */ 16984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 17984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#ifndef ANDROID_VEC_H 18984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define ANDROID_VEC_H 19984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 20984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include <math.h> 21984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 22984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include <stdint.h> 23984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include <stddef.h> 24984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 25984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "traits.h" 26984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 27984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 28984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 29984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define PURE __attribute__((pure)) 30984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 31984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace android { 32984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 33984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 34984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// non-inline helpers 35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 36984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass vec; 38984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 39984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 40984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass vbase; 41984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 42984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace helpers { 43984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 44984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T> inline T min(T a, T b) { return a<b ? a : b; } 45984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T> inline T max(T a, T b) { return a>b ? a : b; } 46984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 47984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < template<typename T, size_t S> class VEC, 48984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, size_t SIZE, size_t S> 49984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianvec<TYPE, SIZE>& doAssign( 50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec<TYPE, SIZE>& lhs, const VEC<TYPE, S>& rhs) { 51984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const size_t minSize = min(SIZE, S); 52984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const size_t maxSize = max(SIZE, S); 53984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<minSize ; i++) 54984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs[i] = rhs[i]; 55984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=minSize ; i<maxSize ; i++) 56984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs[i] = 0; 57984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return lhs; 58984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 59984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 60984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 61984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 62984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VLHS, 63984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VRHS, 64984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 65984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 66984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 67984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianVLHS<TYPE, SIZE> PURE doAdd( 68984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VLHS<TYPE, SIZE>& lhs, 69984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VRHS<TYPE, SIZE>& rhs) { 70984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian VLHS<TYPE, SIZE> r; 71984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 72984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i] = lhs[i] + rhs[i]; 73984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 74984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 75984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 76984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 77984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VLHS, 78984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VRHS, 79984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 80984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 81984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 82984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianVLHS<TYPE, SIZE> PURE doSub( 83984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VLHS<TYPE, SIZE>& lhs, 84984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VRHS<TYPE, SIZE>& rhs) { 85984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian VLHS<TYPE, SIZE> r; 86984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 87984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i] = lhs[i] - rhs[i]; 88984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 89984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 90984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 91984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 92984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VEC, 93984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 94984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 95984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 96984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianVEC<TYPE, SIZE> PURE doMulScalar( 97984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VEC<TYPE, SIZE>& lhs, 98984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType rhs) { 99984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian VEC<TYPE, SIZE> r; 100984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 101984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i] = lhs[i] * rhs; 102984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 103984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 104984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 105984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 106984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VEC, 107984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 108984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 109984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 110984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianVEC<TYPE, SIZE> PURE doScalarMul( 111984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType lhs, 112984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VEC<TYPE, SIZE>& rhs) { 113984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian VEC<TYPE, SIZE> r; 114984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 115984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i] = lhs * rhs[i]; 116984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 117984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 118984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 119984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace helpers 120984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 121984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 122984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Below we define the mathematical operators for vectors. 123984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// We use template template arguments so we can generically 124984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// handle the case where the right-hand-size and left-hand-side are 125984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// different vector types (but with same value_type and size). 126984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// This is needed for performance when using ".xy{z}" element access 127984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// on vec<>. Without this, an extra conversion to vec<> would be needed. 128984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// 129984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// example: 130984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// vec4_t a; 131984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// vec3_t b; 132984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// vec3_t c = a.xyz + b; 133984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// 134984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// "a.xyz + b" is a mixed-operation between a vbase<> and a vec<>, requiring 135984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// a conversion of vbase<> to vec<>. The template gunk below avoids this, 136984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// by allowing the addition on these different vector types directly 137984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// 138984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 139984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 140984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VLHS, 141984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VRHS, 142984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 143984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 144984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 145984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline VLHS<TYPE, SIZE> PURE operator + ( 146984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VLHS<TYPE, SIZE>& lhs, 147984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VRHS<TYPE, SIZE>& rhs) { 148984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doAdd(lhs, rhs); 149984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 150984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 151984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 152984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VLHS, 153984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VRHS, 154984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 155984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 156984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 157984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline VLHS<TYPE, SIZE> PURE operator - ( 158984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VLHS<TYPE, SIZE>& lhs, 159984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VRHS<TYPE, SIZE>& rhs) { 160984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doSub(lhs, rhs); 161984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 162984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 163984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 164984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VEC, 165984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 166984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 167984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 168984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline VEC<TYPE, SIZE> PURE operator * ( 169984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VEC<TYPE, SIZE>& lhs, 170984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType rhs) { 171984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMulScalar(lhs, rhs); 172984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 173984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 174984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 175984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VEC, 176984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 177984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 178984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 179984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline VEC<TYPE, SIZE> PURE operator * ( 180984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType lhs, 181984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VEC<TYPE, SIZE>& rhs) { 182984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doScalarMul(lhs, rhs); 183984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 184984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 185984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 186984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 187984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VLHS, 188984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VRHS, 189984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 190984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 191984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 192984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianTYPE PURE dot_product( 193984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VLHS<TYPE, SIZE>& lhs, 194984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VRHS<TYPE, SIZE>& rhs) { 195984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian TYPE r(0); 196984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 197984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r += lhs[i] * rhs[i]; 198984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 199984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 200984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 201984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 202984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class V, 203984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 204984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 205984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 206984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianTYPE PURE length(const V<TYPE, SIZE>& v) { 207984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return sqrt(dot_product(v, v)); 208984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 209984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 210984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 2113301542828febc768e1df42892cfac4992c35474Mathias Agopian template<typename T, size_t S> class V, 2123301542828febc768e1df42892cfac4992c35474Mathias Agopian typename TYPE, 2133301542828febc768e1df42892cfac4992c35474Mathias Agopian size_t SIZE 2143301542828febc768e1df42892cfac4992c35474Mathias Agopian> 2153e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael JohnsonTYPE PURE length_squared(const V<TYPE, SIZE>& v) { 2163e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson return dot_product(v, v); 2173e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson} 2183e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson 2193e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnsontemplate < 2203e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson template<typename T, size_t S> class V, 2213e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson typename TYPE, 2223e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson size_t SIZE 2233e87d8dadefaf4b56bf15a15f1b53928d7a12cd2Michael Johnson> 2243301542828febc768e1df42892cfac4992c35474Mathias AgopianV<TYPE, SIZE> PURE normalize(const V<TYPE, SIZE>& v) { 2253301542828febc768e1df42892cfac4992c35474Mathias Agopian return v * (1/length(v)); 2263301542828febc768e1df42892cfac4992c35474Mathias Agopian} 2273301542828febc768e1df42892cfac4992c35474Mathias Agopian 2283301542828febc768e1df42892cfac4992c35474Mathias Agopiantemplate < 229984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VLHS, 230984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VRHS, 231984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE 232984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 233984826cc158193e61e3a00359ef4f6699c7d748aMathias AgopianVLHS<TYPE, 3> PURE cross_product( 234984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VLHS<TYPE, 3>& u, 235984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const VRHS<TYPE, 3>& v) { 236984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian VLHS<TYPE, 3> r; 237984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r.x = u.y*v.z - u.z*v.y; 238984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r.y = u.z*v.x - u.x*v.z; 239984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r.z = u.x*v.y - u.y*v.x; 240984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 241984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 242984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 243984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 244984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 245984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianvec<TYPE, SIZE> PURE operator - (const vec<TYPE, SIZE>& lhs) { 246984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec<TYPE, SIZE> r; 247984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 248984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i] = -lhs[i]; 249984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 250984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 251984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 252984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 253984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 254984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// This our basic vector type, it just implements the data storage 255984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// and accessors. 256984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 257984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 258984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct vbase { 259984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian TYPE v[SIZE]; 260984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline const TYPE& operator[](size_t i) const { return v[i]; } 261984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline TYPE& operator[](size_t i) { return v[i]; } 262984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 263984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate<> struct vbase<float, 2> { 264984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian union { 265984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian float v[2]; 266984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct { float x, y; }; 267984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct { float s, t; }; 268984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian }; 269984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline const float& operator[](size_t i) const { return v[i]; } 270984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline float& operator[](size_t i) { return v[i]; } 271984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 272984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate<> struct vbase<float, 3> { 273984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian union { 274984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian float v[3]; 275984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct { float x, y, z; }; 276984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct { float s, t, r; }; 277984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vbase<float, 2> xy; 278984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vbase<float, 2> st; 279984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian }; 280984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline const float& operator[](size_t i) const { return v[i]; } 281984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline float& operator[](size_t i) { return v[i]; } 282984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 283984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate<> struct vbase<float, 4> { 284984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian union { 285984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian float v[4]; 286984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct { float x, y, z, w; }; 287984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct { float s, t, r, q; }; 288984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vbase<float, 3> xyz; 289984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vbase<float, 3> str; 290984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vbase<float, 2> xy; 291984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vbase<float, 2> st; 292984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian }; 293984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline const float& operator[](size_t i) const { return v[i]; } 294984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inline float& operator[](size_t i) { return v[i]; } 295984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 296984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 297984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 298984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 299984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 300984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass vec : public vbase<TYPE, SIZE> 301984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian{ 302984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef typename TypeTraits<TYPE>::ParameterType pTYPE; 303984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef vbase<TYPE, SIZE> base; 304984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 305984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic: 306984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // STL-like interface. 307984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE value_type; 308984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE& reference; 309984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE const& const_reference; 310984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef size_t size_type; 311984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 312984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE* iterator; 313984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE const* const_iterator; 314984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian iterator begin() { return base::v; } 315984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian iterator end() { return base::v + SIZE; } 316984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const_iterator begin() const { return base::v; } 317984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const_iterator end() const { return base::v + SIZE; } 318984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_type size() const { return SIZE; } 319984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 320984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 321984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // default constructors 322984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 323984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec() { } 324984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec(const vec& rhs) : base(rhs) { } 325984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec(const base& rhs) : base(rhs) { } 326984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 327984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 328984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // conversion constructors 329984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 330984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec(pTYPE rhs) { 331984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 332984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator[](i) = rhs; 333984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 334984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 335984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template < template<typename T, size_t S> class VEC, size_t S> 336984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian explicit vec(const VEC<TYPE, S>& rhs) { 337984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian helpers::doAssign(*this, rhs); 338984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 339984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 340984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian explicit vec(TYPE const* array) { 341984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 342984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator[](i) = array[i]; 343984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 344984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 345984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 346984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // Assignment 347984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 348984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator = (const vec& rhs) { 349984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator=(rhs); 350984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return *this; 351984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 352984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 353984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator = (const base& rhs) { 354984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator=(rhs); 355984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return *this; 356984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 357984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 358984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator = (pTYPE rhs) { 359984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 360984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator[](i) = rhs; 361984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return *this; 362984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 363984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 364984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template < template<typename T, size_t S> class VEC, size_t S> 365984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator = (const VEC<TYPE, S>& rhs) { 366984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doAssign(*this, rhs); 367984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 368984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 369984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 370984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // operation-assignment 371984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 372984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator += (const vec& rhs); 373984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator -= (const vec& rhs); 374984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec& operator *= (pTYPE rhs); 375984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 376984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 377984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // non-member function declaration and definition 378984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // NOTE: we declare the non-member function as friend inside the class 379984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // so that they are known to the compiler when the class is instantiated. 380984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // This helps the compiler doing template argument deduction when the 381984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // passed types are not identical. Essentially this helps with 382984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // type conversion so that you can multiply a vec<float> by an scalar int 383984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // (for instance). 384984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 385984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline vec PURE operator + (const vec& lhs, const vec& rhs) { 386984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doAdd(lhs, rhs); 387984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 388984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline vec PURE operator - (const vec& lhs, const vec& rhs) { 389984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doSub(lhs, rhs); 390984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 391984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline vec PURE operator * (const vec& lhs, pTYPE v) { 392984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMulScalar(lhs, v); 393984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 394984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline vec PURE operator * (pTYPE v, const vec& rhs) { 395984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doScalarMul(v, rhs); 396984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 397984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline TYPE PURE dot_product(const vec& lhs, const vec& rhs) { 398984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return android::dot_product(lhs, rhs); 399984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 400984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 401984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 402984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 403984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 404984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 405984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianvec<TYPE, SIZE>& vec<TYPE, SIZE>::operator += (const vec<TYPE, SIZE>& rhs) { 406984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec<TYPE, SIZE>& lhs(*this); 407984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 408984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs[i] += rhs[i]; 409984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return lhs; 410984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 411984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 412984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 413984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianvec<TYPE, SIZE>& vec<TYPE, SIZE>::operator -= (const vec<TYPE, SIZE>& rhs) { 414984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec<TYPE, SIZE>& lhs(*this); 415984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 416984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs[i] -= rhs[i]; 417984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return lhs; 418984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 419984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 420984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t SIZE> 421984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianvec<TYPE, SIZE>& vec<TYPE, SIZE>::operator *= (vec<TYPE, SIZE>::pTYPE rhs) { 422984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec<TYPE, SIZE>& lhs(*this); 423984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 424984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs[i] *= rhs; 425984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return lhs; 426984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 427984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 428984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 429984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 430984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantypedef vec<float, 2> vec2_t; 431984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantypedef vec<float, 3> vec3_t; 432984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantypedef vec<float, 4> vec4_t; 433984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 434984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 435984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 436984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace android 437984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 438984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#endif /* ANDROID_VEC_H */ 439