173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian/* 273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * Copyright (C) 2011 The Android Open Source Project 373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * 473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * you may not use this file except in compliance with the License. 673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * You may obtain a copy of the License at 773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * 873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * 1073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * Unless required by applicable law or agreed to in writing, software 1173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * See the License for the specific language governing permissions and 1473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * limitations under the License. 1573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian */ 1673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 1773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#ifndef ANDROID_VEC_H 1873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define ANDROID_VEC_H 1973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#include <math.h> 2173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#include <stdint.h> 2373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#include <stddef.h> 2473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#include "traits.h" 2673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 2873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define PURE __attribute__((pure)) 3073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 3173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiannamespace android { 3273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 3373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 3473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// non-inline helpers 3573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 3673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 3773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianclass vec; 3873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 3973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 4073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianclass vbase; 4173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 4273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiannamespace helpers { 4373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 4473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T> inline T min(T a, T b) { return a<b ? a : b; } 4573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T> inline T max(T a, T b) { return a>b ? a : b; } 4673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 4773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < template<typename T, size_t S> class VEC, 4873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, size_t SIZE, size_t S> 4973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianvec<TYPE, SIZE>& doAssign( 5073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec<TYPE, SIZE>& lhs, const VEC<TYPE, S>& rhs) { 5173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const size_t minSize = min(SIZE, S); 5273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const size_t maxSize = max(SIZE, S); 5373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<minSize ; i++) 5473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian lhs[i] = rhs[i]; 5573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=minSize ; i<maxSize ; i++) 5673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian lhs[i] = 0; 5773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return lhs; 5873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 5973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 6073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 6173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 6273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VLHS, 6373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VRHS, 6473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 6573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 6673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 6773e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianVLHS<TYPE, SIZE> PURE doAdd( 6873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VLHS<TYPE, SIZE>& lhs, 6973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VRHS<TYPE, SIZE>& rhs) { 7073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian VLHS<TYPE, SIZE> r; 7173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 7273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r[i] = lhs[i] + rhs[i]; 7373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 7473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 7573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 7673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 7773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VLHS, 7873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VRHS, 7973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 8073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 8173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 8273e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianVLHS<TYPE, SIZE> PURE doSub( 8373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VLHS<TYPE, SIZE>& lhs, 8473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VRHS<TYPE, SIZE>& rhs) { 8573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian VLHS<TYPE, SIZE> r; 8673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 8773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r[i] = lhs[i] - rhs[i]; 8873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 8973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 9073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 9173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 9273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VEC, 9373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 9473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 9573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 9673e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianVEC<TYPE, SIZE> PURE doMulScalar( 9773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VEC<TYPE, SIZE>& lhs, 9873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TypeTraits<TYPE>::ParameterType rhs) { 9973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian VEC<TYPE, SIZE> r; 10073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 10173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r[i] = lhs[i] * rhs; 10273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 10373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 10473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 10573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 10673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VEC, 10773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 10873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 10973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 11073e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianVEC<TYPE, SIZE> PURE doScalarMul( 11173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TypeTraits<TYPE>::ParameterType lhs, 11273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VEC<TYPE, SIZE>& rhs) { 11373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian VEC<TYPE, SIZE> r; 11473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 11573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r[i] = lhs * rhs[i]; 11673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 11773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 11873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 11973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; // namespace helpers 12073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 12173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 12273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// Below we define the mathematical operators for vectors. 12373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// We use template template arguments so we can generically 12473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// handle the case where the right-hand-size and left-hand-side are 12573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// different vector types (but with same value_type and size). 12673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// This is needed for performance when using ".xy{z}" element access 12773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// on vec<>. Without this, an extra conversion to vec<> would be needed. 12873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// 12973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// example: 13073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// vec4_t a; 13173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// vec3_t b; 13273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// vec3_t c = a.xyz + b; 13373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// 13473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// "a.xyz + b" is a mixed-operation between a vbase<> and a vec<>, requiring 13573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// a conversion of vbase<> to vec<>. The template gunk below avoids this, 13673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// by allowing the addition on these different vector types directly 13773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// 13873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 13973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 14073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VLHS, 14173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VRHS, 14273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 14373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 14473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 14573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianinline VLHS<TYPE, SIZE> PURE operator + ( 14673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VLHS<TYPE, SIZE>& lhs, 14773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VRHS<TYPE, SIZE>& rhs) { 14873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doAdd(lhs, rhs); 14973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 15073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 15173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 15273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VLHS, 15373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VRHS, 15473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 15573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 15673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 15773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianinline VLHS<TYPE, SIZE> PURE operator - ( 15873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VLHS<TYPE, SIZE>& lhs, 15973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VRHS<TYPE, SIZE>& rhs) { 16073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doSub(lhs, rhs); 16173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 16273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 16373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 16473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VEC, 16573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 16673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 16773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 16873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianinline VEC<TYPE, SIZE> PURE operator * ( 16973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VEC<TYPE, SIZE>& lhs, 17073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TypeTraits<TYPE>::ParameterType rhs) { 17173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doMulScalar(lhs, rhs); 17273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 17373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 17473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 17573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VEC, 17673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 17773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 17873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 17973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianinline VEC<TYPE, SIZE> PURE operator * ( 18073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TypeTraits<TYPE>::ParameterType lhs, 18173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VEC<TYPE, SIZE>& rhs) { 18273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doScalarMul(lhs, rhs); 18373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 18473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 18573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 18673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 18773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VLHS, 18873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VRHS, 18973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 19073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 19173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 19273e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianTYPE PURE dot_product( 19373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VLHS<TYPE, SIZE>& lhs, 19473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VRHS<TYPE, SIZE>& rhs) { 19573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian TYPE r(0); 19673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 19773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r += lhs[i] * rhs[i]; 19873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 19973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 20073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 20173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 20273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class V, 20373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE, 20473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_t SIZE 20573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 20673e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianTYPE PURE length(const V<TYPE, SIZE>& v) { 20773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return sqrt(dot_product(v, v)); 20873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 20973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 21073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate < 2116043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian template<typename T, size_t S> class V, 2126043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian typename TYPE, 2136043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian size_t SIZE 2146043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian> 215f5cfea78b0454a31571693ee86c321adcb965410Michael JohnsonTYPE PURE length_squared(const V<TYPE, SIZE>& v) { 216f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson return dot_product(v, v); 217f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson} 218f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson 219f5cfea78b0454a31571693ee86c321adcb965410Michael Johnsontemplate < 220f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson template<typename T, size_t S> class V, 221f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson typename TYPE, 222f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson size_t SIZE 223f5cfea78b0454a31571693ee86c321adcb965410Michael Johnson> 2246043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias AgopianV<TYPE, SIZE> PURE normalize(const V<TYPE, SIZE>& v) { 2256043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian return v * (1/length(v)); 2266043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian} 2276043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopian 2286043e5329cc023ae1bf6c0b7b750e584c1ebfbf4Mathias Agopiantemplate < 22973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VLHS, 23073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename T, size_t S> class VRHS, 23173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typename TYPE 23273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian> 23373e0bc805a143d8cc2202fccb73230459edc6869Mathias AgopianVLHS<TYPE, 3> PURE cross_product( 23473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VLHS<TYPE, 3>& u, 23573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const VRHS<TYPE, 3>& v) { 23673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian VLHS<TYPE, 3> r; 23773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r.x = u.y*v.z - u.z*v.y; 23873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r.y = u.z*v.x - u.x*v.z; 23973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r.z = u.x*v.y - u.y*v.x; 24073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 24173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 24273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 24373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 24473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 24573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianvec<TYPE, SIZE> PURE operator - (const vec<TYPE, SIZE>& lhs) { 24673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec<TYPE, SIZE> r; 24773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 24873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian r[i] = -lhs[i]; 24973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return r; 25073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 25173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 25273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 25373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 25473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// This our basic vector type, it just implements the data storage 25573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// and accessors. 25673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 25773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 25873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct vbase { 25973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian TYPE v[SIZE]; 26073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline const TYPE& operator[](size_t i) const { return v[i]; } 26173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline TYPE& operator[](size_t i) { return v[i]; } 26273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 26373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate<> struct vbase<float, 2> { 26473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian union { 26573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian float v[2]; 26673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian struct { float x, y; }; 26773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian struct { float s, t; }; 26873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian }; 26973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline const float& operator[](size_t i) const { return v[i]; } 27073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline float& operator[](size_t i) { return v[i]; } 27173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 27273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate<> struct vbase<float, 3> { 27373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian union { 27473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian float v[3]; 27573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian struct { float x, y, z; }; 27673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian struct { float s, t, r; }; 27773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vbase<float, 2> xy; 27873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vbase<float, 2> st; 27973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian }; 28073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline const float& operator[](size_t i) const { return v[i]; } 28173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline float& operator[](size_t i) { return v[i]; } 28273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 28373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate<> struct vbase<float, 4> { 28473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian union { 28573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian float v[4]; 28673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian struct { float x, y, z, w; }; 28773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian struct { float s, t, r, q; }; 28873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vbase<float, 3> xyz; 28973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vbase<float, 3> str; 29073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vbase<float, 2> xy; 29173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vbase<float, 2> st; 29273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian }; 29373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline const float& operator[](size_t i) const { return v[i]; } 29473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian inline float& operator[](size_t i) { return v[i]; } 29573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 29673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 29773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 29873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 29973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 30073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianclass vec : public vbase<TYPE, SIZE> 30173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian{ 30273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef typename TypeTraits<TYPE>::ParameterType pTYPE; 30373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef vbase<TYPE, SIZE> base; 30473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 30573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianpublic: 30673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // STL-like interface. 30773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPE value_type; 30873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPE& reference; 30973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPE const& const_reference; 31073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef size_t size_type; 31173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 31273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPE* iterator; 31373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPE const* const_iterator; 31473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian iterator begin() { return base::v; } 31573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian iterator end() { return base::v + SIZE; } 31673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const_iterator begin() const { return base::v; } 31773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian const_iterator end() const { return base::v + SIZE; } 31873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian size_type size() const { return SIZE; } 31973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 32073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // ----------------------------------------------------------------------- 32173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // default constructors 32273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 32373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec() { } 32473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec(const vec& rhs) : base(rhs) { } 32573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec(const base& rhs) : base(rhs) { } 32673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 32773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // ----------------------------------------------------------------------- 32873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // conversion constructors 32973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 33073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec(pTYPE rhs) { 33173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 33273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian base::operator[](i) = rhs; 33373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 33473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 33573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template < template<typename T, size_t S> class VEC, size_t S> 33673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian explicit vec(const VEC<TYPE, S>& rhs) { 33773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian helpers::doAssign(*this, rhs); 33873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 33973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 34073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian explicit vec(TYPE const* array) { 34173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 34273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian base::operator[](i) = array[i]; 34373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 34473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 34573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // ----------------------------------------------------------------------- 34673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // Assignment 34773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 34873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator = (const vec& rhs) { 34973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian base::operator=(rhs); 35073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return *this; 35173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 35273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 35373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator = (const base& rhs) { 35473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian base::operator=(rhs); 35573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return *this; 35673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 35773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 35873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator = (pTYPE rhs) { 35973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 36073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian base::operator[](i) = rhs; 36173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return *this; 36273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 36373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 36473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template < template<typename T, size_t S> class VEC, size_t S> 36573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator = (const VEC<TYPE, S>& rhs) { 36673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doAssign(*this, rhs); 36773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 36873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 36973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // ----------------------------------------------------------------------- 37073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // operation-assignment 37173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 37273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator += (const vec& rhs); 37373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator -= (const vec& rhs); 37473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec& operator *= (pTYPE rhs); 37573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 37673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // ----------------------------------------------------------------------- 37773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // non-member function declaration and definition 37873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // NOTE: we declare the non-member function as friend inside the class 37973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // so that they are known to the compiler when the class is instantiated. 38073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // This helps the compiler doing template argument deduction when the 38173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // passed types are not identical. Essentially this helps with 38273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // type conversion so that you can multiply a vec<float> by an scalar int 38373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // (for instance). 38473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 38573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian friend inline vec PURE operator + (const vec& lhs, const vec& rhs) { 38673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doAdd(lhs, rhs); 38773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 38873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian friend inline vec PURE operator - (const vec& lhs, const vec& rhs) { 38973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doSub(lhs, rhs); 39073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 39173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian friend inline vec PURE operator * (const vec& lhs, pTYPE v) { 39273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doMulScalar(lhs, v); 39373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 39473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian friend inline vec PURE operator * (pTYPE v, const vec& rhs) { 39573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return helpers::doScalarMul(v, rhs); 39673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 39773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian friend inline TYPE PURE dot_product(const vec& lhs, const vec& rhs) { 39873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return android::dot_product(lhs, rhs); 39973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian } 40073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 40173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 40273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 40373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 40473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 40573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianvec<TYPE, SIZE>& vec<TYPE, SIZE>::operator += (const vec<TYPE, SIZE>& rhs) { 40673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec<TYPE, SIZE>& lhs(*this); 40773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 40873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian lhs[i] += rhs[i]; 40973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return lhs; 41073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 41173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 41273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 41373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianvec<TYPE, SIZE>& vec<TYPE, SIZE>::operator -= (const vec<TYPE, SIZE>& rhs) { 41473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec<TYPE, SIZE>& lhs(*this); 41573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 41673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian lhs[i] -= rhs[i]; 41773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return lhs; 41873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 41973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 42073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TYPE, size_t SIZE> 42173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianvec<TYPE, SIZE>& vec<TYPE, SIZE>::operator *= (vec<TYPE, SIZE>::pTYPE rhs) { 42273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian vec<TYPE, SIZE>& lhs(*this); 42373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian for (size_t i=0 ; i<SIZE ; i++) 42473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian lhs[i] *= rhs; 42573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian return lhs; 42673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian} 42773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 42873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 42973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 43073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantypedef vec<float, 2> vec2_t; 43173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantypedef vec<float, 3> vec3_t; 43273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantypedef vec<float, 4> vec4_t; 43373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 43473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 43573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 43673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; // namespace android 43773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 43873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#endif /* ANDROID_VEC_H */ 439