1 /+ 2 Vasaro Copyright © 2018 Andrea Fontana 3 This file is part of Vasaro. 4 5 Vasaro is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 Vasaro is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with Vasaro. If not, see <http://www.gnu.org/licenses/>. 17 +/ 18 module vec3; 19 20 struct Vec3 21 { 22 import std.traits: isNumeric; 23 import core.simd; 24 25 version(D_SIMD) { pragma(msg, "SIMD enabled"); } 26 else { pragma(msg, "SIMD not enabled"); } 27 28 union 29 { 30 version(D_SIMD) 31 { 32 float4 simd = 0; 33 } 34 35 float[3] data; 36 struct { float x; float y; float z; } 37 } 38 39 // Better avoid copy c-tors 40 @disable this(this); 41 42 this(float x, float y, float z) { this.data = [x,y,z]; } 43 this(float[3] data) { this.data[] = data[]; } 44 45 Vec3 opBinary(string op)(const ref Vec3 v) const if((op == "+") || (op == "-") || (op == "*") || (op == "/")) { 46 Vec3 result; 47 version(D_SIMD) { result.simd = mixin("simd" ~ op ~ "v.simd"); } 48 else { result.data[] = mixin("data[]" ~ op ~ "v.data[]"); } 49 return result; 50 } 51 52 Vec3 opBinary(string op, T)(const T v) const if(((op == "+") || (op == "-") || (op == "*") || (op == "/")) && isNumeric!T) { 53 Vec3 result; 54 version(D_SIMD) { result.simd = mixin("simd" ~ op ~ "v"); } 55 else { result.data[] = mixin("data[]" ~ op ~ "v"); } 56 return result; 57 } 58 59 void opOpAssign(string op)(const ref Vec3 v) if((op == "+") || (op == "-") || (op == "*") || (op == "/")) { 60 version(D_SIMD) { mixin("simd = simd " ~ op ~ "v.simd;"); } 61 else { mixin("this.data[] " ~ op ~ "= v.data[];"); } 62 } 63 64 void opOpAssign(string op, T)(const T v) if(((op == "+") || (op == "-") || (op == "*") || (op == "/")) && isNumeric!T) { 65 version(D_SIMD) { mixin("simd = simd " ~ op ~ "v;"); } 66 else { mixin("this.data[] " ~ op ~ "= v;"); } 67 } 68 69 void opAssign(const ref Vec3 v) 70 { 71 version(D_SIMD) { simd = v.simd; } 72 else { this.data[] = v.data[]; } 73 } 74 75 void opAssign(Vec3 v) 76 { 77 version(D_SIMD) { simd = v.simd; } 78 else { this.data[] = v.data[]; } 79 } 80 81 @property float magnitude() const 82 { 83 import std.math : sqrt; 84 return sqrt(x*x + y*y + z*z); 85 } 86 87 Vec3 normalized() const 88 { 89 auto m = magnitude(); 90 if (m == 0) return Vec3(); 91 else return this / magnitude; 92 } 93 94 void normalize() 95 { 96 auto m = magnitude(); 97 if (m == 0) return; 98 else this /= magnitude; 99 } 100 101 Vec3 dotProduct (const ref Vec3 v) const { return this*v; } 102 Vec3 crossProduct (Vec3 v) const { return Vec3(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); } 103 104 }