From 61ddd9fc269347850267ef0ab11d5a485a3b578d Mon Sep 17 00:00:00 2001 From: Gnarly Narwhal Date: Fri, 26 Apr 2019 08:56:58 -0700 Subject: [PATCH] Added engine --- .gitignore | 4 + LICENSE | 21 + src/geno/GenoChars.h | 34 + src/geno/GenoInts.h | 39 + src/geno/GenoMacros.h | 32 + src/geno/audio/GenoAL.h | 33 + src/geno/audio/GenoAudioBuffer.cpp | 74 + src/geno/audio/GenoAudioBuffer.h | 50 + src/geno/audio/GenoAudioDevice.cpp | 108 + src/geno/audio/GenoAudioDevice.h | 68 + src/geno/audio/GenoAudioSource.cpp | 70 + src/geno/audio/GenoAudioSource.h | 49 + src/geno/audio/GenoListener.cpp | 73 + src/geno/audio/GenoListener.h | 49 + src/geno/data/GenoImage.cpp | 208 + src/geno/data/GenoImage.h | 66 + src/geno/data/GenoWavFile.cpp | 87 + src/geno/data/GenoWavFile.h | 21 + src/geno/engine/GenoCamera2D.cpp | 71 + src/geno/engine/GenoCamera2D.h | 58 + src/geno/engine/GenoEngine.cpp | 127 + src/geno/engine/GenoEngine.h | 122 + src/geno/engine/GenoInput.cpp | 142 + src/geno/engine/GenoInput.h | 88 + src/geno/engine/GenoLoop.cpp | 133 + src/geno/engine/GenoLoop.h | 82 + src/geno/engine/GenoMonitor.cpp | 227 + src/geno/engine/GenoMonitor.h | 131 + src/geno/engine/GenoWindow.cpp | 300 + src/geno/engine/GenoWindow.h | 127 + src/geno/exceptions/GenoException.cpp | 35 + src/geno/exceptions/GenoException.h | 42 + .../exceptions/GenoMaxCapacityException.cpp | 30 + .../exceptions/GenoMaxCapacityException.h | 38 + src/geno/gl/GenoFramebuffer.cpp | 151 + src/geno/gl/GenoFramebuffer.h | 100 + src/geno/gl/GenoGL.h | 36 + src/geno/gl/GenoShader.cpp | 178 + src/geno/gl/GenoShader.h | 65 + src/geno/gl/GenoSpritesheet.cpp | 172 + src/geno/gl/GenoSpritesheet.h | 92 + src/geno/gl/GenoTexture.cpp | 38 + src/geno/gl/GenoTexture.h | 45 + src/geno/gl/GenoTexture2D.cpp | 94 + src/geno/gl/GenoTexture2D.h | 75 + src/geno/gl/GenoVao.cpp | 72 + src/geno/gl/GenoVao.h | 44 + src/geno/math/GenoConstants.h | 34 + src/geno/math/linear/GenoMatrix.h | 195 + src/geno/math/linear/GenoMatrix4.h | 8579 +++++++++++++++++ src/geno/math/linear/GenoMatrixN.h | 200 + src/geno/math/linear/GenoVector.h | 476 + src/geno/math/linear/GenoVector1.h | 56 + src/geno/math/linear/GenoVector2.h | 1080 +++ src/geno/math/linear/GenoVector3.h | 3080 ++++++ src/geno/math/linear/GenoVector4.h | 7440 ++++++++++++++ src/geno/math/linear/GenoVectorDimensions.cpp | 34 + src/geno/math/linear/GenoVectorDimensions.h | 41 + src/geno/shaders/GenoShader2c.cpp | 42 + src/geno/shaders/GenoShader2c.h | 43 + src/geno/shaders/GenoShader2ss.cpp | 42 + src/geno/shaders/GenoShader2ss.h | 43 + src/geno/shaders/GenoShader2t.cpp | 37 + src/geno/shaders/GenoShader2t.h | 39 + src/geno/shaders/src/Shader2c/Shader2cf.gls | 35 + src/geno/shaders/src/Shader2c/Shader2cv.gls | 35 + src/geno/shaders/src/Shader2ss/Shader2ssf.gls | 37 + src/geno/shaders/src/Shader2ss/Shader2ssv.gls | 40 + src/geno/shaders/src/Shader2t/Shader2tf.gls | 37 + src/geno/shaders/src/Shader2t/Shader2tv.gls | 39 + src/geno/template/GenoArrayList.h | 168 + src/geno/template/GenoQueue.h | 150 + src/geno/template/GenoStack.h | 131 + src/geno/thread/GenoThreadPool.cpp | 104 + src/geno/thread/GenoThreadPool.h | 98 + src/geno/thread/GenoTime.cpp | 43 + src/geno/thread/GenoTime.h | 60 + src/main.cpp | 156 + 78 files changed, 26595 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 src/geno/GenoChars.h create mode 100644 src/geno/GenoInts.h create mode 100644 src/geno/GenoMacros.h create mode 100644 src/geno/audio/GenoAL.h create mode 100644 src/geno/audio/GenoAudioBuffer.cpp create mode 100644 src/geno/audio/GenoAudioBuffer.h create mode 100644 src/geno/audio/GenoAudioDevice.cpp create mode 100644 src/geno/audio/GenoAudioDevice.h create mode 100644 src/geno/audio/GenoAudioSource.cpp create mode 100644 src/geno/audio/GenoAudioSource.h create mode 100644 src/geno/audio/GenoListener.cpp create mode 100644 src/geno/audio/GenoListener.h create mode 100644 src/geno/data/GenoImage.cpp create mode 100644 src/geno/data/GenoImage.h create mode 100644 src/geno/data/GenoWavFile.cpp create mode 100644 src/geno/data/GenoWavFile.h create mode 100644 src/geno/engine/GenoCamera2D.cpp create mode 100644 src/geno/engine/GenoCamera2D.h create mode 100644 src/geno/engine/GenoEngine.cpp create mode 100644 src/geno/engine/GenoEngine.h create mode 100644 src/geno/engine/GenoInput.cpp create mode 100644 src/geno/engine/GenoInput.h create mode 100644 src/geno/engine/GenoLoop.cpp create mode 100644 src/geno/engine/GenoLoop.h create mode 100644 src/geno/engine/GenoMonitor.cpp create mode 100644 src/geno/engine/GenoMonitor.h create mode 100644 src/geno/engine/GenoWindow.cpp create mode 100644 src/geno/engine/GenoWindow.h create mode 100644 src/geno/exceptions/GenoException.cpp create mode 100644 src/geno/exceptions/GenoException.h create mode 100644 src/geno/exceptions/GenoMaxCapacityException.cpp create mode 100644 src/geno/exceptions/GenoMaxCapacityException.h create mode 100644 src/geno/gl/GenoFramebuffer.cpp create mode 100644 src/geno/gl/GenoFramebuffer.h create mode 100644 src/geno/gl/GenoGL.h create mode 100644 src/geno/gl/GenoShader.cpp create mode 100644 src/geno/gl/GenoShader.h create mode 100644 src/geno/gl/GenoSpritesheet.cpp create mode 100644 src/geno/gl/GenoSpritesheet.h create mode 100644 src/geno/gl/GenoTexture.cpp create mode 100644 src/geno/gl/GenoTexture.h create mode 100644 src/geno/gl/GenoTexture2D.cpp create mode 100644 src/geno/gl/GenoTexture2D.h create mode 100644 src/geno/gl/GenoVao.cpp create mode 100644 src/geno/gl/GenoVao.h create mode 100644 src/geno/math/GenoConstants.h create mode 100644 src/geno/math/linear/GenoMatrix.h create mode 100644 src/geno/math/linear/GenoMatrix4.h create mode 100644 src/geno/math/linear/GenoMatrixN.h create mode 100644 src/geno/math/linear/GenoVector.h create mode 100644 src/geno/math/linear/GenoVector1.h create mode 100644 src/geno/math/linear/GenoVector2.h create mode 100644 src/geno/math/linear/GenoVector3.h create mode 100644 src/geno/math/linear/GenoVector4.h create mode 100644 src/geno/math/linear/GenoVectorDimensions.cpp create mode 100644 src/geno/math/linear/GenoVectorDimensions.h create mode 100644 src/geno/shaders/GenoShader2c.cpp create mode 100644 src/geno/shaders/GenoShader2c.h create mode 100644 src/geno/shaders/GenoShader2ss.cpp create mode 100644 src/geno/shaders/GenoShader2ss.h create mode 100644 src/geno/shaders/GenoShader2t.cpp create mode 100644 src/geno/shaders/GenoShader2t.h create mode 100644 src/geno/shaders/src/Shader2c/Shader2cf.gls create mode 100644 src/geno/shaders/src/Shader2c/Shader2cv.gls create mode 100644 src/geno/shaders/src/Shader2ss/Shader2ssf.gls create mode 100644 src/geno/shaders/src/Shader2ss/Shader2ssv.gls create mode 100644 src/geno/shaders/src/Shader2t/Shader2tf.gls create mode 100644 src/geno/shaders/src/Shader2t/Shader2tv.gls create mode 100644 src/geno/template/GenoArrayList.h create mode 100644 src/geno/template/GenoQueue.h create mode 100644 src/geno/template/GenoStack.h create mode 100644 src/geno/thread/GenoThreadPool.cpp create mode 100644 src/geno/thread/GenoThreadPool.h create mode 100644 src/geno/thread/GenoTime.cpp create mode 100644 src/geno/thread/GenoTime.h create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c3ea78 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +x64/ +Debug/ +Release/ +*.vcxproj* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e129676 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +Mit License + +Copyright (c) 2018 Gnarly Narwhal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/geno/GenoChars.h b/src/geno/GenoChars.h new file mode 100644 index 0000000..4dc2398 --- /dev/null +++ b/src/geno/GenoChars.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_CHARS +#define GNARLY_GENOME_CHARS + +using char8 = char; +using char16 = short; +using char32 = int; + +#endif // GNARLY_GENOME_CHARS \ No newline at end of file diff --git a/src/geno/GenoInts.h b/src/geno/GenoInts.h new file mode 100644 index 0000000..4f5f5e4 --- /dev/null +++ b/src/geno/GenoInts.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_INTS +#define GNARLY_GENOME_INTS + +using int8 = signed char; +using uint8 = unsigned char; +using int16 = signed short; +using uint16 = unsigned short; +using int32 = signed int; +using uint32 = unsigned int; +using int64 = signed long long; +using uint64 = unsigned long long; + +#endif // GNARLY_GENOME_INTS \ No newline at end of file diff --git a/src/geno/GenoMacros.h b/src/geno/GenoMacros.h new file mode 100644 index 0000000..b8a8fb9 --- /dev/null +++ b/src/geno/GenoMacros.h @@ -0,0 +1,32 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_MACROS +#define GNARLY_GENOME_MACROS + +#define GENO_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +#endif // GNARLY_GENOME_MACROS \ No newline at end of file diff --git a/src/geno/audio/GenoAL.h b/src/geno/audio/GenoAL.h new file mode 100644 index 0000000..4916b6c --- /dev/null +++ b/src/geno/audio/GenoAL.h @@ -0,0 +1,33 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_AL +#define GNARLY_GENOME_AL + +#include +#include + +#endif // GNARLY_GENOME_AL \ No newline at end of file diff --git a/src/geno/audio/GenoAudioBuffer.cpp b/src/geno/audio/GenoAudioBuffer.cpp new file mode 100644 index 0000000..1f046f0 --- /dev/null +++ b/src/geno/audio/GenoAudioBuffer.cpp @@ -0,0 +1,74 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "AL\al.h" + +#include "GenoAudioBuffer.h" + +void GenoAudioBuffer::clean() { + if (buffer) + alDeleteBuffers(1, &buffer); +} + +GenoAudioBuffer::GenoAudioBuffer(uint32 format, uint32 size, uint8 data[], uint32 frequency) { + clean(); + alGenBuffers(1, &buffer); + alBufferData(buffer, format, data, size, frequency); +} + +GenoAudioBuffer::GenoAudioBuffer(GenoWavFile * wavFile) { + bufferData(wavFile->getFormat(), wavFile->getSize(), wavFile->getData(), wavFile->getSampleRate()); +} + +GenoAudioBuffer::GenoAudioBuffer(const char * path) { + GenoWavFile * file = new GenoWavFile(path); + loadWav(file); + delete file; +} + +void GenoAudioBuffer::bufferData(uint32 format, uint32 size, uint8 data[], uint32 frequency) { + clean(); + alGenBuffers(1, &buffer); + alBufferData(buffer, format, data, size, frequency); +} + +void GenoAudioBuffer::loadWav(GenoWavFile * wavFile) { + bufferData(wavFile->getFormat(), wavFile->getSize(), wavFile->getData(), wavFile->getSampleRate()); +} + +void GenoAudioBuffer::loadWav(const char * path) { + GenoWavFile * file = new GenoWavFile(path); + loadWav(file); + delete file; +} + +uint32 GenoAudioBuffer::getBuffer() { + return buffer; +} + +GenoAudioBuffer::~GenoAudioBuffer() { + clean(); +} \ No newline at end of file diff --git a/src/geno/audio/GenoAudioBuffer.h b/src/geno/audio/GenoAudioBuffer.h new file mode 100644 index 0000000..7bf82db --- /dev/null +++ b/src/geno/audio/GenoAudioBuffer.h @@ -0,0 +1,50 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_AUDIO_BUFFER +#define GNARLY_GENOME_AUDIO_BUFFER + +#include "../GenoInts.h" +#include "../data/GenoWavFile.h" + +class GenoAudioBuffer { + private: + uint32 buffer; + + void clean(); + public: + GenoAudioBuffer(uint32 format, uint32 size, uint8 data[], uint32 frequency); + GenoAudioBuffer(GenoWavFile * wavFile); + GenoAudioBuffer(const char * path); + void bufferData(uint32 format, uint32 size, uint8 data[], uint32 frequency); + void loadWav(GenoWavFile * wavFile); + void loadWav(const char * path); + uint32 getBuffer(); + ~GenoAudioBuffer(); +}; + +#define GNARLY_GENOME_AUDIO_BUFFER_FORWARD +#endif // GNARLY_GENOME_AUDIO_BUFFER \ No newline at end of file diff --git a/src/geno/audio/GenoAudioDevice.cpp b/src/geno/audio/GenoAudioDevice.cpp new file mode 100644 index 0000000..6d09c48 --- /dev/null +++ b/src/geno/audio/GenoAudioDevice.cpp @@ -0,0 +1,108 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include "GenoAudioDevice.h" + +GenoAudioOutputDevice::GenoAudioOutputDevice(ALCdevice * device, const char * name) { + this->device = device; + context = alcCreateContext(device, 0); + int32 nameLength = strlen(name); + this->name = new char[nameLength + 1]; + strcpy(this->name, name); +} + +void GenoAudioOutputDevice::setActive() { + alcMakeContextCurrent(context); +} + +const char * GenoAudioOutputDevice::getName() { + return name; +} + +GenoAudioOutputDevice::~GenoAudioOutputDevice() { + alcDestroyContext(context); + alcCloseDevice(device); +} + +int32 GenoAudioDevices::numOutputDevices = 0; +GenoAudioOutputDevice ** GenoAudioDevices::outputDevices = 0; + +void GenoAudioDevices::init() { + bool enumOk = alcIsExtensionPresent(0, "ALC_ENUMERATION_EXT"); + if (enumOk) { + numOutputDevices = 0; + const char * devices = alcGetString(0, ALC_DEVICE_SPECIFIER); + const char * loop = devices; + while (*loop) { + ++numOutputDevices; + loop += strlen(loop) + 1; + } + outputDevices = new GenoAudioOutputDevice*[numOutputDevices]; + loop = devices; + for (int32 i = 0; i < numOutputDevices; ++i) { + outputDevices[i] = new GenoAudioOutputDevice(alcOpenDevice(loop), loop); + loop += strlen(loop) + 1; + } + } + else { + ALCdevice * device = alcOpenDevice(0); + if(device) { + numOutputDevices = 1; + outputDevices = new GenoAudioOutputDevice*[1] { new GenoAudioOutputDevice(device, alcGetString(device, ALC_DEVICE_SPECIFIER)) }; + } + else { + numOutputDevices = 0; + outputDevices = 0; + } + } +} + +uint32 GenoAudioDevices::getNumOutputDevices() { + return numOutputDevices; +} + +GenoAudioOutputDevice * GenoAudioDevices::getDefaultOutputDevice() { + return outputDevices[0]; +} + +GenoAudioOutputDevice * GenoAudioDevices::getOutputDevice(uint32 outputDevice) { + if(outputDevice >= 0 && outputDevice < numOutputDevices) + return outputDevices[outputDevice]; + else + return 0; +} + +void GenoAudioDevices::cleanup() { + for (int32 i = 0; i < numOutputDevices; ++i) + delete outputDevices[i]; + delete [] outputDevices; +} + +GenoAudioDevices::GenoAudioDevices() {} +GenoAudioDevices::~GenoAudioDevices() {} \ No newline at end of file diff --git a/src/geno/audio/GenoAudioDevice.h b/src/geno/audio/GenoAudioDevice.h new file mode 100644 index 0000000..0c0e295 --- /dev/null +++ b/src/geno/audio/GenoAudioDevice.h @@ -0,0 +1,68 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_AUDIO_DEVICE +#define GNARLY_GENOME_AUDIO_DEVICE + +#include "../GenoInts.h" +#include "GenoAL.h" +#include "../engine/GenoEngine.h" + +class GenoAudioOutputDevice { + private: + GenoAudioOutputDevice(ALCdevice * device, const char * name); + ALCdevice * device; + ALCcontext * context; + char * name; + + public: + void setActive(); + const char * getName(); + ~GenoAudioOutputDevice(); + + friend class GenoAudioDevices; +}; + +class GenoAudioDevices final { + private: + static int32 numOutputDevices; + static GenoAudioOutputDevice ** outputDevices; + + GenoAudioDevices(); + ~GenoAudioDevices(); + + static void init(); + static void cleanup(); + public: + static uint32 getNumOutputDevices(); + static GenoAudioOutputDevice * getDefaultOutputDevice(); + static GenoAudioOutputDevice * getOutputDevice(uint32 outputDevice); + + friend class GenoEngine; +}; + +#define GNARLY_GENOME_AUDIO_DEVICE_FORWARD +#endif // GNARLY_GENOME_AUDIO_DEVICE \ No newline at end of file diff --git a/src/geno/audio/GenoAudioSource.cpp b/src/geno/audio/GenoAudioSource.cpp new file mode 100644 index 0000000..d0f6658 --- /dev/null +++ b/src/geno/audio/GenoAudioSource.cpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include + +#include "GenoAudioSource.h" + +GenoAudioSource::GenoAudioSource() { + alGenSources(1, &source); + alSourcef(source, AL_GAIN, 1); + alSource3f(source, AL_POSITION, 0, 0, 0); + alSource3f(source, AL_DIRECTION, 0, 0, 0); +} + +GenoAudioSource::GenoAudioSource(GenoAudioBuffer * buffer) { + alGenSources(1, &source); + alSourcef(source, AL_GAIN, 1); + alSource3f(source, AL_POSITION, 0, 0, 0); + alSource3f(source, AL_DIRECTION, 0, 0, 0); + alSourcei(source, AL_BUFFER, buffer->getBuffer()); +} + +void GenoAudioSource::setBuffer(GenoAudioBuffer * buffer) { + alSourcei(source, AL_BUFFER, buffer->getBuffer()); +} + +void GenoAudioSource::play() { + alSourcePlay(source); +} + +void GenoAudioSource::stop() { + alSourceStop(source); +} + +void GenoAudioSource::pause() { + alSourcePause(source); +} + +void GenoAudioSource::loop(bool loop) { + alSourcei(source, AL_LOOPING, loop); +} + +GenoAudioSource::~GenoAudioSource() { + alDeleteSources(1, &source); +} diff --git a/src/geno/audio/GenoAudioSource.h b/src/geno/audio/GenoAudioSource.h new file mode 100644 index 0000000..b8fcbf7 --- /dev/null +++ b/src/geno/audio/GenoAudioSource.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_AUDIO_SOURCE +#define GNARLY_GENOME_AUDIO_SOURCE + +#include "../GenoInts.h" +#include "GenoAudioBuffer.h" + +class GenoAudioSource { + private: + uint32 source; + + public: + GenoAudioSource(); + GenoAudioSource(GenoAudioBuffer * buffer); + void play(); + void pause(); + void stop(); + void setBuffer(GenoAudioBuffer * buffer); + void loop(bool loop); + ~GenoAudioSource(); +}; + +#define GNARLY_GENOME_AUDIO_SOURCE_FOWARD +#endif // GNARLY_GENOME_AUDIO_SOURCE \ No newline at end of file diff --git a/src/geno/audio/GenoListener.cpp b/src/geno/audio/GenoListener.cpp new file mode 100644 index 0000000..1f389d1 --- /dev/null +++ b/src/geno/audio/GenoListener.cpp @@ -0,0 +1,73 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoAL.h" + +#include "GenoListener.h" + +GenoListener::GenoListener() : + position(GenoVector3f()), + velocity(GenoVector3f()), + at(0, 0, -1), + up(0, 1, 0), + gain(1) {} + +GenoListener::GenoListener(GenoVector3f position, GenoVector3f velocity, GenoVector3f at, GenoVector3f up, float gain) : + position(position), + velocity(velocity), + at(at), + up(up), + gain(gain) {} + +void GenoListener::setActive() { + alListener3f(AL_POSITION, position.x(), position.y(), position.z()); + + alListener3f(AL_VELOCITY, velocity.x(), velocity.y(), velocity.z()); + + float orientation[] = { at.x(), at.y(), at.z(), up.x(), up.y(), up.z() }; + alListenerfv(AL_ORIENTATION, orientation); + + alListenerf(AL_GAIN, gain); +} + +void GenoListener::setPosition(GenoVector3f position) { + this->position = position; +} + +void GenoListener::setVelocity(GenoVector3f velocity) { + this->velocity = velocity; +} + +void GenoListener::setOrientation(GenoVector3f at, GenoVector3f up) { + this->at = at; + this->up = up; +} + +void GenoListener::setGain(float gain) { + this->gain = gain; +} + +GenoListener::~GenoListener() {} \ No newline at end of file diff --git a/src/geno/audio/GenoListener.h b/src/geno/audio/GenoListener.h new file mode 100644 index 0000000..d97a62e --- /dev/null +++ b/src/geno/audio/GenoListener.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_LISTENER +#define GNARLY_GENOME_LISTENER + +#include "../math/linear/GenoVector3.h" + +class GenoListener { + private: + GenoVector3f position, velocity, at, up; + float gain; + + public: + GenoListener(); + GenoListener(GenoVector3f position, GenoVector3f velocity, GenoVector3f at, GenoVector3f up, float gain); + void setActive(); + void setPosition(GenoVector3f position); + void setVelocity(GenoVector3f velocity); + void setOrientation(GenoVector3f at, GenoVector3f up); + void setGain(float gain); + ~GenoListener(); +}; + +#define GNARLY_GENOME_LISTENER_FORWARD +#endif // GNARLY_GENOME_LISTENER \ No newline at end of file diff --git a/src/geno/data/GenoImage.cpp b/src/geno/data/GenoImage.cpp new file mode 100644 index 0000000..46a639f --- /dev/null +++ b/src/geno/data/GenoImage.cpp @@ -0,0 +1,208 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include + +#include "GenoImage.h" + +struct GenoBitmapFileHeader { + uint16 signature; + uint32 fileSize; + uint16 res1; + uint16 res2; + uint32 offset; +}; + +struct GenoBitmapInfoHeader { + uint32 headerSize; + uint32 width; + uint32 height; + uint16 colorPlanes; + uint16 bitsPerPixel; + uint32 compression; + uint32 imageSize; + uint32 horzRes; + uint32 vertRes; + uint32 colorPerPalette; + uint32 important; +}; + +GenoImage::GenoImage() {} + +GenoImage * GenoImage::create(const GenoImageCreateInfo & info) { + uint32 width = 0; + uint32 height = 0; + uint8 * image = 0; + switch (info.type) { + case GENO_IMAGE_TYPE_CREATE: { + width = info.width; + height = info.height; + uint64 size = width * height * 4; + image = new uint8[size]; + for (int32 i = 0; i < size; i += 4) { + image[i ] = info.r; + image[i + 1] = info.g; + image[i + 2] = info.b; + image[i + 3] = info.a; + } + break; + } + case GENO_IMAGE_TYPE_BMP: { + std::ifstream file(info.path, std::ios::binary); + if (file) { + GenoBitmapFileHeader fileHeader; + file.read(reinterpret_cast (&fileHeader), sizeof(fileHeader)); + + if (fileHeader.signature == 0x4D42) { + GenoBitmapInfoHeader infoHeader; + file.read(reinterpret_cast (&infoHeader), sizeof(infoHeader)); + + + width = infoHeader.width; + height = infoHeader.height; + + image = new uint8[width * height * 4]; + + if (infoHeader.bitsPerPixel == 24 && infoHeader.compression == 0) { + + uint8 padding = (4 - (width * 3) % 4) % 4; + + file.seekg(fileHeader.offset); + int32 lWidth = width * 4; + int32 lHeight = height * 4; + for (int32 i = lHeight - 4; i >= 0; i -= 4) { + for (int32 j = 0; j < lWidth; j += 4) { + int pixel = j * height + i; + image[pixel + 3] = file.get(); + image[pixel + 2] = file.get(); + image[pixel + 1] = file.get(); + image[pixel ] = 0xFF; + } + file.seekg(padding, std::ios::cur); + } + } + else + return 0; + } + else + return 0; + } + else + return 0; + file.close(); + break; + } + case GENO_IMAGE_TYPE_PNG: { + FILE * fp = fopen(info.path, "rb"); + + png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + png_infop info = png_create_info_struct(png); + + png_init_io(png, fp); + + png_read_info(png, info); + + width = png_get_image_width(png, info); + height = png_get_image_height(png, info); + png_byte colorType = png_get_color_type(png, info); + png_byte bitDepth = png_get_bit_depth(png, info); + + if (bitDepth == 16) + png_set_strip_16(png); + + if (colorType == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png); + + if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) + png_set_expand_gray_1_2_4_to_8(png); + + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png); + + if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_PALETTE) + png_set_filler(png, 0xFF, PNG_FILLER_AFTER); + + if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + png_read_update_info(png, info); + + png_bytep * rowPointers = (png_bytep *)malloc(sizeof(png_bytep) * height); + for (int y = 0; y < height; y++) + rowPointers[y] = (png_byte *) malloc(png_get_rowbytes(png, info)); + + png_read_image(png, rowPointers); + + image = new uint8[width * height * 4]; + for (int j = 0; j < height; ++j) { + png_bytep row = rowPointers[j]; + for (int i = 0; i < width; ++i) { + uint32 pixel = i * 4 + j * width * 4; + png_bytep px = row + (i * 4); + image[pixel ] = px[0]; + image[pixel + 1] = px[1]; + image[pixel + 2] = px[2]; + image[pixel + 3] = px[3]; + } + } + + png_destroy_read_struct(&png, &info, NULL); + fclose(fp); + break; + } + } + + GenoImage * ret = new GenoImage(); + ret->width = width; + ret->height = height; + ret->image = image; + + return ret; +} + +uint32 GenoImage::getWidth() const { + return width; +} + +uint32 GenoImage::getHeight() const { + return height; +} + +uint8 * GenoImage::getBytes() { + return image; +} + +const uint8 * GenoImage::getBytes() const { + return image; +} + +GenoImage::~GenoImage() { + delete [] image; +} \ No newline at end of file diff --git a/src/geno/data/GenoImage.h b/src/geno/data/GenoImage.h new file mode 100644 index 0000000..74d6ff5 --- /dev/null +++ b/src/geno/data/GenoImage.h @@ -0,0 +1,66 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_IMAGE +#define GNARLY_GENOME_IMAGE + +#include "../GenoInts.h" + +#define GENO_IMAGE_TYPE_CREATE 0x00 +#define GENO_IMAGE_TYPE_PNG 0x01 +#define GENO_IMAGE_TYPE_BMP 0x02 + +struct GenoImageCreateInfo { + uint32 type; + + uint32 width; + uint32 height; + uint8 r; + uint8 g; + uint8 b; + uint8 a; + + const char * path; +}; + +class GenoImage { + private: + uint32 width; + uint32 height; + uint8 * image; + + GenoImage(); + public: + static GenoImage * create(const GenoImageCreateInfo & info); + uint32 getWidth() const; + uint32 getHeight() const; + uint8 * getBytes(); + const uint8 * getBytes() const; + ~GenoImage(); +}; + +#define GNARLY_GENOME_IMAGE_FORWARD +#endif // GNARLY_GENOME_IMAGE \ No newline at end of file diff --git a/src/geno/data/GenoWavFile.cpp b/src/geno/data/GenoWavFile.cpp new file mode 100644 index 0000000..545c809 --- /dev/null +++ b/src/geno/data/GenoWavFile.cpp @@ -0,0 +1,87 @@ +#include +#include + +#include "../audio/GenoAL.h" + +#include "GenoWavFile.h" + +#pragma pack(2) + +struct GenoWavFileHeader { + uint32 signature; + uint32 size; + uint32 format; +}; + +struct GenoWavFormatChunk { + uint32 id; + uint32 size; + uint16 format; + uint16 numChannels; + uint32 sampleRate; + uint32 byteRate; + uint16 blockAlign; + uint16 bitsPerSample; +}; + +struct GenoWavSubChunk { + uint32 id; + uint32 size; +}; + +GenoWavFile::GenoWavFile(const char * path) { + std::ifstream file(path, std::ios::binary); + if (file) { + GenoWavFileHeader fileHeader; + file.read(reinterpret_cast(&fileHeader), sizeof(fileHeader)); + + if (fileHeader.signature == 0x46464952 && !file.eof()) { + GenoWavFormatChunk formatChunk; + file.read(reinterpret_cast(&formatChunk), sizeof(formatChunk)); + + if (formatChunk.id == 0x20746d66 && !file.eof()) { + GenoWavSubChunk subChunk = GenoWavSubChunk(); + subChunk.size = 0; + do { + file.ignore(subChunk.size); + file.read(reinterpret_cast(&subChunk), sizeof(subChunk)); + } while (subChunk.id != 0x61746164 && !file.eof()); + if (!file.eof()) { + data = new uint8[subChunk.size]; + file.read(reinterpret_cast(data), subChunk.size); + if (!file.eof()) { + size = subChunk.size; + if (formatChunk.numChannels == 1) + format = formatChunk.bitsPerSample == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16; + else + format = formatChunk.bitsPerSample == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16; + sampleRate = formatChunk.sampleRate; + } + else + delete [] data; + } + } + } + } + file.close(); +} + +uint32 GenoWavFile::getFormat() { + return format; +} + +uint32 GenoWavFile::getSampleRate() { + return sampleRate; +} + +uint32 GenoWavFile::getSize() { + return size; +} + +uint8 * GenoWavFile::getData() { + return data; +} + +GenoWavFile::~GenoWavFile() { + delete [] data; +} \ No newline at end of file diff --git a/src/geno/data/GenoWavFile.h b/src/geno/data/GenoWavFile.h new file mode 100644 index 0000000..4968d73 --- /dev/null +++ b/src/geno/data/GenoWavFile.h @@ -0,0 +1,21 @@ +#ifndef GNARLY_GENOME_WAVFILE +#define GNARLY_GENOME_WAVFILE + +#include "../GenoInts.h" + +class GenoWavFile { + private: + uint32 format, sampleRate, size; + uint8 * data; + + public: + GenoWavFile(const char * path); + uint32 getFormat(); + uint32 getSampleRate(); + uint32 getSize(); + uint8 * getData(); + ~GenoWavFile(); +}; + +#define GNARLY_GENOME_WAVFILE_FORWARD +#endif // GNARLY_GENOME_WAVFILE \ No newline at end of file diff --git a/src/geno/engine/GenoCamera2D.cpp b/src/geno/engine/GenoCamera2D.cpp new file mode 100644 index 0000000..5c64ada --- /dev/null +++ b/src/geno/engine/GenoCamera2D.cpp @@ -0,0 +1,71 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoCamera2D.h" + +GenoCamera2D::GenoCamera2D(float left, float right, float bottom, float top, float near, float far) : + width(right - left), + height(bottom - top), + projection(GenoMatrix4f::makeOrthographic(left, right, bottom, top, near, far)), + view(GenoMatrix4f::makeIdentity()), + projectionView(projection), + position(), + rotation(0) {} + +void GenoCamera2D::update() { + view.setTranslateXY(-position).rotateZ(-rotation); + projectionView = projection * view; +} + +void GenoCamera2D::setProjection(float left, float right, float bottom, float top, float near, float far) { + projection.setOrthographic(left, right, bottom, top, near, far); +} + +GenoMatrix4f GenoCamera2D::getProjection() { + return projection; +} + +GenoMatrix4f GenoCamera2D::getView() { + return view; +} + +GenoMatrix4f GenoCamera2D::getVPMatrix() { + return projectionView; +} + +float GenoCamera2D::getWidth() { + return width; +} + +float GenoCamera2D::getHeight() { + return height; +} + +GenoVector2f GenoCamera2D::getDimensions() { + return { width, height }; +} + +GenoCamera2D::~GenoCamera2D() {} \ No newline at end of file diff --git a/src/geno/engine/GenoCamera2D.h b/src/geno/engine/GenoCamera2D.h new file mode 100644 index 0000000..efe251b --- /dev/null +++ b/src/geno/engine/GenoCamera2D.h @@ -0,0 +1,58 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_CAMERA2D +#define GNARLY_GENOME_CAMERA2D + +#include "../math/linear/GenoVector2.h" +#include "../math/linear/GenoMatrix4.h" + +class GenoCamera2D { + private: + float width; + float height; + + GenoMatrix4f projection; + GenoMatrix4f view; + GenoMatrix4f projectionView; + public: + GenoVector2f position; + float rotation; + + GenoCamera2D(float left, float right, float bottom, float top, float near, float far); + void update(); + void setProjection(float left, float right, float bottom, float top, float near, float far); + GenoMatrix4f getProjection(); + GenoMatrix4f getView(); + GenoMatrix4f getVPMatrix(); + float getWidth(); + float getHeight(); + GenoVector2f getDimensions(); + ~GenoCamera2D(); +}; + +#define GNARLY_GENOME_CAMERA2D_FORWARD +#endif // GNARLY_GENOME_CAMERA2D \ No newline at end of file diff --git a/src/geno/engine/GenoEngine.cpp b/src/geno/engine/GenoEngine.cpp new file mode 100644 index 0000000..f2281ed --- /dev/null +++ b/src/geno/engine/GenoEngine.cpp @@ -0,0 +1,127 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include "../gl/GenoGL.h" +#include "GenoInput.h" +#include "GenoMonitor.h" +#include "../audio/GenoAudioDevice.h" + +#include "GenoEngine.h" + +namespace { + void errorCallback(int32 code, const char * message); +} + +GenoLoopCallback GenoEngine::callback = 0; +GenoLoop * GenoEngine::loop = 0; +GenoEngine::GenoEventPollFunc GenoEngine::getEvents = 0; + +void GenoEngine::defaultLoop() { + GenoInput::update(); + GenoEngine::pollEvents(); + callback(); +} + +bool GenoEngine::init() { + glfwSetErrorCallback(errorCallback); + + if (!glfwInit()) { + std::cerr << "GL Framework failed to initialize!" << std::endl; + return false; + } + + getEvents = glfwPollEvents; + + GenoMonitors::init(); + GenoAudioDevices::init(); + + return true; +} + +bool GenoEngine::initGlew() { + if (glewInit() != GLEW_NO_ERROR) { + std::cerr << "GL Extension Wrangler failed to initialize!" << std::endl; + return false; + } + + return true; +} + +void GenoEngine::setLoop(GenoLoopCreateInfo info, bool overrideDefault) { + delete loop; + + if (!overrideDefault) { + callback = info.callback; + info.callback = defaultLoop; + } + + loop = new GenoLoop(info); +} + +void GenoEngine::startLoop() { + loop->start(); +} + +void GenoEngine::stopLoop() { + loop->stop(); +} + +void GenoEngine::destroy() { + stopLoop(); + delete loop; + + GenoAudioDevices::cleanup(); + GenoMonitors::cleanup(); + + glfwTerminate(); +} + +void GenoEngine::setSwapInterval(uint8 swapInterval) { + glfwSwapInterval(swapInterval); +} + +void GenoEngine::pollEvents() { + getEvents(); +} + +void GenoEngine::setPollFunc(bool pollFunc) { + getEvents = pollFunc ? glfwPollEvents : glfwWaitEvents; +} + +GenoLoop * GenoEngine::getLoop() { + return loop; +} + +GenoEngine::GenoEngine() {} +GenoEngine::~GenoEngine() {} + +namespace { + void errorCallback(int32 code, const char * message) { + std::cerr << "GLFW error " << code << ": " << message << std::endl; + } +} \ No newline at end of file diff --git a/src/geno/engine/GenoEngine.h b/src/geno/engine/GenoEngine.h new file mode 100644 index 0000000..1fe6cd3 --- /dev/null +++ b/src/geno/engine/GenoEngine.h @@ -0,0 +1,122 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_LOOP_FORWARD +#define GNARLY_GENOME_LOOP_FORWARD + +class GenoLoop; + +#endif // GNARLY_GENOME_LOOP_FORWARD + +#ifndef GNARLY_GENOME_ENGINE +#define GNARLY_GENOME_ENGINE + +#include "../GenoInts.h" + +#include "GenoLoop.h" + +#define GENO_ENGINE_EVENTS_WAIT false +#define GENO_ENGINE_EVENTS_POLL true + +/** + * The engine +**/ +class GenoEngine final { + private: + typedef void (*GenoEventPollFunc)(); + + static GenoLoopCallback callback; + static GenoLoop * loop; + static GenoEventPollFunc getEvents; + + static void defaultLoop(); + + GenoEngine(); + ~GenoEngine(); + public: + + ////// PROGRAM FLOW CONTROL METHODS ////// + + /** + * Initializes the engine + **/ + static bool init(); + + /** + * Initializes glew + **/ + static bool initGlew(); + + /** + * Sets the parameters for the loop. Can either override the default loop or run in conjunction with it + * + * @param info - The loop info struct + * @param overrideDefault - Whether or not to override the default loop + **/ + static void setLoop(GenoLoopCreateInfo info, bool overrideDefault = false); + + /** + * Starts the loop + **/ + static void startLoop(); + + /** + * Stops the loop + **/ + static void stopLoop(); + + /** + * Destroys the engine + **/ + static void destroy(); + + ////// UTILITY METHODS ////// + + /** + * Enables or disabled vsync. Sets the ratio between monitor refresh rate and buffer swap rate. + **/ + static void setSwapInterval(uint8 interval); + + /** + * Polls events (e.g. keyboard, mouse, window changes) + * + * Calls the currently set getEvent func, either glfwPollEvents() or glfwWaitEvents() + **/ + static void pollEvents(); + + /** + * Sets the event polling function + **/ + static void setPollFunc(bool pollFunc); + + /** + * Returns the game loop + **/ + static GenoLoop * getLoop(); +}; + +#define GNARLY_GENOME_ENGINE_FORWARD +#endif // GNARLY_GENOME_ENGINE \ No newline at end of file diff --git a/src/geno/engine/GenoInput.cpp b/src/geno/engine/GenoInput.cpp new file mode 100644 index 0000000..101f717 --- /dev/null +++ b/src/geno/engine/GenoInput.cpp @@ -0,0 +1,142 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoEngine.h" +#include "../gl/GenoFramebuffer.h" + +#include "GenoInput.h" + +double GenoInput::repeatDelay = GENO_INPUT_DEFAULT_DELAY; +double GenoInput::repeatSpeed = GENO_INPUT_DEFAULT_SPEED; + +uint8 GenoInput::keyStates[GLFW_KEY_LAST]; +double GenoInput::keyTimes[GLFW_KEY_LAST]; +double GenoInput::keyTargets[GLFW_KEY_LAST]; + +uint8 GenoInput::mouseButtonStates[GLFW_MOUSE_BUTTON_LAST]; +double GenoInput::mouseButtonTimes[GLFW_MOUSE_BUTTON_LAST]; +double GenoInput::mouseButtonTargets[GLFW_MOUSE_BUTTON_LAST]; + +GenoVector2d GenoInput::mouseCoords = {}; + +void GenoInput::update() { + double delta = GenoEngine::getLoop()->getDelta(); + for (uint32 i = 0; i < GLFW_KEY_LAST; ++i) { + if (keyStates[i] > GENO_INPUT_UNPRESSED) + keyTimes[i] += delta; + if (keyStates[i] == GENO_INPUT_RELEASED || keyStates[i] == GENO_INPUT_PRESSED) + ++keyStates[i]; + if (keyStates[i] == GENO_INPUT_REPEATED) + keyStates[i] = GENO_INPUT_HELD; + if (keyStates[i] == GENO_INPUT_HELD && keyTimes[i] >= keyTargets[i]) { + keyStates[i] = GENO_INPUT_REPEATED; + keyTargets[i] += repeatSpeed; + } + } + for (uint32 i = 0; i < GLFW_MOUSE_BUTTON_LAST; ++i) { + if (mouseButtonStates[i] > GENO_INPUT_UNPRESSED) + mouseButtonTimes[i] += delta; + if (mouseButtonStates[i] == GENO_INPUT_RELEASED || mouseButtonStates[i] == GENO_INPUT_PRESSED) + ++mouseButtonStates[i]; + if (mouseButtonStates[i] == GENO_INPUT_REPEATED) + mouseButtonStates[i] = GENO_INPUT_HELD; + if (mouseButtonStates[i] == GENO_INPUT_HELD && mouseButtonTimes[i] >= mouseButtonTargets[i]) { + mouseButtonStates[i] = GENO_INPUT_REPEATED; + mouseButtonTargets[i] += repeatSpeed; + } + } +} + +void GenoInput::setRepeatSpeed(double speed) { + GenoInput::repeatSpeed = speed; +} + +void GenoInput::setRepeatDelay(double delay) { + GenoInput::repeatDelay = delay; +} + +void GenoInput::setRepeat(double delay, double speed) { + GenoInput::repeatDelay = delay; + GenoInput::repeatSpeed = speed; +} + +uint8 GenoInput::getKeyState(uint16 key) { + return keyStates[key]; +} + +double GenoInput::getKeyDuration(uint16 key) { + return keyTimes[key]; +} + +uint8 GenoInput::getMouseButtonState(uint8 key) { + return mouseButtonStates[key]; +} + +double GenoInput::getMouseButtonDuration(uint8 key) { + return mouseButtonTimes[key]; +} + +GenoVector2d GenoInput::getRawMouseCoords() { + return mouseCoords; +} + +GenoVector2f GenoInput::getMouseCoords(GenoCamera2D * camera) { + return (GenoVector2f) mouseCoords / GenoVector2f(GenoFramebuffer::getCurrentWidth(), GenoFramebuffer::getCurrentHeight()) * camera->getDimensions() + camera->position; +} + +GenoInput::GenoInput() {} +GenoInput::~GenoInput() {} + +////// CALLBACKS ////// + +void GenoInput::keyCallback(GLFWwindow * window, int32 key, int32 scancode, int32 action, int32 mods) { + if (key != GLFW_KEY_UNKNOWN) { + if (action == GLFW_PRESS) + keyStates[key] = GENO_INPUT_PRESSED; + else if (action == GLFW_RELEASE) { + keyStates[key] = GENO_INPUT_RELEASED; + keyTimes[key] = 0; + keyTargets[key] = repeatDelay; + } + } +} + +void GenoInput::mouseButtonCallback(GLFWwindow * window, int32 button, int32 action, int32 mods) { + if (button != GLFW_KEY_UNKNOWN) { + if (action == GLFW_PRESS) + mouseButtonStates[button] = GENO_INPUT_PRESSED; + else if (action == GLFW_RELEASE) { + mouseButtonStates[button] = GENO_INPUT_RELEASED; + mouseButtonTimes[button] = 0; + mouseButtonTargets[button] = repeatDelay; + } + } +} + +void GenoInput::cursorPositionCallback(GLFWwindow * window, double x, double y) { + mouseCoords.v[0] = x; + mouseCoords.v[1] = y; +} \ No newline at end of file diff --git a/src/geno/engine/GenoInput.h b/src/geno/engine/GenoInput.h new file mode 100644 index 0000000..da1a071 --- /dev/null +++ b/src/geno/engine/GenoInput.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_INPUT +#define GNARLY_GENOME_INPUT + +#include "../GenoInts.h" + +#include "../gl/GenoGL.h" +#include "../math/linear/GenoVector2.h" +#include "../engine/GenoCamera2D.h" + +#define GENO_INPUT_RELEASED 0x00 +#define GENO_INPUT_UNPRESSED 0x01 +#define GENO_INPUT_PRESSED 0x02 +#define GENO_INPUT_HELD 0x03 +#define GENO_INPUT_REPEATED 0x04 + +#define GENO_INPUT_DEFAULT_DELAY 0.3 +#define GENO_INPUT_DEFAULT_SPEED 0.05 + +class GenoInput final { + private: + GenoInput(); + ~GenoInput(); + + static double repeatDelay; + static double repeatSpeed; + + static uint8 keyStates[GLFW_KEY_LAST]; + static double keyTimes[GLFW_KEY_LAST]; + static double keyTargets[GLFW_KEY_LAST]; + + static uint8 mouseButtonStates[GLFW_MOUSE_BUTTON_LAST]; + static double mouseButtonTimes[GLFW_MOUSE_BUTTON_LAST]; + static double mouseButtonTargets[GLFW_MOUSE_BUTTON_LAST]; + + static GenoVector2d mouseCoords; + + ////// CALLBACKS ////// + + static void cursorPositionCallback(GLFWwindow * window, double x, double y); + static void keyCallback(GLFWwindow * window, int32 key, int32 scancode, int32 action, int32 mods); + static void mouseButtonCallback(GLFWwindow * window, int32 button, int32 action, int32 mods); + public: + static void update(); + + static void setRepeatDelay(double delay); + static void setRepeatSpeed(double speed); + static void setRepeat(double delay, double speed); + + static uint8 getKeyState(uint16 key); + static double getKeyDuration(uint16 key); + + static uint8 getMouseButtonState(uint8 mouseButton); + static double getMouseButtonDuration(uint8 mouseButton); + + static GenoVector2d getRawMouseCoords(); + static GenoVector2f getMouseCoords(GenoCamera2D * camera); + + friend class GenoWindow; +}; + +#define GNARLY_GENOME_INPUT_FORWARD +#endif // GNARLY_GENOME_INPUT \ No newline at end of file diff --git a/src/geno/engine/GenoLoop.cpp b/src/geno/engine/GenoLoop.cpp new file mode 100644 index 0000000..a37f32d --- /dev/null +++ b/src/geno/engine/GenoLoop.cpp @@ -0,0 +1,133 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../thread/GenoTime.h" + +#include "GenoLoop.h" + +GenoLoop::GenoLoop(const GenoLoopCreateInfo & info) : + sanicLoop(false), + callbackCount(1 + info.numSubLoops), + looping(false), + deltas(new double[callbackCount]), + deltaScales(new double[callbackCount]), + fps(new uint32[callbackCount]), + millisPerFrames(new double[callbackCount]), + callbacks(new GenoLoopCallback[callbackCount]) { + + fps[0] = 0; + deltas[0] = 0; + deltaScales[0] = info.deltaScale; + if (info.targetFps != 0) + millisPerFrames[0] = 1000 / info.targetFps; + else { + sanicLoop = true; + millisPerFrames[0] = 0; + } + callbacks[0] = info.callback; + + for (uint32 i = 1; i < callbackCount; ++i) { + fps[i] = 0; + deltas[i] = 0; + deltaScales[i] = info.subLoops[i - 1].deltaScale; + if (info.subLoops[i - 1].targetFps != 0) + millisPerFrames[i] = 1000 / info.subLoops[i - 1].targetFps; + else + millisPerFrames[i] = 0; + callbacks[i] = info.subLoops[i - 1].callback; + } +} + +void GenoLoop::start() { + uint32 * frames = new uint32[callbackCount]; + double * pastTimes = new double[callbackCount + 1]; + double * truePastTimes = new double[callbackCount + 1]; + double curTime = 0; + + for (uint32 i = 0; i < callbackCount; ++i) { + frames[i] = 0; + pastTimes[i] = GenoTime::getTime(milliseconds); + } + pastTimes[callbackCount] = GenoTime::getTime(milliseconds); + + looping = true; + while (looping) { + curTime = GenoTime::getTime(milliseconds); + if (curTime - pastTimes[0] > 1000) { + for (uint32 i = 0; i < callbackCount; ++i) { + fps[i] = frames[i]; + frames[i] = 0; + } + pastTimes[0] += 1000; + } + for (uint32 i = 0; i < callbackCount; ++i) { + if (curTime - pastTimes[i + 1] >= millisPerFrames[i]) { + callbacks[i](); + deltas[i] = (curTime - truePastTimes[i + 1]) * deltaScales[i]; + pastTimes[i + 1] += millisPerFrames[i]; + truePastTimes[i + 1] = curTime; + ++frames[i]; + } + } + if (!sanicLoop) + GenoTime::sleepUntil(pastTimes[1] + millisPerFrames[0]); + } + + delete [] truePastTimes; + delete [] pastTimes; + delete [] frames; +} + +void GenoLoop::stop() { + looping = false; +} + +double GenoLoop::getDelta(uint32 loopIndex) { + return deltas[loopIndex]; +} + +uint32 GenoLoop::getFPS(uint32 loopIndex) { + return fps[loopIndex]; +} + +void GenoLoop::setFPS(double fps, uint32 loopIndex) { + millisPerFrames[loopIndex] = 1000 / fps; +} + +void GenoLoop::setDeltaScale(double deltaScale, uint32 loopIndex) { + deltaScales[loopIndex] = deltaScale; +} + +void GenoLoop::setCallback(GenoLoopCallback callback, uint32 loopIndex) { + callbacks[loopIndex] = callback; +} + +GenoLoop::~GenoLoop() { + delete [] deltas; + delete [] deltaScales; + delete [] millisPerFrames; + delete [] callbacks; +} \ No newline at end of file diff --git a/src/geno/engine/GenoLoop.h b/src/geno/engine/GenoLoop.h new file mode 100644 index 0000000..18ce05e --- /dev/null +++ b/src/geno/engine/GenoLoop.h @@ -0,0 +1,82 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_LOOP +#define GNARLY_GENOME_LOOP + +// bröther may I have some lööps +// +// ^..---..^ +// / @ v @ \ +// / ^ \ +// . . +// || | | || +// '|_| |_|' +// \ / +// \_|_____|_/ + +#include "../GenoInts.h" + +typedef void (*GenoLoopCallback)(); + +struct GenoSubLoopCreateInfo { + double targetFps; + double deltaScale; + GenoLoopCallback callback; +}; + +struct GenoLoopCreateInfo { + double targetFps; + double deltaScale; + GenoLoopCallback callback; + uint32 numSubLoops; + GenoSubLoopCreateInfo * subLoops; +}; + +class GenoLoop { + private: + bool sanicLoop; + uint32 callbackCount; + bool looping; + uint32 * fps; + double * deltas; + double * deltaScales; + double * millisPerFrames; + GenoLoopCallback * callbacks; + public: + GenoLoop(const GenoLoopCreateInfo & info); + void start(); + void stop(); + double getDelta(uint32 loopIndex = 0); + uint32 getFPS(uint32 loopIndex = 0); + void setFPS(double fps, uint32 loopIndex = 0); + void setDeltaScale(double scale, uint32 loopIndex = 0); + void setCallback(GenoLoopCallback callback, uint32 loopIndex = 0); + ~GenoLoop(); +}; + +#define GNARLY_GENOME_LOOP_FORWARD +#endif // GNARLY_GENOME_LOOP \ No newline at end of file diff --git a/src/geno/engine/GenoMonitor.cpp b/src/geno/engine/GenoMonitor.cpp new file mode 100644 index 0000000..c420dbf --- /dev/null +++ b/src/geno/engine/GenoMonitor.cpp @@ -0,0 +1,227 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoMonitor.h" + +GenoVideoMode::GenoVideoMode(const GLFWvidmode & videoMode) : + width(videoMode.width), + height(videoMode.height), + redBits(videoMode.redBits), + greenBits(videoMode.greenBits), + blueBits(videoMode.blueBits), + refreshRate(videoMode.refreshRate) {} + +int32 GenoVideoMode::getWidth() const { + return width; +} + +int32 GenoVideoMode::getHeight() const { + return height; +} + +GenoVector2i GenoVideoMode::getDimensions() const { + return { width, height }; +} + +int32 GenoVideoMode::getRedBits() const { + return redBits; +} + +int32 GenoVideoMode::getGreenBits() const { + return greenBits; +} + +int32 GenoVideoMode::getBlueBits() const { + return blueBits; +} + +GenoVector3i GenoVideoMode::getBitDepth() const { + return { redBits, greenBits, blueBits }; +} + +int32 GenoVideoMode::getRefreshRate() const { + return refreshRate; +} + +GenoVideoMode::~GenoVideoMode() {} + +GenoMonitor::GenoMonitor(GLFWmonitor * monitor) : + monitor(monitor) { + int32 count; + const GLFWvidmode * vidmodes = glfwGetVideoModes(monitor, &count); + numVideoModes = count; + videoModes = new GenoVideoMode*[numVideoModes]; + for (uint32 i = 0; i < count; ++i) + videoModes[i] = new GenoVideoMode(vidmodes[i]); + + GenoVideoMode * videoMode = videoModes[numVideoModes - 1]; + width = videoMode->getWidth(); + height = videoMode->getHeight(); + glfwGetMonitorPos(monitor, &x, &y); + int32 physicalWidth; + int32 physicalHeight; + glfwGetMonitorPhysicalSize(monitor, &physicalWidth, &physicalHeight); + sizeX = physicalWidth; + sizeY = physicalHeight; + name = glfwGetMonitorName(monitor); +} + +int32 GenoMonitor::getX() const { + return x; +} + +int32 GenoMonitor::getY() const { + return y; +} + +GenoVector2i GenoMonitor::getPosition() const { + return { x, y }; +} + +int32 GenoMonitor::getWidth() const { + return width; +} + +int32 GenoMonitor::getHeight() const { + return height; +} + +GenoVector2i GenoMonitor::getDimensions() const { + return { width, height }; +} + +double GenoMonitor::getPhysicalWidth(double scale) const { + return sizeX / scale; +} + +double GenoMonitor::getPhysicalHeight(double scale) const { + return sizeY / scale; +} + +GenoVector2d GenoMonitor::getPhysicalDimensions(double scale) const { + return { sizeX / scale, sizeY / scale }; +} + +double GenoMonitor::getPhysicalDiagonal(double scale) const { + return sqrt(sizeX * sizeX + sizeY * sizeY) / scale; +} +const char * GenoMonitor::getName() const { + return name; +} + +uint32 GenoMonitor::getNumVideoModes() const { + return numVideoModes; +} + +GenoVideoMode * GenoMonitor::getDefaultVideoMode() const { + return videoModes[numVideoModes - 1]; +} + +GenoVideoMode * GenoMonitor::getVideoMode(uint32 num) const { + return videoModes[num]; +} + +GenoMonitor::~GenoMonitor() { + for (uint32 i = 0; i < numVideoModes; ++i) + delete videoModes[i]; + delete [] videoModes; +} + +uint32 GenoMonitors::numMonitors = 0; +GenoMonitor ** GenoMonitors::monitors = 0; + +uint32 GenoMonitors::getNumMonitors() { + return numMonitors; +} + +void GenoMonitors::init() { + int32 count; + GLFWmonitor ** glfwMonitors = glfwGetMonitors(&count); + numMonitors = count; + + monitors = new GenoMonitor*[numMonitors]; + + for (uint32 i = 0; i < numMonitors; ++i) + monitors[i] = new GenoMonitor(glfwMonitors[i]); + + glfwSetMonitorCallback(monitorCallback); +} + +GenoMonitor * GenoMonitors::getPrimaryMonitor() { + return monitors[0]; +} + +GenoMonitor * GenoMonitors::getMonitor(uint32 num) { + return monitors[num]; +} + +void GenoMonitors::cleanup() { + for (uint32 i = 0; i < numMonitors; ++i) + delete monitors[i]; + delete [] monitors; +} + +void GenoMonitors::monitorCallback(GLFWmonitor * monitor, int32 event) { + if (event == GLFW_DISCONNECTED) { + bool found = false; + for (uint32 i = 0; i < numMonitors - 1; ++i) { + if (found) + monitors[i] = monitors[i + 1]; + else if (monitors[i]->monitor == monitor) { + delete monitors[i]; + monitors[i] = monitors[i + 1]; + } + } + if (!found) + delete monitors[numMonitors - 1]; + } + else { + GenoMonitor * gMonitor = new GenoMonitor(monitor); + + GenoMonitor ** target = new GenoMonitor*[++numMonitors]; + + int32 count; + GLFWmonitor ** monitors = glfwGetMonitors(&count); + + for (uint32 i = 0; i < count; ++i) { + bool found = false; + for (uint32 j = 0; j < numMonitors - 1; ++j) { + if (GenoMonitors::monitors[j]->monitor == monitors[i]) { + found = true; + target[i] = GenoMonitors::monitors[j]; + } + } + if (!found) + target[i] = gMonitor; + } + + delete [] GenoMonitors::monitors; + GenoMonitors::monitors = target; + } +} + +GenoMonitors::GenoMonitors() {} +GenoMonitors::~GenoMonitors() {} \ No newline at end of file diff --git a/src/geno/engine/GenoMonitor.h b/src/geno/engine/GenoMonitor.h new file mode 100644 index 0000000..48becad --- /dev/null +++ b/src/geno/engine/GenoMonitor.h @@ -0,0 +1,131 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_MONITOR +#define GNARLY_GENOME_MONITOR + +#include "../GenoInts.h" + +#include "../math/linear/GenoVector2.h" +#include "../math/linear/GenoVector3.h" +#include "../gl/GenoGL.h" + +#define GENO_MONITOR_SCALE_MILLIMETERS 1.0 +#define GENO_MONITOR_SCALE_CENTIMETERS 10.0 +#define GENO_MONITOR_SCALE_INCHES 25.4 +#define GENO_MONITOR_SCALE_FEET 304.8 + +class GenoVideoMode final { + private: + int32 width; + int32 height; + int32 redBits; + int32 greenBits; + int32 blueBits; + int32 refreshRate; + + GenoVideoMode(const GLFWvidmode & videoMode); + ~GenoVideoMode(); + public: + int32 getWidth() const; + int32 getHeight() const; + GenoVector2i getDimensions() const; + + int32 getRedBits() const; + int32 getGreenBits() const; + int32 getBlueBits() const; + GenoVector3i getBitDepth() const; + + int32 getRefreshRate() const; + + friend class GenoMonitor; +}; + +class GenoMonitor final { + private: + GLFWmonitor * monitor; + + uint32 numVideoModes; + GenoVideoMode ** videoModes; + + int32 x; + int32 y; + int32 width; + int32 height; + double sizeX; + double sizeY; + const char * name; + + GenoMonitor(GLFWmonitor * monitor); + ~GenoMonitor(); + public: + int32 getX() const; + int32 getY() const; + GenoVector2i getPosition() const; + + int32 getWidth() const; + int32 getHeight() const; + GenoVector2i getDimensions() const; + + double getPhysicalWidth(double scale = GENO_MONITOR_SCALE_INCHES) const; + double getPhysicalHeight(double scale = GENO_MONITOR_SCALE_INCHES) const; + GenoVector2d getPhysicalDimensions(double scale = GENO_MONITOR_SCALE_INCHES) const; + double getPhysicalDiagonal(double scale = GENO_MONITOR_SCALE_INCHES) const; + + const char * getName() const; + + uint32 getNumVideoModes() const; + GenoVideoMode * getDefaultVideoMode() const; + GenoVideoMode * getVideoMode(uint32 num) const; + + friend class GenoMonitors; + friend class GenoWindow; +}; + +class GenoMonitors final { + private: + static uint32 numMonitors; + static GenoMonitor ** monitors; + + GenoMonitors(); + ~GenoMonitors(); + + static void init(); + static void cleanup(); + + ////// Callbacks ////// + + static void monitorCallback(GLFWmonitor * monitor, int32 event); + public: + static uint32 getNumMonitors(); + static GenoMonitor * getPrimaryMonitor(); + static GenoMonitor * getMonitor(uint32 num); + + friend class GenoEngine; +}; + +#define GNARLY_GENOME_MONITOR_FORWARD +#endif // GNARLY_GENOME_MONITOR \ No newline at end of file diff --git a/src/geno/engine/GenoWindow.cpp b/src/geno/engine/GenoWindow.cpp new file mode 100644 index 0000000..44a0539 --- /dev/null +++ b/src/geno/engine/GenoWindow.cpp @@ -0,0 +1,300 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoInput.h" + +#include "GenoWindow.h" + +GenoWindow::GenoWindow() {} + +GenoWindow * GenoWindow::create(const GenoWindowCreateInfo & info) { + GenoWindow * ret = new GenoWindow(); + + bool visible = true; + for (uint32 i = 0; i < info.numHints; ++i) { + uint32 index = i * 2; + if (info.hints[index] == GLFW_VISIBLE) + visible = info.hints[index + 1]; + else + glfwWindowHint(info.hints[index], info.hints[index + 1]); + } + glfwWindowHint(GLFW_VISIBLE, false); + + GenoMonitor * monitor = info.monitor; + GenoVideoMode * vidMode = info.videoMode; + + if (monitor == 0) + monitor = GenoMonitors::getPrimaryMonitor(); + + int32 width = info.width; + int32 height = info.height; + if (width == 0) + width = monitor->getWidth() * 0.5; + if (height == 0) + height = monitor->getHeight() * 0.5; + if (info.fullscreen) { + if (vidMode == 0) + vidMode = monitor->getDefaultVideoMode(); + + glfwWindowHint(GLFW_RED_BITS, vidMode->getRedBits()); + glfwWindowHint(GLFW_GREEN_BITS, vidMode->getGreenBits()); + glfwWindowHint(GLFW_BLUE_BITS, vidMode->getBlueBits()); + glfwWindowHint(GLFW_REFRESH_RATE, vidMode->getRefreshRate()); + } + + GLFWwindow * window; + window = glfwCreateWindow(width, height, info.title, 0, 0); + + if (window == 0) { + delete ret; + return 0; + } + + int32 x = 0; + int32 y = 0; + if (info.defaultPosition) { + glfwGetWindowPos(window, &x, &y); + double rx = (double) x / (double) GenoMonitors::getPrimaryMonitor()->getWidth(); + double ry = (double) y / (double) GenoMonitors::getPrimaryMonitor()->getHeight(); + x = rx * monitor->getWidth(); + y = ry * monitor->getHeight(); + glfwSetWindowPos(window, x, y); + } + else + glfwSetWindowPos(window, info.x + monitor->getX(), info.y + monitor->getY()); + + ret->cachedX = (double) x / (double) monitor->getWidth(); + ret->cachedY = (double) y / (double) monitor->getHeight(); + ret->cachedWidth = width; + ret->cachedHeight = height; + + glfwGetWindowSize(window, &width, &height); + + glfwSetWindowPosCallback(window, positionCallback); + glfwSetWindowSizeCallback(window, sizeCallback); + glfwSetFramebufferSizeCallback(window, framebufferSizeCallback); + glfwSetWindowFocusCallback(window, windowFocusCallback); + + glfwSetCursorPosCallback(window, GenoInput::cursorPositionCallback); + glfwSetKeyCallback(window, GenoInput::keyCallback); + glfwSetMouseButtonCallback(window, GenoInput::mouseButtonCallback); + + ret->curMonitor = monitor; + + ret->x = x; + ret->y = y; + ret->width = width; + ret->height = height; + ret->window = window; + + uint32 clearBits = GL_COLOR_BUFFER_BIT; + + if (info.depth) { + glEnable(GL_DEPTH_TEST); + clearBits |= GL_DEPTH_BUFFER_BIT; + } + + int32 frameWidth; + int32 frameHeight; + glfwGetFramebufferSize(window, &frameWidth, &frameHeight); + + GenoFramebuffer * framebuffer = new GenoFramebuffer(); + framebuffer->id = 0; + framebuffer->width = frameWidth; + framebuffer->width = frameHeight; + framebuffer->clearRed = info.clearRed; + framebuffer->clearGreen = info.clearGreen; + framebuffer->clearBlue = info.clearBlue; + framebuffer->clearBits = clearBits; + + ret->framebuffer = framebuffer; + + if (GenoFramebuffer::activeFramebuffer == 0) + GenoFramebuffer::activeFramebuffer = framebuffer; + + glfwSetWindowUserPointer(window, ret); + + if (vidMode != 0) + ret->setFullscreen(monitor, vidMode); + + glfwShowWindow(window); + + return ret; +} + +void GenoWindow::activate() const { + glfwMakeContextCurrent(window); + glfwFocusWindow(window); +} + +void GenoWindow::bindFramebuffer() const { + framebuffer->bind(); +} + +void GenoWindow::swap() const { + glfwSwapBuffers(window); +} + +int32 GenoWindow::getX() const { + return x; +} + +int32 GenoWindow::getY() const { + return y; +} + +GenoVector2i GenoWindow::getPosition() const { + return { x, y }; +} + +int32 GenoWindow::getWidth() const { + return width; +} + +int32 GenoWindow::getHeight() const { + return height; +} + +GenoVector2i GenoWindow::getDimensions() const { + return { width, height }; +} + +bool GenoWindow::shouldClose() const { + return glfwWindowShouldClose(window); +} + +void GenoWindow::setShouldClose(bool shouldClose) { + glfwSetWindowShouldClose(window, shouldClose); +} + +void GenoWindow::disableFullscreen(GenoMonitor * monitor) { + glfwSetWindowMonitor(window, 0, monitor->getX() + cachedX * monitor->getWidth(), monitor->getY() + cachedY * monitor->getHeight(), cachedWidth, cachedHeight, 0); + fullscreen = false; +} + +void GenoWindow::disableFullscreen(GenoMonitor * monitor, int32 x, int32 y, int32 width, int32 height) { + glfwSetWindowMonitor(window, 0, x + monitor->getX(), y + monitor->getY(), width, height, 0); + fullscreen = false; +} + +void GenoWindow::setFullscreen(GenoMonitor * monitor, GenoVideoMode * videoMode) { + if (!fullscreen) { + cachedX = (double) x / (double) curMonitor->getWidth(); + cachedY = (double) y / (double) curMonitor->getHeight(); + cachedWidth = width; + cachedHeight = height; + } + glfwSetWindowMonitor(window, monitor->monitor, monitor->getX() + 1, monitor->getY() + 1, videoMode->getWidth(), videoMode->getHeight(), videoMode->getRefreshRate()); + fullscreen = true; +} + +void GenoWindow::setX(int32 x) { + glfwSetWindowPos(window, x, y); +} + +void GenoWindow::setY(int32 y) { + glfwSetWindowPos(window, x, y); +} + +void GenoWindow::setPosition(int32 x, int32 y) { + glfwSetWindowPos(window, x, y); +} + +void GenoWindow::setPosition(const GenoVector2i & position) { + glfwSetWindowPos(window, position.v[0], position.v[1]); +} + +void GenoWindow::setWidth(uint32 width) { + glfwSetWindowSize(window, width, height); +} + +void GenoWindow::setHeight(int32 height) { + glfwSetWindowSize(window, width, height); +} + +void GenoWindow::setDimensions(int32 width, int32 height) { + glfwSetWindowSize(window, width, height); +} + +void GenoWindow::setDimensions(const GenoVector2i & position) { + glfwSetWindowSize(window, position.v[0], position.v[1]); +} + +void GenoWindow::maximize() { + glfwMaximizeWindow(window); +} + +void GenoWindow::minimize() { + glfwIconifyWindow(window); +} + +GenoWindow::~GenoWindow() { + glfwDestroyWindow(window); +} + +void GenoWindow::positionCallback(GLFWwindow * window, int32 x, int32 y) { + GenoWindow * win = reinterpret_cast(glfwGetWindowUserPointer(window)); + win->x = x; + win->y = y; + + int32 cx = win->x + win->width / 2; + int32 cy = win->y + win->height / 2; + for (uint32 i = 0; i < GenoMonitors::getNumMonitors(); ++i) { + GenoMonitor * cur = GenoMonitors::getMonitor(i); + if (cx >= cur->getX() && cy >= cur->getY() && cx < cur->getX() + cur->getWidth() && cy < cur->getY() + cur->getHeight()) + win->curMonitor = cur; + } +} + +void GenoWindow::sizeCallback(GLFWwindow * window, int32 width, int32 height) { + GenoWindow * win = reinterpret_cast(glfwGetWindowUserPointer(window)); + win->width = width; + win->height = height; + + int32 cx = win->x + win->width / 2; + int32 cy = win->y + win->height / 2; + for (uint32 i = 0; i < GenoMonitors::getNumMonitors(); ++i) { + GenoMonitor * cur = GenoMonitors::getMonitor(i); + if (cx >= cur->getX() && cy >= cur->getY() && cx < cur->getX() + cur->getWidth() && cy < cur->getY() + cur->getHeight()) + win->curMonitor = cur; + } +} + +void GenoWindow::framebufferSizeCallback(GLFWwindow * window, int32 width, int32 height) { + GenoWindow * win = reinterpret_cast(glfwGetWindowUserPointer(window)); + GenoFramebuffer * framebuffer = win->framebuffer; + framebuffer->width = width; + framebuffer->height = height; + if (GenoFramebuffer::activeFramebuffer == framebuffer) + glViewport(0, 0, width, height); +} + +void GenoWindow::windowFocusCallback(GLFWwindow * window, int32 action) { + if (action == GLFW_TRUE) { + GenoWindow * win = reinterpret_cast(glfwGetWindowUserPointer(window)); + GenoFramebuffer::activeWindow = win; + } +} \ No newline at end of file diff --git a/src/geno/engine/GenoWindow.h b/src/geno/engine/GenoWindow.h new file mode 100644 index 0000000..d825526 --- /dev/null +++ b/src/geno/engine/GenoWindow.h @@ -0,0 +1,127 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_MONITOR_FORWARD +#define GNARLY_GENOME_MONITOR_FORWARD + +struct GenoVideoMode; +class GenoMonitor; +class GenoMonitors; + +#endif // GNARLY_GENOME_MONITOR_FORWARD + +#ifndef GNARLY_GENOME_FRAMEBUFFER_FORWARD +#define GNARLY_GENOME_FRAMEBUFFER_FORWARD + +class GenoFramebuffer; + +#endif // GNARLY_GENOME_FRAMEBUFFER_FORWARD + +#ifndef GNARLY_GENOME_WINDOW +#define GNARLY_GENOME_WINDOW + +#include "../GenoInts.h" + +#include "GenoMonitor.h" +#include "../gl/GenoGL.h" +#include "../gl/GenoFramebuffer.h" + +struct GenoWindowCreateInfo { + bool defaultPosition; + int32 x; + int32 y; + uint32 width; + uint32 height; + bool fullscreen; + GenoMonitor * monitor; + GenoVideoMode * videoMode; + const char * title; + uint32 numHints; + int32 * hints; + float clearRed; + float clearGreen; + float clearBlue; + bool depth; +}; + +class GenoWindow { + private: + bool fullscreen; + + double cachedX; + double cachedY; + int32 cachedWidth; + int32 cachedHeight; + + GenoMonitor * curMonitor; + + int32 x; + int32 y; + int32 width; + int32 height; + GLFWwindow * window; + + GenoFramebuffer * framebuffer; + + GenoWindow(); + + ////// Callbacks ////// + + static void positionCallback(GLFWwindow * window, int32 x, int32 y); + static void sizeCallback(GLFWwindow * window, int32 width, int32 height); + static void framebufferSizeCallback(GLFWwindow * window, int32 width, int32 height); + static void windowFocusCallback(GLFWwindow * window, int32 action); + public: + static GenoWindow * create(const GenoWindowCreateInfo & info); + void activate() const; + void bindFramebuffer() const; + void swap() const; + int32 getX() const; + int32 getY() const; + GenoVector2i getPosition() const; + int32 getWidth() const; + int32 getHeight() const; + GenoVector2i getDimensions() const; + bool shouldClose() const; + void setShouldClose(bool shouldClose); + void disableFullscreen(GenoMonitor * monitor); + void disableFullscreen(GenoMonitor * monitor, int32 x, int32 y, int32 width, int32 height); + void setFullscreen(GenoMonitor * monitor, GenoVideoMode * videoMode); + void setX(int32 x); + void setY(int32 y); + void setPosition(int32 x, int32 y); + void setPosition(const GenoVector2i & position); + void setWidth(uint32 width); + void setHeight(int32 height); + void setDimensions(int32 width, int32 height); + void setDimensions(const GenoVector2i & position); + void maximize(); + void minimize(); + ~GenoWindow(); +}; + +#define GNARLY_GENOME_WINDOW_FORWARD +#endif // GNARLY_GENOME_WINDOW \ No newline at end of file diff --git a/src/geno/exceptions/GenoException.cpp b/src/geno/exceptions/GenoException.cpp new file mode 100644 index 0000000..b1d0dda --- /dev/null +++ b/src/geno/exceptions/GenoException.cpp @@ -0,0 +1,35 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoException.h" + +GenoException::GenoException(const char8 * message) : + message(message) {} + + +const char8 * GenoException::getMessage() { + return message; +} \ No newline at end of file diff --git a/src/geno/exceptions/GenoException.h b/src/geno/exceptions/GenoException.h new file mode 100644 index 0000000..9e54e92 --- /dev/null +++ b/src/geno/exceptions/GenoException.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_EXCEPTION +#define GNARLY_GENOME_EXCEPTION + +#include "../GenoChars.h" + +class GenoException { + protected: + const char8 * message; + + public: + GenoException(const char8 * message); + const char8 * getMessage(); +}; + +#define GNARLY_GENOME_EXCEPTION_FORWARD +#endif // GNARLY_GENOME_EXCEPTION \ No newline at end of file diff --git a/src/geno/exceptions/GenoMaxCapacityException.cpp b/src/geno/exceptions/GenoMaxCapacityException.cpp new file mode 100644 index 0000000..814810b --- /dev/null +++ b/src/geno/exceptions/GenoMaxCapacityException.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoMaxCapacityException.h" + +GenoMaxCapacityException::GenoMaxCapacityException() : + GenoException("GenoMaxCapacityException: Max capacity reached in GenoArrayList!") {} \ No newline at end of file diff --git a/src/geno/exceptions/GenoMaxCapacityException.h b/src/geno/exceptions/GenoMaxCapacityException.h new file mode 100644 index 0000000..efa6ac6 --- /dev/null +++ b/src/geno/exceptions/GenoMaxCapacityException.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_MAX_CAPACITY_EXCEPTION +#define GNARLY_GENOME_MAX_CAPACITY_EXCEPTION + +#include "GenoException.h" + +class GenoMaxCapacityException : public GenoException { + public: + GenoMaxCapacityException(); +}; + +#define GNARLY_GENOME_MAX_CAPACITY_EXCEPTION_FORWARD +#endif // GNARLY_GENOME_MAX_CAPACITY_EXCEPTION \ No newline at end of file diff --git a/src/geno/gl/GenoFramebuffer.cpp b/src/geno/gl/GenoFramebuffer.cpp new file mode 100644 index 0000000..7d02eb1 --- /dev/null +++ b/src/geno/gl/GenoFramebuffer.cpp @@ -0,0 +1,151 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include "GenoGL.h" +#include "GenoFramebuffer.h" + +const GenoWindow * GenoFramebuffer::activeWindow = 0; +const GenoFramebuffer * GenoFramebuffer::activeFramebuffer = 0; + +void GenoFramebuffer::clear() { + glClear(activeFramebuffer->clearBits); +} + +void GenoFramebuffer::bindDefault() { + activeWindow->bindFramebuffer(); +} + +uint32 GenoFramebuffer::getCurrentWidth() { + return activeFramebuffer->width; +} + +uint32 GenoFramebuffer::getCurrentHeight() { + return activeFramebuffer->height; +} + +GenoFramebuffer::GenoFramebuffer() {} + +GenoFramebuffer::GenoFramebuffer(const GenoFramebufferCreateInfo & info) : + width(info.width), + height(info.height), + numColorAttachments(info.numColorAttachments), + depthType(info.depthAttachmentType) { + + glGenFramebuffers(1, &id); + glBindFramebuffer(GL_FRAMEBUFFER, id); + + if (numColorAttachments != 0) { + clearBits |= GL_COLOR_BUFFER_BIT; + clearRed = info.clearRed; + clearGreen = info.clearGreen; + clearBlue = info.clearBlue; + uint32 * colorAttachmentIds = new uint32[numColorAttachments]; + uint32 * drawBuffers = new uint32[numColorAttachments]; + colorAttachments = new GenoTexture2D*[numColorAttachments]; + glGenTextures(numColorAttachments, colorAttachmentIds); + for (uint32 i = 0; i < numColorAttachments; ++i) { + glBindTexture(GL_TEXTURE_2D, colorAttachmentIds[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + for (uint32 j = 0; j < info.numTextureParams; ++j) { + uint32 index = j * 2; + glTexParameteri(GL_TEXTURE_2D, info.textureParams[index], info.textureParams[index + 1]); + } + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, colorAttachmentIds[i], 0); + colorAttachments[i] = new GenoTexture2D(colorAttachmentIds[i], width, height); + drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i; + } + glDrawBuffers(numColorAttachments, drawBuffers); + + delete [] colorAttachmentIds; + delete [] drawBuffers; + } + if (depthType == GENO_FRAMEBUFFER_DEPTH_BUFFER) { + clearBits |= GL_DEPTH_BUFFER_BIT; + clearDepth = info.clearDepth; + glGenRenderbuffers(1, &depthBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer); + } + else if (depthType == GENO_FRAMEBUFFER_DEPTH_TEXTURE) { + clearBits |= GL_DEPTH_BUFFER_BIT; + clearDepth = info.clearDepth; + uint32 textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + for (uint32 i = 0; i < info.numTextureParams; ++i) { + uint32 index = i * 2; + glTexParameteri(GL_TEXTURE_2D, info.textureParams[index], info.textureParams[index + 1]); + } + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textureId, 0); + depthTexture = new GenoTexture2D(textureId, width, height); + } + + activeFramebuffer->bind(); +} + +uint32 GenoFramebuffer::getWidth() const { + return width; +} + +uint32 GenoFramebuffer::getHeight() const { + return height; +} + +const GenoTexture2D * GenoFramebuffer::getColorTexture(uint32 index) const { + return colorAttachments[index]; +} + +const GenoTexture2D * GenoFramebuffer::getDepthTexture() const { + return depthTexture; +} + +void GenoFramebuffer::bind() const { + for (uint32 i = GL_TEXTURE0; i < GL_TEXTURE31; ++i) { + glActiveTexture(i); + glBindTexture(GL_TEXTURE_2D, 0); + } + activeFramebuffer = this; + glBindFramebuffer(GL_FRAMEBUFFER, id); + glClearColor(clearRed, clearGreen, clearBlue, 1); + glClearDepth(clearDepth); + glViewport(0, 0, width, height); +} + +GenoFramebuffer::~GenoFramebuffer() { + for (uint32 i = 0; i < numColorAttachments; ++i) + delete colorAttachments[i]; + delete [] colorAttachments; + if (depthType == GENO_FRAMEBUFFER_DEPTH_TEXTURE) + delete depthTexture; + else if (depthType == GENO_FRAMEBUFFER_DEPTH_BUFFER) + glDeleteRenderbuffers(1, &depthBuffer); + glDeleteFramebuffers(1, &id); +} + diff --git a/src/geno/gl/GenoFramebuffer.h b/src/geno/gl/GenoFramebuffer.h new file mode 100644 index 0000000..4b4c5d6 --- /dev/null +++ b/src/geno/gl/GenoFramebuffer.h @@ -0,0 +1,100 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_WINDOW_FORWARD +#define GNARLY_GENOME_WINDOW_FORWARD + +class GenoWindow; + +#endif // GNARLY_GENOME_WINDOW_FORWARD + +#ifndef GNARLY_GENOME_FRAMEBUFFER +#define GNARLY_GENOME_FRAMEBUFFER + +#include "../GenoInts.h" +#include "../engine/GenoWindow.h" +#include "GenoTexture2D.h" + +#define GENO_FRAMEBUFFER_DEPTH_NONE 0x00 +#define GENO_FRAMEBUFFER_DEPTH_TEXTURE 0x01 +#define GENO_FRAMEBUFFER_DEPTH_BUFFER 0x02 + +struct GenoFramebufferCreateInfo { + uint32 width; + uint32 height; + uint32 numColorAttachments; + uint32 depthAttachmentType; + uint32 numTextureParams; + uint32 * textureParams; + + float clearRed; + float clearGreen; + float clearBlue; + float clearDepth; +}; + +class GenoFramebuffer { + private: + static const GenoWindow * activeWindow; + static const GenoFramebuffer * activeFramebuffer; + + uint32 id; + uint32 width; + uint32 height; + + uint32 clearBits; + float clearRed; + float clearGreen; + float clearBlue; + float clearDepth; + + uint32 numColorAttachments; + GenoTexture2D ** colorAttachments; + uint32 depthType; + uint32 depthBuffer; + GenoTexture2D * depthTexture; + + GenoFramebuffer(); + public: + static void clear(); + static void bindDefault(); + + static uint32 getCurrentWidth(); + static uint32 getCurrentHeight(); + + GenoFramebuffer(const GenoFramebufferCreateInfo & info); + uint32 getWidth() const; + uint32 getHeight() const; + void bind() const; + const GenoTexture2D * getColorTexture(uint32 index = 0) const; + const GenoTexture2D * getDepthTexture() const; + ~GenoFramebuffer(); + + friend class GenoWindow; +}; + +#define GNARLY_GENOME_FRAMEBUFFER_FORWARD +#endif // GNARLY_GENOME_FRAMEBUFFER \ No newline at end of file diff --git a/src/geno/gl/GenoGL.h b/src/geno/gl/GenoGL.h new file mode 100644 index 0000000..68f48d2 --- /dev/null +++ b/src/geno/gl/GenoGL.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_GL +#define GNARLY_GENOME_GL + +/** + * Includes both glew and glfw to ensure that they are included in the correct order +**/ +#include +#include + +#endif // GNARLY_GENOME_GL \ No newline at end of file diff --git a/src/geno/gl/GenoShader.cpp b/src/geno/gl/GenoShader.cpp new file mode 100644 index 0000000..8721257 --- /dev/null +++ b/src/geno/gl/GenoShader.cpp @@ -0,0 +1,178 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include + +#include "GenoGL.h" + +#include "GenoShader.h" + +int32 GenoShader::active = 0; + +GenoShader::GenoShader(const char * vert, const char * frag, bool file) { + uint32 vertId = loadShader(vert, GL_VERTEX_SHADER, file); + uint32 fragId = loadShader(frag, GL_FRAGMENT_SHADER, file); + program = glCreateProgram(); + glAttachShader(program, vertId); + glAttachShader(program, fragId); + glLinkProgram(program); + + int result, length; + glGetProgramiv(program, GL_LINK_STATUS, &result); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); + + if (length > 1) { + char * message = new char[length + 1]; + glGetProgramInfoLog(program, length, 0, message); + std::cerr << message << std::endl; + delete[] message; + } + + glDetachShader(program, vertId); + glDetachShader(program, fragId); + + glDeleteShader(vertId); + glDeleteShader(fragId); +} + +GenoShader::GenoShader(const char * vert, const char * geom, const char * frag, bool file) { + uint32 vertId = loadShader(vert, GL_VERTEX_SHADER, file); + uint32 geomId = loadShader(geom, GL_GEOMETRY_SHADER, file); + uint32 fragId = loadShader(frag, GL_FRAGMENT_SHADER, file); + program = glCreateProgram(); + glAttachShader(program, vertId); + glAttachShader(program, geomId); + glAttachShader(program, fragId); + glLinkProgram(program); + + + int result, length; + glGetProgramiv(program, GL_LINK_STATUS, &result); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); + + if (length > 1) { + char * message = new char[length + 1]; + glGetProgramInfoLog(program, length, 0, message); + std::cerr << message << std::endl; + delete[] message; + } + + glDetachShader(program, vertId); + glDetachShader(program, geomId); + glDetachShader(program, fragId); + + glDeleteShader(vertId); + glDeleteShader(geomId); + glDeleteShader(fragId); +} + +uint32 GenoShader::loadShader(const char * path, int32 type, bool file) { + int length; + char * input; + if (file) { + std::ifstream fin(path, std::ifstream::binary); + if (fin) { + std::string contents((std::istreambuf_iterator(fin)), std::istreambuf_iterator()); + + input = new char[contents.length() + 1]; + memcpy(input, contents.c_str(), contents.length()); + input[contents.length()] = 0; + + fin.close(); + } + #ifdef _DEBUG + else { + std::cerr << "Genome Error (GenoShader): Cannot find shader '" << path << "'!" << std::endl; + return 0; + } + #endif + } + else { + length = strlen(path); + input = new char[length]; + strcpy(input, path); + } + + uint32 id = glCreateShader(type); + glShaderSource(id, 1, &input, 0); + glCompileShader(id); + + int result; + glGetShaderiv(id, GL_COMPILE_STATUS, &result); + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); + + if (length > 1) { + if(file) + std::cerr << "Genome Error (GenoShader): Shader '" << path << "' compilation failed!" << std::endl; + else + std::cerr << "Genome Error (GenoShader): Shader compilation failed!" << std::endl; + char * message = new char[length + 1]; + glGetShaderInfoLog(id, length, 0, message); + std::cerr << "\t" << message << std::endl; + delete [] message; + } + + return id; + delete [] input; +} + +void GenoShader::enable() { + if (active != program) { + glUseProgram(program); + active = program; + } +} + +void GenoShader::disable() { + if (active != 0) { + glUseProgram(0); + active = 0; + } +} + +GenoShader::~GenoShader() { + glDeleteProgram(program); +} + +GenoMvpShader::GenoMvpShader(const char * vert, const char * frag, bool file) : + GenoShader(vert, frag, file) { + mvpLoc = glGetUniformLocation(program, "mvp"); +} + +GenoMvpShader::GenoMvpShader(const char * vert, const char * frag, const char * geom, bool file) : + GenoShader(vert, frag, geom, file) { + mvpLoc = glGetUniformLocation(program, "mvp"); +} + +void GenoMvpShader::setMvp(const GenoMatrix4f & mvp) { + glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvp.m); +} + +void GenoMvpShader::setMvp(const float * mvp) { + glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvp); +} \ No newline at end of file diff --git a/src/geno/gl/GenoShader.h b/src/geno/gl/GenoShader.h new file mode 100644 index 0000000..427e7f2 --- /dev/null +++ b/src/geno/gl/GenoShader.h @@ -0,0 +1,65 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_SHADER +#define GNARLY_GENOME_SHADER + +#include "../GenoInts.h" + +#include "../math/linear/GenoMatrix4.h" + +#define GENO_SHADER_STRING_IS_SOURCE 0x00 +#define GENO_SHADER_STRING_IS_PATH 0x01 + +class GenoShader { + private: + static int32 active; + + uint32 loadShader(const char * path, int32 type, bool file); + protected: + GenoShader(const char * vert, const char * frag, bool file); + GenoShader(const char * vert, const char * geom, const char * frag, bool file); + int32 program; + public: + void enable(); + void disable(); + ~GenoShader(); +}; + +class GenoMvpShader : public GenoShader { + private: + uint32 mvpLoc; + protected: + GenoMvpShader(const char * vert, const char * frag, bool file); + GenoMvpShader(const char * vert, const char * frag, const char * geom, bool file); + public: + void setMvp(const GenoMatrix4f & mvp); + void setMvp(const float * mvp); + +}; + +#define GNARLY_GENOME_SHADER_FORWARD +#endif // GNARLY_GENOME_SHADER \ No newline at end of file diff --git a/src/geno/gl/GenoSpritesheet.cpp b/src/geno/gl/GenoSpritesheet.cpp new file mode 100644 index 0000000..d5f177b --- /dev/null +++ b/src/geno/gl/GenoSpritesheet.cpp @@ -0,0 +1,172 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include "GenoGL.h" +#include "../data/GenoImage.h" +#include "GenoSpritesheet.h" + +GenoSpritesheet::GenoSpritesheet() {} + +GenoSpritesheet * GenoSpritesheet::create(const GenoSpritesheetCreateInfo & info) { + GenoImage * image = 0; + uint32 width; + uint32 height; + uint32 fullWidth; + uint32 fullHeight; + uint8 * data; + if (info.type == GENO_SPRITESHEET_TYPE_CREATE) { + width = info.width / info.numSpritesX; + height = info.height / info.numSpritesY; + fullWidth = info.width; + fullHeight = info.height; + data = info.data; + } + else { + GenoImageCreateInfo imageInfo = {}; + imageInfo.type = info.type; + imageInfo.path = info.texture; + + image = GenoImage::create(imageInfo); + + if (image == 0) + return 0; + + width = image->getWidth() / info.numSpritesX; + height = image->getHeight() / info.numSpritesY; + fullWidth = image->getWidth(); + fullHeight = image->getHeight(); + data = image->getBytes(); + } + + float fractionalWidth = (float) width / (float) fullWidth; + float fractionalHeight = (float) height / (float) fullHeight; + + float paddingX = 0; + float paddingY = 0; + bool cleanData = false; + if (info.addPadding) { + cleanData = true; + uint32 fullPadWidth = fullWidth + info.numSpritesX * 2; + uint32 fullPadHeight = fullHeight + info.numSpritesY * 2; + uint32 padWidth = width + 2; + uint32 padHeight = height + 2; + uint8 * newData = new uint8[fullPadWidth * fullPadHeight * 4]; + uint32 numSprites = info.numSpritesX * info.numSpritesY; + uint32 numPixels = padWidth * padHeight; + for (uint32 i = 0; i < numSprites; ++i) { + uint32 spriteX = i % info.numSpritesX; + uint32 spriteY = i / info.numSpritesX; + uint32 padOffsetX = padWidth * spriteX; + uint32 padOffsetY = padHeight * spriteY; + uint32 offsetX = width * spriteX; + uint32 offsetY = height * spriteY; + for (uint32 j = 0; j < numPixels; ++j) { + uint32 pixelX = j % padWidth; + uint32 pixelY = j / padWidth; + uint32 targetX = pixelX == padWidth - 1 ? pixelX - 2 : (pixelX > 0 ? pixelX - 1 : 0); + uint32 targetY = pixelY == padHeight - 1 ? pixelY - 2 : (pixelY > 0 ? pixelY - 1 : 0); + uint32 writeIndex = ((pixelY + padOffsetY) * fullPadWidth + pixelX + padOffsetX) * 4; + uint32 readIndex = ((targetY + offsetY ) * fullWidth + targetX + offsetX ) * 4; + newData[writeIndex ] = data[readIndex ]; + newData[writeIndex + 1] = data[readIndex + 1]; + newData[writeIndex + 2] = data[readIndex + 2]; + newData[writeIndex + 3] = data[readIndex + 3]; + } + } + fullWidth = padWidth * info.numSpritesX; + fullHeight = padHeight * info.numSpritesY; + data = newData; + + paddingX = 1.0 / (float) fullPadWidth; + paddingY = 1.0 / (float) fullPadHeight; + } + + + uint32 id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fullWidth, fullHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + for (uint32 i = 0; i < info.numParams; ++i) { + uint32 index = i * 2; + glTexParameteri(GL_TEXTURE_2D, info.params[index], info.params[index + 1]); + } + + GenoSpritesheet * ret = new GenoSpritesheet(); + ret->id = id; + ret->width = width; + ret->height = height; + ret->numSpritesX = info.numSpritesX; + ret->numSpritesY = info.numSpritesY; + ret->paddingX = paddingX; + ret->paddingY = paddingY; + ret->fractionalWidth = fractionalWidth; + ret->fractionalHeight = fractionalHeight; + ret->scaleX = fractionalWidth - paddingX * 2; + ret->scaleY = fractionalHeight - paddingY * 2; + + if (cleanData) + delete [] data; + delete image; + + return ret; +} + +uint32 GenoSpritesheet::getWidth() const { + return width; +} + +uint32 GenoSpritesheet::getHeight() const { + return height; +} + +GenoMatrix4f GenoSpritesheet::getTransform(uint32 sprite) const { + return GenoMatrix4f::makeTranslateXY((sprite % numSpritesX) * fractionalWidth + paddingX, + (sprite / numSpritesX) * fractionalHeight + paddingY).scaleXY(scaleX, scaleY); +} + +GenoMatrix4f GenoSpritesheet::getTransform(uint32 x, uint32 y) const { + return GenoMatrix4f::makeTranslateXY(x * fractionalWidth + paddingX, + y * fractionalHeight + paddingY).scaleXY(scaleX, scaleY); +} + +GenoMatrix4f GenoSpritesheet::getTransform(const GenoVector2i & coords) const { + return GenoMatrix4f::makeTranslateXY(coords.v[0] * fractionalWidth + paddingX, + coords.v[1] * fractionalHeight + paddingY).scaleXY(scaleX, scaleY); +} + +void GenoSpritesheet::bind(uint8 textureNum) const { + glActiveTexture(GL_TEXTURE0 + textureNum); + glBindTexture(GL_TEXTURE_2D, id); +} + +void GenoSpritesheet::unbind() const { + glBindTexture(GL_TEXTURE_2D, 0); +} + +GenoSpritesheet::~GenoSpritesheet() {} \ No newline at end of file diff --git a/src/geno/gl/GenoSpritesheet.h b/src/geno/gl/GenoSpritesheet.h new file mode 100644 index 0000000..c8d9ec3 --- /dev/null +++ b/src/geno/gl/GenoSpritesheet.h @@ -0,0 +1,92 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_TEXTURE_FORWARD +#define GNARLY_GENOME_TEXTURE_FORWARD + +class GenoTexture; + +#endif // GNARLY_GENOME_TEXTURE_FORWARD + +#ifndef GNARLY_GENOME_SPRITESHEET +#define GNARLY_GENOME_SPRITESHEET + +#define GENO_SPRITESHEET_TYPE_CREATE 0x00 +#define GENO_SPRITESHEET_TYPE_PNG 0x01 +#define GENO_SPRITESHEET_TYPE_BMP 0x02 + +#include "../GenoInts.h" +#include "../math/linear/GenoMatrix4.h" +#include "../math/linear/GenoVector2.h" +#include "GenoTexture.h" + +struct GenoSpritesheetCreateInfo { + uint32 type; + bool addPadding; + uint32 numSpritesX; + uint32 numSpritesY; + uint32 numParams; + uint32 * params; + + uint32 width; + uint32 height; + uint8 * data; + + const char * texture; +}; + +class GenoSpritesheet : public GenoTexture { + private: + uint32 width; + uint32 height; + uint32 numSpritesX; + uint32 numSpritesY; + + float paddingX; + float paddingY; + float fractionalWidth; + float fractionalHeight; + float scaleX; + float scaleY; + + GenoSpritesheet(); + public: + static GenoSpritesheet * create(const GenoSpritesheetCreateInfo & info); + uint32 getWidth() const; + uint32 getHeight() const; + + GenoMatrix4f getTransform(uint32 sprite) const; + GenoMatrix4f getTransform(uint32 x, uint32 y) const; + GenoMatrix4f getTransform(const GenoVector2i & coords) const; + + virtual void bind(uint8 textureNum = 0) const; + virtual void unbind() const; + + ~GenoSpritesheet(); +}; + +#define GNARLY_GENOME_SPRITESHEET_FORWARD +#endif // GNARLY_GENOME_SPRITESHEET \ No newline at end of file diff --git a/src/geno/gl/GenoTexture.cpp b/src/geno/gl/GenoTexture.cpp new file mode 100644 index 0000000..6d49b2b --- /dev/null +++ b/src/geno/gl/GenoTexture.cpp @@ -0,0 +1,38 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoGL.h" + +#include "GenoTexture.h" + +GenoTexture::GenoTexture() {} + +GenoTexture::GenoTexture(uint32 id) : + id(id) {} + +GenoTexture::~GenoTexture() { + glDeleteTextures(1, &id); +} \ No newline at end of file diff --git a/src/geno/gl/GenoTexture.h b/src/geno/gl/GenoTexture.h new file mode 100644 index 0000000..eb781db --- /dev/null +++ b/src/geno/gl/GenoTexture.h @@ -0,0 +1,45 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_TEXTURE +#define GNARLY_GENOME_TEXTURE + +#include "../GenoInts.h" + +class GenoTexture { + protected: + uint32 id; + + GenoTexture(); + GenoTexture(uint32 id); + public: + virtual void bind(uint8 textureNum = 0) const = 0; + virtual void unbind() const = 0; + virtual ~GenoTexture(); +}; + +#define GNARLY_GENOME_TEXTURE_FORWARD +#endif // GNARLY_GENOME_TEXTURE \ No newline at end of file diff --git a/src/geno/gl/GenoTexture2D.cpp b/src/geno/gl/GenoTexture2D.cpp new file mode 100644 index 0000000..b4af992 --- /dev/null +++ b/src/geno/gl/GenoTexture2D.cpp @@ -0,0 +1,94 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoGL.h" +#include "../data/GenoImage.h" + +#include "GenoTexture2D.h" + +GenoTexture2D::GenoTexture2D(uint32 id, uint32 width, uint32 height) : + GenoTexture(id), + width(width), + height(height) {} + +GenoTexture2D * GenoTexture2D::create(const GenoTexture2DCreateInfo & info) { + GenoImage * image = 0; + uint32 width; + uint32 height; + uint8 * data; + if (info.type == GENO_TEXTURE2D_TYPE_CREATE) { + width = info.width; + height = info.height; + data = info.data; + } + else { + GenoImageCreateInfo imageInfo = {}; + imageInfo.type = info.type; + imageInfo.path = info.texture; + + image = GenoImage::create(imageInfo); + + if (image == 0) + return 0; + width = image->getWidth(); + height = image->getHeight(); + data = image->getBytes(); + } + + uint32 id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + for (uint32 i = 0; i < info.numParams; ++i) { + uint32 index = i * 2; + glTexParameteri(GL_TEXTURE_2D, info.params[index], info.params[index + 1]); + } + + GenoTexture2D * ret = new GenoTexture2D(id, width, height); + + delete image; + + return ret; +} + +uint32 GenoTexture2D::getWidth() const { + return width; +} + +uint32 GenoTexture2D::getHeight() const { + return height; +} + +void GenoTexture2D::bind(uint8 textureNum) const { + glActiveTexture(GL_TEXTURE0 + textureNum); + glBindTexture(GL_TEXTURE_2D, id); +} + +void GenoTexture2D::unbind() const { + glBindTexture(GL_TEXTURE_2D, 0); +} + +GenoTexture2D::~GenoTexture2D() {} \ No newline at end of file diff --git a/src/geno/gl/GenoTexture2D.h b/src/geno/gl/GenoTexture2D.h new file mode 100644 index 0000000..474b98f --- /dev/null +++ b/src/geno/gl/GenoTexture2D.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_TEXTURE_FORWARD +#define GNARLY_GENOME_TEXTURE_FORWARD + +class GenoTexture; + +#endif // GNARLY_GENOME_TEXTURE_FORWARD + +#ifndef GNARLY_GENOME_TEXTURE2D +#define GNARLY_GENOME_TEXTURE2D + +#include "../GenoInts.h" + +#include "GenoTexture.h" + +#define GENO_TEXTURE2D_TYPE_CREATE 0x00 +#define GENO_TEXTURE2D_TYPE_PNG 0x01 +#define GENO_TEXTURE2D_TYPE_BMP 0x02 + +struct GenoTexture2DCreateInfo { + uint32 type; + uint32 numParams; + uint32 * params; + + uint32 width; + uint32 height; + uint8 * data; + + const char * texture; +}; + +class GenoTexture2D : public GenoTexture { + private: + uint32 width; + uint32 height; + + GenoTexture2D(uint32 id, uint32 width, uint32 height); + public: + static GenoTexture2D * create(const GenoTexture2DCreateInfo & info); + uint32 getWidth() const; + uint32 getHeight() const; + virtual void bind(uint8 textureNum = 0) const; + virtual void unbind() const; + ~GenoTexture2D(); + + friend class GenoFramebuffer; +}; + +#define GNARLY_GENOME_TEXTURE2D_FORWARD +#endif // GNARLY_GENOME_TEXTURE2D diff --git a/src/geno/gl/GenoVao.cpp b/src/geno/gl/GenoVao.cpp new file mode 100644 index 0000000..51ced80 --- /dev/null +++ b/src/geno/gl/GenoVao.cpp @@ -0,0 +1,72 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoGL.h" + +#include "GenoVao.h" + +template +struct GenoVertexAttribType {}; + +template<> struct GenoVertexAttribType< int8 > { const static uint32 TYPE = GL_UNSIGNED_BYTE; }; +template<> struct GenoVertexAttribType { const static uint32 TYPE = GL_BYTE; }; +template<> struct GenoVertexAttribType< int16> { const static uint32 TYPE = GL_UNSIGNED_SHORT; }; +template<> struct GenoVertexAttribType { const static uint32 TYPE = GL_SHORT; }; +template<> struct GenoVertexAttribType< int32> { const static uint32 TYPE = GL_UNSIGNED_INT; }; +template<> struct GenoVertexAttribType { const static uint32 TYPE = GL_INT; }; +template<> struct GenoVertexAttribType { const static uint32 TYPE = GL_FLOAT; }; +template<> struct GenoVertexAttribType { const static uint32 TYPE = GL_DOUBLE; }; + +GenoVao::GenoVao(uint32 num, float verts[], uint32 count, uint32 indices[]) { + this->count = count; + glGenVertexArrays(1, &vao); + addAttrib(num, 3, verts); + glGenBuffers(1, &ibo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(int32), indices, GL_STATIC_DRAW); +} + +template +void GenoVao::addAttrib(uint32 num, uint32 stride, T data[]) { + glBindVertexArray(vao); + glGenBuffers(1, vbos + attribs); + glBindBuffer(GL_ARRAY_BUFFER, vbos[attribs]); + glBufferData(GL_ARRAY_BUFFER, stride * num * sizeof(T), data, GL_STATIC_DRAW); + glVertexAttribPointer(attribs, stride, GenoVertexAttribType::TYPE, GL_FALSE, 0, (void*) 0); + glEnableVertexAttribArray(attribs); + ++attribs; +} + +void GenoVao::render() { + glBindVertexArray(vao); + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0); +} + +GenoVao::~GenoVao() { + glDeleteBuffers(attribs, vbos); + glDeleteBuffers(1, &ibo); + glDeleteVertexArrays(1, &vao); +} diff --git a/src/geno/gl/GenoVao.h b/src/geno/gl/GenoVao.h new file mode 100644 index 0000000..a66d3da --- /dev/null +++ b/src/geno/gl/GenoVao.h @@ -0,0 +1,44 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_VAO +#define GNARLY_GENOME_VAO + +#include "../GenoInts.h" + +class GenoVao { + private: + uint32 vao, vbos[15], ibo, count; + uint8 attribs = 0; + public: + GenoVao(uint32 num, float verts[], uint32 count, uint32 indices[]); + template void addAttrib(uint32 num, uint32 stride, T data[]); + void render(); + ~GenoVao(); +}; + +#define GNARLY_GENOME_VAO_FORWARD +#endif // GNARLY_GENOME_VAO \ No newline at end of file diff --git a/src/geno/math/GenoConstants.h b/src/geno/math/GenoConstants.h new file mode 100644 index 0000000..bfa7185 --- /dev/null +++ b/src/geno/math/GenoConstants.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_CONSTANTS +#define GNARLY_GENOME_CONSTANTS + +template constexpr T GENO_PI = T(3.141592653589793238462643383279l); +template constexpr T GENO_TAU = T(6.283185307179586476925286766559l); +template constexpr T GENO_E = T(2.718281828459045235360287471353l); + +#endif // GNARLY_GENOME_CONSTANTS \ No newline at end of file diff --git a/src/geno/math/linear/GenoMatrix.h b/src/geno/math/linear/GenoMatrix.h new file mode 100644 index 0000000..0c1dc00 --- /dev/null +++ b/src/geno/math/linear/GenoMatrix.h @@ -0,0 +1,195 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_MATRIX +#define GNARLY_GENOME_MATRIX + +#include +#include + +#include "GenoVector.h" + +template +class GenoMatrix { + + static_assert(N > 0 && M > 0, "Matrix dimensions must be greater than 0!"); + + private: + bool owner = true; + + void clean() { + if (owner) + delete [] m; + } + public: + T * m; + + GenoMatrix() : + m(new T[N * M]()) {} + + GenoMatrix(T * m, bool owner = true) noexcept : + owner(owner), + m(m) {} + + GenoMatrix(std::initializer_list list) : + m(new T[N * M]) { + auto min = list.size() < N * M ? list.size() : N * M; + auto init = list.begin(); + for (uint32 i = 0; i < min; ++i) + m[(i % M) * N + (i / M)] = init[i]; + } + + template + GenoMatrix(const GenoMatrix & matrix) : + m(new T[N * M]) { + for (uint32 i = 0; i < N * M; ++i) + m[i] = (T) matrix.m[i]; + } + + GenoMatrix(const GenoMatrix & matrix) : + m(new T[N * M]) { + for (uint32 i = 0; i < N * M; ++i) + m[i] = matrix.m[i]; + } + + GenoMatrix(GenoMatrix && matrix) noexcept : + owner(matrix.owner), + m(matrix.m) { + matrix.owner = false; + } + + GenoMatrix & operator=(const GenoMatrix & matrix) { + for (uint32 i = 0; i < N * M; ++i) + m[i] = matrix.m[i]; + return *this; + } + + GenoMatrix & operator=(GenoMatrix && matrix) noexcept { + clean(); + owner = matrix.owner; + m = matrix.m; + matrix.owner = false; + return *this; + } + + GenoMatrix & operator+=(const GenoMatrix & matrix) { + for (uint32 i = 0; i < N * M; ++i) + m[i] += matrix.m[i]; + return *this; + } + + GenoMatrix & operator-=(const GenoMatrix & matrix) { + for (uint32 i = 0; i < N * M; ++i) + m[i] -= matrix.m[i]; + return *this; + } + + GenoVector operator[](uint32 index) const noexcept { + return GenoVector(index * M, false); + } + + ~GenoMatrix() { + clean(); + } +}; + +template +GenoMatrix operator+(const GenoMatrix & left, const GenoMatrix & right) { + auto sum = new T[N * M]; + for (uint32 i = 0; i < N * M; ++i) + sum[i] = left.m[i] + right.m[i]; + return sum; +} + +template +GenoMatrix operator-(const GenoMatrix & left, const GenoMatrix & right) { + auto difference = new T[N * M]; + for (uint32 i = 0; i < N * M; ++i) + difference[i] = left.m[i] - right.m[i]; + return difference; +} + +template +GenoMatrix operator*(const GenoMatrix & left, const GenoMatrix & right) { + auto product = new T[N2 * M]; + for (uint32 i = 0; i < M; ++i) { + for (uint32 j = 0; j < N2; ++j) { + product[j * M + i] = 0; + for (uint32 k = 0; k < N; ++k) + product[j * M + i] += left.m[k * M + i] * right.m[j * N + k]; + } + } + return product; +} + +template +GenoVector operator*(const GenoMatrix & left, const GenoVector & right) { + auto product = new T[M]; + for (uint32 i = 0; i < M; ++i) { + product[i] = 0; + for (uint32 j = 0; j < N; ++j) + product[i] += left.m[j * M + i] * right.v[j]; + } + return product; +} + +template +std::ostream & operator<<(std::ostream & stream, const GenoMatrix & matrix) { + for (uint32 i = 0; i < M; ++i) { + stream << '['; + for (uint32 j = 0; j < N; ++j) { + stream << matrix.m[j * M + i]; + if (j < N - 1) + stream << ", "; + } + stream << "]\n"; + } + return stream; +} + +template using GenoMatrixNMb = GenoMatrix; +template using GenoMatrixNMub = GenoMatrix; +template using GenoMatrixNMs = GenoMatrix; +template using GenoMatrixNMus = GenoMatrix; +template using GenoMatrixNMi = GenoMatrix; +template using GenoMatrixNMui = GenoMatrix; +template using GenoMatrixNMl = GenoMatrix; +template using GenoMatrixNMul = GenoMatrix; +template using GenoMatrixNMf = GenoMatrix; +template using GenoMatrixNMd = GenoMatrix; + +#define GNARLY_GENOME_MATRIX_FORWARD +#endif // GNARLY_GENOME_MATRIX \ No newline at end of file diff --git a/src/geno/math/linear/GenoMatrix4.h b/src/geno/math/linear/GenoMatrix4.h new file mode 100644 index 0000000..c28c24e --- /dev/null +++ b/src/geno/math/linear/GenoMatrix4.h @@ -0,0 +1,8579 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_VECTOR2_FORWARD +#define GNARLY_GENOME_VECTOR2_FORWARD + +template +class GenoVector<2, T>; + +#endif // GNARLY_GENOME_VECTOR2_FORWARD + +#ifndef GNARLY_GENOME_VECTOR3_FORWARD +#define GNARLY_GENOME_VECTOR3_FORWARD + +template +class GenoVector<3, T>; + +#endif // GNARLY_GENOME_VECTOR3_FORWARD + +#ifndef GNARLY_GENOME_VECTOR4_FORWARD +#define GNARLY_GENOME_VECTOR4_FORWARD + +template +class GenoVector<4, T>; + +#endif // GNARLY_GENOME_VECTOR4_FORWARD + +#ifndef GNARLY_GENOME_MATRIX_FORWARD +#define GNARLY_GENOME_MATRIX_FORWARD + +template +class GenoMatrix; + +#endif // GNARLY_GENOME_MATRIX_FORWARD + +#ifndef GNARLY_GENOME_MATRIXN_FORWARD +#define GNARLY_GENOME_MATRIXN_FORWARD + +template +class GenoMatrix; + +#endif // GNARLY_GENOME_MATRIXN_FORWARD + +#ifndef GNARLY_GENOME_MATRIX4 +#define GNARLY_GENOME_MATRIX4 + +#include +#include + +#include "GenoVector2.h" +#include "GenoVector3.h" +#include "GenoVector4.h" +#include "GenoMatrixN.h" + +template +class GenoMatrix<4, 4, T> { + private: + bool owner = true; + + void clean() { + if (owner) + delete [] m; + } + public: + T * m; + + static GenoMatrix<4, 4, T> makeIdentity() { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeOrthographic(T left, T right, T bottom, T top, T near, T far) { + return new T[4 * 4] { + 2 / (right - left), 0, 0, 0, + 0, 2 / (top - bottom), 0, 0, + 0, 0, 2 / (far - near), 0, + (left + right) / (left - right), (bottom + top) / (bottom - top), (near + far) / (near - far), 1 + }; + } + + static GenoMatrix<4, 4, T> makePerspective(T fovY, T aspectRatio, T near, T far) { + auto vertical = 1 / tan(fovY / 2); + return new T[4 * 4] { + vertical / aspectRatio, 0, 0, 0, + 0, vertical, 0, 0, + 0, 0, (near + far) / (near - far), -1, + 0, 0, (2 * far * near) / (near - far), 0 + }; + } + + static GenoMatrix<4, 4, T> makeShear2D(T axisAngle, T shearAngle) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = tan(shearAngle); + return new T[4 * 4] { + sinAxis * tanShear * cosAxis, -cosAxis * tanShear * cosAxis, 0, 0, + sinAxis * tanShear * sinAxis, -cosAxis * tanShear * sinAxis, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2D(const GenoVector<2, T> & axis, T shearAngle) { + auto unitAxis = normalize(axis); + auto tanShear = tan(shearAngle); + return new T[4 * 4] { + unitAxis.v[1] * tanShear * unitAxis.v[0], -unitAxis.v[0] * tanShear * unitAxis.v[0], 0, 0, + unitAxis.v[1] * tanShear * unitAxis.v[1], -unitAxis.v[0] * tanShear * unitAxis.v[1], 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2D(T axisAngle, const GenoVector<2, T> & shear) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = shear.v[1] / shear.v[0]; + return new T[4 * 4] { + sinAxis * tanShear * cosAxis, -cosAxis * tanShear * cosAxis, 0, 0, + sinAxis * tanShear * sinAxis, -cosAxis * tanShear * sinAxis, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2D(const GenoVector<2, T> & axis, const GenoVector<2, T> & shear) { + auto unitAxis = normalize(axis); + auto tanShear = shear.v[1] / shear.v[0]; + return new T[4 * 4] { + unitAxis.v[1] * tanShear * unitAxis.v[0], -unitAxis.v[0] * tanShear * unitAxis.v[0], 0, 0, + unitAxis.v[1] * tanShear * unitAxis.v[1], -unitAxis.v[0] * tanShear * unitAxis.v[1], 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2DX(T angle) { + return new T[4 * 4] { + 1, -tan(angle), 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2DX(const GenoVector<2, T> & shear) { + return new T[4 * 4] { + 1, -shear.v[1] / shear.v[0], 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2DY(T angle) { + return new T[4 * 4] { + 1, 0, 0, 0, + tan(angle), 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeShear2DY(const GenoVector<2, T> & shear) { + return new T[4 * 4] { + 1, 0, 0, 0, + shear.v[1] / shear.v[0], 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslate2D(T translateX, T translateY) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translateX, translateY, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslate2D(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[0], translate.v[1], 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslate(T translateX, T translateY, T translateZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translateX, translateY, translateZ, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslate(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[0], translate.v[1], translate.v[2], 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotate2D(T rotation) { + auto sinZ = sin(rotation); + auto cosZ = cos(rotation); + return new T[4 * 4] { + cosZ, sinZ, 0, 0, + -sinZ, cosZ, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScale2D(T scale) { + return new T[4 * 4] { + scale, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScale2D(T scaleX, T scaleY) { + return new T[4 * 4] { + scaleX, 0, 0, 0, + 0, scaleY, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScale2D(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + scale.v[0], 0, 0, 0, + 0, scale.v[1], 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScale(T scale) { + return new T[4 * 4] { + scale, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, scale, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScale(T scaleX, T scaleY, T scaleZ) { + return new T[4 * 4] { + scaleX, 0, 0, 0, + 0, scaleY, 0, 0, + 0, 0, scaleZ, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScale(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[0], 0, 0, 0, + 0, scale.v[1], 0, 0, + 0, 0, scale.v[2], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateX(T translateX) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translateX, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateY(T translateY) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, translateY, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateZ(T translateZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, translateZ, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXY(T translateX, T translateY) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translateX, translateY, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXY(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[0], translate.v[1], 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXZ(T translateX, T translateZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translateX, 0, translateZ, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXZ(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[0], 0, translate.v[1], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateYX(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[1], translate.v[0], 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateYZ(T translateY, T translateZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, translateY, translateZ, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateYZ(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, translate.v[0], translate.v[1], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateZX(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[1], 0, translate.v[0], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateZY(const GenoVector<2, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, translate.v[1], translate.v[0], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXYZ(T translateX, T translateY, T translateZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translateX, translateY, translateZ, 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXYZ(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[0], translate.v[1], translate.v[2], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateXZY(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[0], translate.v[2], translate.v[1], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateYXZ(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[1], translate.v[0], translate.v[2], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateYZX(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[2], translate.v[0], translate.v[1], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateZXY(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[1], translate.v[2], translate.v[0], 1 + }; + } + + static GenoMatrix<4, 4, T> makeTranslateZYX(const GenoVector<3, T> & translate) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + translate.v[2], translate.v[1], translate.v[0], 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateX(T rotateX) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + return new T[4 * 4] { + 1, 0, 0, 0, + 0, cosX, sinX, 0, + 0, -sinX, cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateY(T rotateY) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + return new T[4 * 4] { + cosY, 0, -sinY, 0, + 0, 1, 0, 0, + sinY, 0, cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateZ(T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return new T[4 * 4] { + cosZ, sinZ, 0, 0, + -sinZ, cosZ, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXY(T rotateX, T rotateY) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + return new T[4 * 4] { + cosY, 0, -sinY, 0, + sinY * sinX, cosX, cosY * sinX, 0, + sinY * cosX, -sinX, cosY * cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXY(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + return new T[4 * 4] { + cosY, 0, -sinY, 0, + sinY * sinX, cosX, cosY * sinX, 0, + sinY * cosX, -sinX, cosY * cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXZ(T rotateX, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return new T[4 * 4] { + cosZ, sinZ, 0, 0, + -sinZ * cosX, cosZ * cosX, sinX, 0, + sinZ * sinX, -cosZ * sinX, cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXZ(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return new T[4 * 4] { + cosZ, sinZ, 0, 0, + -sinZ * cosX, cosZ * cosX, sinX, 0, + sinZ * sinX, -cosZ * sinX, cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateYX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + return new T[4 * 4] { + cosY, sinX * sinY, -cosX * sinY, 0, + 0, cosX, sinX, 0, + sinY, -sinX * cosY, cosX * cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateYZ(T rotateY, T rotateZ) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return new T[4 * 4] { + cosZ * cosY, sinZ * cosY, -sinY, 0, + -sinZ, cosZ, 0, 0, + cosZ * sinY, sinZ * sinY, cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateYZ(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return new T[4 * 4] { + cosZ * cosY, sinZ * cosY, -sinY, 0, + -sinZ, cosZ, 0, 0, + cosZ * sinY, sinZ * sinY, cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateZX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return new T[4 * 4] { + cosZ, cosX * sinZ, sinX * sinZ, 0, + -sinZ, cosX * cosZ, sinX * cosZ, 0, + 0, -sinX, cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateZY(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return new T[4 * 4] { + cosY * cosZ, sinZ, -sinY * cosZ, 0, + -cosY * sinZ, cosZ, sinY * sinZ, 0, + sinY, 0, cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXYZ(T rotateX, T rotateY, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return new T[4 * 4] { + cosZ * cosY, sinZ * cosY, -sinY, 0, + -sinZ * cosX + cosZ * sinY * sinX, cosZ * cosX + sinZ * sinY * sinX, cosY * sinX, 0, + sinZ * sinX + cosZ * sinY * cosX, -cosZ * sinX + sinZ * sinY * cosX, cosY * cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXYZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + return new T[4 * 4] { + cosZ * cosY, sinZ * cosY, -sinY, 0, + -sinZ * cosX + cosZ * sinY * sinX, cosZ * cosX + sinZ * sinY * sinX, cosY * sinX, 0, + sinZ * sinX + cosZ * sinY * cosX, -cosZ * sinX + sinZ * sinY * cosX, cosY * cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateXZY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return new T[4 * 4] { + cosY * cosZ, sinZ, -sinY * cosZ, 0, + -cosY * sinZ * cosX + sinY * sinX, cosZ * cosX, sinY * sinZ * cosX + cosY * sinX, 0, + cosY * sinZ * sinX + sinY * cosX, -cosZ * sinX, -sinY * sinZ * sinX + cosY * cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateYXZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + return new T[4 * 4] { + cosZ * cosY - sinZ * sinX * sinY, sinZ * cosY + cosZ * sinX * sinY, -cosX * sinY, 0, + -sinZ * cosX, cosZ * cosX, sinX, 0, + cosZ * sinY + sinZ * sinX * cosY, sinZ * sinY - cosZ * sinX * cosY, cosX * cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateYZX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return new T[4 * 4] { + cosZ * cosY, cosX * sinZ * cosY + sinX * sinY, sinX * sinZ * cosY - cosX * sinY, 0, + -sinZ, cosX * cosZ, sinX * cosZ, 0, + cosZ * sinY, cosX * sinZ * sinY - sinX * cosY, sinX * sinZ * sinY + cosX * cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateZXY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return new T[4 * 4] { + cosY * cosZ + sinY * sinX * sinZ, cosX * sinZ, -sinY * cosZ + cosY * sinX * sinZ, 0, + -cosY * sinZ + sinY * sinX * cosZ, cosX * cosZ, sinY * sinZ + cosY * sinX * cosZ, 0, + sinY * cosX, -sinX, cosY * cosX, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeRotateZYX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return new T[4 * 4] { + cosY * cosZ, sinX * sinY * cosZ + cosX * sinZ, -cosX * sinY * cosZ + sinX * sinZ, 0, + -cosY * sinZ, -sinX * sinY * sinZ + cosX * cosZ, cosX * sinY * sinZ + sinX * cosZ, 0, + sinY, -sinX * cosY, cosX * cosY, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleX(T scaleX) { + return new T[4 * 4] { + scaleX, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleY(T scaleY) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, scaleY, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleZ(T scaleZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, scaleZ, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXY(T scale) { + return new T[4 * 4] { + scale, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXY(T scaleX, T scaleY) { + return new T[4 * 4] { + scaleX, 0, 0, 0, + 0, scaleY, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXY(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + scale.v[0], 0, 0, 0, + 0, scale.v[1], 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXZ(T scale) { + return new T[4 * 4] { + scale, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, scale, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXZ(T scaleX, T scaleZ) { + return new T[4 * 4] { + scaleX, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, scaleZ, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXZ(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + scale.v[0], 0, 0, 0, + 0, 1, 0, 0, + 0, 0, scale.v[1], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleYX(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + scale.v[1], 0, 0, 0, + 0, scale.v[0], 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleYZ(T scale) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, scale, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleYZ(T scaleY, T scaleZ) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, scaleY, 0, 0, + 0, 0, scaleZ, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleYZ(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, scale.v[0], 0, 0, + 0, 0, scale.v[1], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleZX(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + scale.v[1], 0, 0, 0, + 0, 1, 0, 0, + 0, 0, scale.v[0], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleZY(const GenoVector<2, T> & scale) { + return new T[4 * 4] { + 1, 0, 0, 0, + 0, scale.v[1], 0, 0, + 0, 0, scale.v[0], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXYZ(T scale) { + return new T[4 * 4] { + scale, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, scale, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXYZ(T scaleX, T scaleY, T scaleZ) { + return new T[4 * 4] { + scaleX, 0, 0, 0, + 0, scaleY, 0, 0, + 0, 0, scaleZ, 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXYZ(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[0], 0, 0, 0, + 0, scale.v[1], 0, 0, + 0, 0, scale.v[2], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleXZY(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[0], 0, 0, 0, + 0, scale.v[2], 0, 0, + 0, 0, scale.v[1], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleYXZ(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[1], 0, 0, 0, + 0, scale.v[0], 0, 0, + 0, 0, scale.v[2], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleYZX(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[2], 0, 0, 0, + 0, scale.v[0], 0, 0, + 0, 0, scale.v[1], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleZXY(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[1], 0, 0, 0, + 0, scale.v[2], 0, 0, + 0, 0, scale.v[0], 0, + 0, 0, 0, 1 + }; + } + + static GenoMatrix<4, 4, T> makeScaleZYX(const GenoVector<3, T> & scale) { + return new T[4 * 4] { + scale.v[2], 0, 0, 0, + 0, scale.v[1], 0, 0, + 0, 0, scale.v[0], 0, + 0, 0, 0, 1 + }; + } + + GenoMatrix() : + m(new T[4 * 4]()) {} + + GenoMatrix(T * m, bool owner = true) noexcept : + owner(owner), + m(m) {} + + GenoMatrix(T a, T b, T c, T d, + T e, T f, T g, T h, + T i, T j, T k, T l, + T m, T n, T o, T p) : + m(new T[4 * 4] { + a, e, i, m, + b, f, j, n, + c, g, k, o, + d, h, l, p + }) {} + + template + GenoMatrix(const GenoMatrix<4, 4, T2> & matrix) : + m(new T[4 * 4]) { + m[0 ] = (T) matrix.m[0 ]; + m[1 ] = (T) matrix.m[1 ]; + m[2 ] = (T) matrix.m[2 ]; + m[3 ] = (T) matrix.m[3 ]; + m[4 ] = (T) matrix.m[4 ]; + m[5 ] = (T) matrix.m[5 ]; + m[6 ] = (T) matrix.m[6 ]; + m[7 ] = (T) matrix.m[7 ]; + m[8 ] = (T) matrix.m[8 ]; + m[9 ] = (T) matrix.m[9 ]; + m[10] = (T) matrix.m[10]; + m[11] = (T) matrix.m[11]; + m[12] = (T) matrix.m[12]; + m[13] = (T) matrix.m[13]; + m[14] = (T) matrix.m[14]; + m[15] = (T) matrix.m[15]; + } + + GenoMatrix(const GenoMatrix<4, 4, T> & matrix) : + m(new T[4 * 4]) { + m[0 ] = matrix.m[0 ]; + m[1 ] = matrix.m[1 ]; + m[2 ] = matrix.m[2 ]; + m[3 ] = matrix.m[3 ]; + m[4 ] = matrix.m[4 ]; + m[5 ] = matrix.m[5 ]; + m[6 ] = matrix.m[6 ]; + m[7 ] = matrix.m[7 ]; + m[8 ] = matrix.m[8 ]; + m[9 ] = matrix.m[9 ]; + m[10] = matrix.m[10]; + m[11] = matrix.m[11]; + m[12] = matrix.m[12]; + m[13] = matrix.m[13]; + m[14] = matrix.m[14]; + m[15] = matrix.m[15]; + } + + GenoMatrix(GenoMatrix<4, 4, T> && matrix) noexcept : + owner(matrix.owner), + m(matrix.m) { + matrix.owner = false; + } + + GenoMatrix<4, 4, T> & operator=(const GenoMatrix<4, 4, T> & matrix) { + m[0 ] = matrix.m[0 ]; + m[1 ] = matrix.m[1 ]; + m[2 ] = matrix.m[2 ]; + m[3 ] = matrix.m[3 ]; + m[4 ] = matrix.m[4 ]; + m[5 ] = matrix.m[5 ]; + m[6 ] = matrix.m[6 ]; + m[7 ] = matrix.m[7 ]; + m[8 ] = matrix.m[8 ]; + m[9 ] = matrix.m[9 ]; + m[10] = matrix.m[10]; + m[11] = matrix.m[11]; + m[12] = matrix.m[12]; + m[13] = matrix.m[13]; + m[14] = matrix.m[14]; + m[15] = matrix.m[15]; + return *this; + } + + GenoMatrix<4, 4, T> & operator=(GenoMatrix<4, 4, T> && matrix) noexcept { + clean(); + owner = matrix.owner; + m = matrix.m; + matrix.owner = false; + return *this; + } + + GenoMatrix<4, 4, T> & operator+=(const GenoMatrix<4, 4, T> & matrix) { + m[0 ] += matrix.m[0 ]; + m[1 ] += matrix.m[1 ]; + m[2 ] += matrix.m[2 ]; + m[3 ] += matrix.m[3 ]; + m[4 ] += matrix.m[4 ]; + m[5 ] += matrix.m[5 ]; + m[6 ] += matrix.m[6 ]; + m[7 ] += matrix.m[7 ]; + m[8 ] += matrix.m[8 ]; + m[9 ] += matrix.m[9 ]; + m[10] += matrix.m[10]; + m[11] += matrix.m[11]; + m[12] += matrix.m[12]; + m[13] += matrix.m[13]; + m[14] += matrix.m[14]; + m[15] += matrix.m[15]; + return *this; + } + + GenoMatrix<4, 4, T> & operator-=(const GenoMatrix<4, 4, T> & matrix) { + m[0 ] -= matrix.m[0 ]; + m[1 ] -= matrix.m[1 ]; + m[2 ] -= matrix.m[2 ]; + m[3 ] -= matrix.m[3 ]; + m[4 ] -= matrix.m[4 ]; + m[5 ] -= matrix.m[5 ]; + m[6 ] -= matrix.m[6 ]; + m[7 ] -= matrix.m[7 ]; + m[8 ] -= matrix.m[8 ]; + m[9 ] -= matrix.m[9 ]; + m[10] -= matrix.m[10]; + m[11] -= matrix.m[11]; + m[12] -= matrix.m[12]; + m[13] -= matrix.m[13]; + m[14] -= matrix.m[14]; + m[15] -= matrix.m[15]; + return *this; + } + + GenoMatrix<4, 4, T> & operator*=(const GenoMatrix<4, 4, T> & matrix) { + return *this = *this * matrix; + } + + GenoVector<4, T> operator[](uint32 index) const noexcept { + return GenoVector<4, T>(index * 4, false); + } + + GenoMatrix<4, 4, T> & setIdentity() { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setOrthographic(T left, T right, T bottom, T top, T near, T far) { + m[0 ] = 2 / (right - left); + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 2 / (top - bottom); + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 2 / (far - near); + m[11] = 0; + m[12] = (left + right) / (left - right); + m[13] = (bottom + top) / (bottom - top); + m[14] = (near + far) / (near - far); + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setPerspective(T fovY, T aspectRatio, T near, T far) { + auto vertical = 1 / tan(fovY / 2); + m[0 ] = vertical / aspectRatio; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = vertical; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = (near + far) / (near - far); + m[11] = -1; + m[12] = 0; + m[13] = 0; + m[14] = (2 * far * near) / (near - far); + m[15] = 0; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2D(T axisAngle, T shearAngle) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = tan(shearAngle); + m[0 ] = sinAxis * tanShear * cosAxis; + m[1 ] = -cosAxis * tanShear * cosAxis; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = sinAxis * tanShear * sinAxis; + m[5 ] = -cosAxis * tanShear * sinAxis; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2D(const GenoVector<2, T> & axis, T shearAngle) { + auto unitAxis = normalize(axis); + auto tanShear = tan(shearAngle); + m[0 ] = unitAxis.v[1] * tanShear * unitAxis.v[0]; + m[1 ] = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = unitAxis.v[1] * tanShear * unitAxis.v[1]; + m[5 ] = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2D(T axisAngle, const GenoVector<2, T> & shear) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = shear.v[1] / shear.v[0]; + m[0 ] = sinAxis * tanShear * cosAxis; + m[1 ] = -cosAxis * tanShear * cosAxis; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = sinAxis * tanShear * sinAxis; + m[5 ] = -cosAxis * tanShear * sinAxis; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2D(const GenoVector<2, T> & axis, const GenoVector<2, T> & shear) { + auto unitAxis = normalize(axis); + auto tanShear = shear.v[1] / shear.v[0]; + m[0 ] = unitAxis.v[1] * tanShear * unitAxis.v[0]; + m[1 ] = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = unitAxis.v[1] * tanShear * unitAxis.v[1]; + m[5 ] = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2DX(T angle) { + m[0 ] = 1; + m[1 ] = -tan(angle); + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2DX(const GenoVector<2, T> & shear) { + m[0 ] = 1; + m[1 ] = -shear.v[1] / shear.v[0]; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2DY(T angle) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = tan(angle); + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setShear2DY(const GenoVector<2, T> & shear) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = shear.v[1] / shear.v[0]; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslate2D(T translateX, T translateY) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translateX; + m[13] = translateY; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslate2D(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[0]; + m[13] = translate.v[1]; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslate(T translateX, T translateY, T translateZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translateX; + m[13] = translateY; + m[14] = translateZ; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslate(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[0]; + m[13] = translate.v[1]; + m[14] = translate.v[2]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotate2D(T rotation) { + auto sinZ = sin(rotation); + auto cosZ = cos(rotation); + m[0 ] = cosZ; + m[1 ] = sinZ; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = -sinZ; + m[5 ] = cosZ; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScale2D(T scale) { + m[0 ] = scale; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScale2D(T scaleX, T scaleY) { + m[0 ] = scaleX; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scaleY; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScale2D(const GenoVector<2, T> & scale) { + m[0 ] = scale.v[0]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScale(T scale) { + m[0 ] = scale; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScale(T scaleX, T scaleY, T scaleZ) { + m[0 ] = scaleX; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scaleY; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scaleZ; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScale(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[0]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[2]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateX(T translateX) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translateX; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateY(T translateY) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = translateY; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateZ(T translateZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = translateZ; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXY(T translateX, T translateY) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translateX; + m[13] = translateY; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXY(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[0]; + m[13] = translate.v[1]; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXZ(T translateX, T translateZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translateX; + m[13] = 0; + m[14] = translateZ; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXZ(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[0]; + m[13] = 0; + m[14] = translate.v[1]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateYX(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[1]; + m[13] = translate.v[0]; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateYZ(T translateY, T translateZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = translateY; + m[14] = translateZ; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateYZ(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = translate.v[0]; + m[14] = translate.v[1]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateZX(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[1]; + m[13] = 0; + m[14] = translate.v[0]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateZY(const GenoVector<2, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = translate.v[1]; + m[14] = translate.v[0]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXYZ(T translateX, T translateY, T translateZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translateX; + m[13] = translateY; + m[14] = translateZ; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXYZ(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[0]; + m[13] = translate.v[1]; + m[14] = translate.v[2]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateXZY(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[0]; + m[13] = translate.v[2]; + m[14] = translate.v[1]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateYXZ(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[1]; + m[13] = translate.v[0]; + m[14] = translate.v[2]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateYZX(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[2]; + m[13] = translate.v[0]; + m[14] = translate.v[1]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateZXY(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[1]; + m[13] = translate.v[2]; + m[14] = translate.v[0]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setTranslateZYX(const GenoVector<3, T> & translate) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = translate.v[2]; + m[13] = translate.v[1]; + m[14] = translate.v[0]; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateX(T rotateX) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = cosX; + m[6 ] = sinX; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = -sinX; + m[10] = cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateY(T rotateY) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + m[0 ] = cosY; + m[1 ] = 0; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = sinY; + m[9 ] = 0; + m[10] = cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateZ(T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + m[0 ] = cosZ; + m[1 ] = sinZ; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = -sinZ; + m[5 ] = cosZ; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXY(T rotateX, T rotateY) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + m[0 ] = cosY; + m[1 ] = 0; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = sinY * sinX; + m[5 ] = cosX; + m[6 ] = cosY * sinX; + m[7 ] = 0; + m[8 ] = sinY * cosX; + m[9 ] = -sinX; + m[10] = cosY * cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXY(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + m[0 ] = cosY; + m[1 ] = 0; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = sinY * sinX; + m[5 ] = cosX; + m[6 ] = cosY * sinX; + m[7 ] = 0; + m[8 ] = sinY * cosX; + m[9 ] = -sinX; + m[10] = cosY * cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXZ(T rotateX, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + m[0 ] = cosZ; + m[1 ] = sinZ; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = -sinZ * cosX; + m[5 ] = cosZ * cosX; + m[6 ] = sinX; + m[7 ] = 0; + m[8 ] = sinZ * sinX; + m[9 ] = -cosZ * sinX; + m[10] = cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXZ(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + m[0 ] = cosZ; + m[1 ] = sinZ; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = -sinZ * cosX; + m[5 ] = cosZ * cosX; + m[6 ] = sinX; + m[7 ] = 0; + m[8 ] = sinZ * sinX; + m[9 ] = -cosZ * sinX; + m[10] = cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateYX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + m[0 ] = cosY; + m[1 ] = sinX * sinY; + m[2 ] = -cosX * sinY; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = cosX; + m[6 ] = sinX; + m[7 ] = 0; + m[8 ] = sinY; + m[9 ] = -sinX * cosY; + m[10] = cosX * cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateYZ(T rotateY, T rotateZ) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + m[0 ] = cosZ * cosY; + m[1 ] = sinZ * cosY; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = -sinZ; + m[5 ] = cosZ; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = cosZ * sinY; + m[9 ] = sinZ * sinY; + m[10] = cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateYZ(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + m[0 ] = cosZ * cosY; + m[1 ] = sinZ * cosY; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = -sinZ; + m[5 ] = cosZ; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = cosZ * sinY; + m[9 ] = sinZ * sinY; + m[10] = cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateZX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + m[0 ] = cosZ; + m[1 ] = cosX * sinZ; + m[2 ] = sinX * sinZ; + m[3 ] = 0; + m[4 ] = -sinZ; + m[5 ] = cosX * cosZ; + m[6 ] = sinX * cosZ; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = -sinX; + m[10] = cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateZY(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + m[0 ] = cosY * cosZ; + m[1 ] = sinZ; + m[2 ] = -sinY * cosZ; + m[3 ] = 0; + m[4 ] = -cosY * sinZ; + m[5 ] = cosZ; + m[6 ] = sinY * sinZ; + m[7 ] = 0; + m[8 ] = sinY; + m[9 ] = 0; + m[10] = cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXYZ(T rotateX, T rotateY, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + m[0 ] = cosZ * cosY; + m[1 ] = sinZ * cosY; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = -sinZ * cosX + cosZ * sinY * sinX; + m[5 ] = cosZ * cosX + sinZ * sinY * sinX; + m[6 ] = cosY * sinX; + m[7 ] = 0; + m[8 ] = sinZ * sinX + cosZ * sinY * cosX; + m[9 ] = -cosZ * sinX + sinZ * sinY * cosX; + m[10] = cosY * cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXYZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + m[0 ] = cosZ * cosY; + m[1 ] = sinZ * cosY; + m[2 ] = -sinY; + m[3 ] = 0; + m[4 ] = -sinZ * cosX + cosZ * sinY * sinX; + m[5 ] = cosZ * cosX + sinZ * sinY * sinX; + m[6 ] = cosY * sinX; + m[7 ] = 0; + m[8 ] = sinZ * sinX + cosZ * sinY * cosX; + m[9 ] = -cosZ * sinX + sinZ * sinY * cosX; + m[10] = cosY * cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateXZY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + m[0 ] = cosY * cosZ; + m[1 ] = sinZ; + m[2 ] = -sinY * cosZ; + m[3 ] = 0; + m[4 ] = -cosY * sinZ * cosX + sinY * sinX; + m[5 ] = cosZ * cosX; + m[6 ] = sinY * sinZ * cosX + cosY * sinX; + m[7 ] = 0; + m[8 ] = cosY * sinZ * sinX + sinY * cosX; + m[9 ] = -cosZ * sinX; + m[10] = -sinY * sinZ * sinX + cosY * cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateYXZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + m[0 ] = cosZ * cosY - sinZ * sinX * sinY; + m[1 ] = sinZ * cosY + cosZ * sinX * sinY; + m[2 ] = -cosX * sinY; + m[3 ] = 0; + m[4 ] = -sinZ * cosX; + m[5 ] = cosZ * cosX; + m[6 ] = sinX; + m[7 ] = 0; + m[8 ] = cosZ * sinY + sinZ * sinX * cosY; + m[9 ] = sinZ * sinY - cosZ * sinX * cosY; + m[10] = cosX * cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateYZX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + m[0 ] = cosZ * cosY; + m[1 ] = cosX * sinZ * cosY + sinX * sinY; + m[2 ] = sinX * sinZ * cosY - cosX * sinY; + m[3 ] = 0; + m[4 ] = -sinZ; + m[5 ] = cosX * cosZ; + m[6 ] = sinX * cosZ; + m[7 ] = 0; + m[8 ] = cosZ * sinY; + m[9 ] = cosX * sinZ * sinY - sinX * cosY; + m[10] = sinX * sinZ * sinY + cosX * cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateZXY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + m[0 ] = cosY * cosZ + sinY * sinX * sinZ; + m[1 ] = cosX * sinZ; + m[2 ] = -sinY * cosZ + cosY * sinX * sinZ; + m[3 ] = 0; + m[4 ] = -cosY * sinZ + sinY * sinX * cosZ; + m[5 ] = cosX * cosZ; + m[6 ] = sinY * sinZ + cosY * sinX * cosZ; + m[7 ] = 0; + m[8 ] = sinY * cosX; + m[9 ] = -sinX; + m[10] = cosY * cosX; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setRotateZYX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + m[0 ] = cosY * cosZ; + m[1 ] = sinX * sinY * cosZ + cosX * sinZ; + m[2 ] = -cosX * sinY * cosZ + sinX * sinZ; + m[3 ] = 0; + m[4 ] = -cosY * sinZ; + m[5 ] = -sinX * sinY * sinZ + cosX * cosZ; + m[6 ] = cosX * sinY * sinZ + sinX * cosZ; + m[7 ] = 0; + m[8 ] = sinY; + m[9 ] = -sinX * cosY; + m[10] = cosX * cosY; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleX(T scaleX) { + m[0 ] = scaleX; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleY(T scaleY) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scaleY; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleZ(T scaleZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scaleZ; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXY(T scale) { + m[0 ] = scale; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXY(T scaleX, T scaleY) { + m[0 ] = scaleX; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scaleY; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXY(const GenoVector<2, T> & scale) { + m[0 ] = scale.v[0]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXZ(T scale) { + m[0 ] = scale; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXZ(T scaleX, T scaleZ) { + m[0 ] = scaleX; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scaleZ; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXZ(const GenoVector<2, T> & scale) { + m[0 ] = scale.v[0]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[1]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleYX(const GenoVector<2, T> & scale) { + m[0 ] = scale.v[1]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[0]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = 1; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleYZ(T scale) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleYZ(T scaleY, T scaleZ) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scaleY; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scaleZ; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleYZ(const GenoVector<2, T> & scale) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[0]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[1]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleZX(const GenoVector<2, T> & scale) { + m[0 ] = scale.v[1]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = 1; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[0]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleZY(const GenoVector<2, T> & scale) { + m[0 ] = 1; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[0]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXYZ(T scale) { + m[0 ] = scale; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXYZ(T scaleX, T scaleY, T scaleZ) { + m[0 ] = scaleX; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scaleY; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scaleZ; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXYZ(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[0]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[2]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleXZY(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[0]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[2]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[1]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleYXZ(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[1]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[0]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[2]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleYZX(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[2]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[0]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[1]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleZXY(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[1]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[2]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[0]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & setScaleZYX(const GenoVector<3, T> & scale) { + m[0 ] = scale.v[2]; + m[1 ] = 0; + m[2 ] = 0; + m[3 ] = 0; + m[4 ] = 0; + m[5 ] = scale.v[1]; + m[6 ] = 0; + m[7 ] = 0; + m[8 ] = 0; + m[9 ] = 0; + m[10] = scale.v[0]; + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return *this; + } + + GenoMatrix<4, 4, T> & projectOrthographic(T left, T right, T bottom, T top, T near, T far) { + auto m0 = 2 / (right - left); + auto m5 = 2 / (top - bottom); + auto m10 = 2 / (far - near); + auto m12 = (left + right) / (left - right); + auto m13 = (bottom + top) / (bottom - top); + auto m14 = (near + far) / (near - far); + T newM[] = { + m[0] * m0, + m[1] * m0, + m[2] * m0, + m[3] * m0, + m[4] * m5, + m[5] * m5, + m[6] * m5, + m[7] * m5, + m[8] * m10, + m[9] * m10, + m[10] * m10, + m[11] * m10, + m[0] * m12 + m[4] * m13 + m[8] * m14 + m[12], + m[1] * m12 + m[5] * m13 + m[9] * m14 + m[13], + m[2] * m12 + m[6] * m13 + m[10] * m14 + m[14], + m[3] * m12 + m[7] * m13 + m[11] * m14 + m[15] + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + m[12] = newM[12]; m[13] = newM[13]; m[14] = newM[14]; m[15] = newM[15]; + return *this; + } + + GenoMatrix<4, 4, T> & projectPerspective(T fovY, T aspectRatio, T near, T far) { + auto vertical = 1 / tan(fovY / 2); + auto m0 = vertical / aspectRatio; + auto m10 = (near + far) / (near - far); + auto m14 = (2 * far * near) / (near - far); + T newM[] = { + m[0] * m0, + m[1] * m0, + m[2] * m0, + m[3] * m0, + m[4] * vertical, + m[5] * vertical, + m[6] * vertical, + m[7] * vertical, + m[8] * m10 - m[12], + m[9] * m10 - m[13], + m[10] * m10 - m[14], + m[11] * m10 - m[15], + m[8] * m14, + m[9] * m14, + m[10] * m14, + m[11] * m14 + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + m[12] = newM[12]; m[13] = newM[13]; m[14] = newM[14]; m[15] = newM[15]; + return *this; + } + + GenoMatrix<4, 4, T> & shear2D(T axisAngle, T shearAngle) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = tan(shearAngle); + auto m0 = sinAxis * tanShear * cosAxis; + auto m1 = -cosAxis * tanShear * cosAxis; + auto m4 = sinAxis * tanShear * sinAxis; + auto m5 = -cosAxis * tanShear * sinAxis; + T newM[] = { + m[0] * m0 + m[4] * m1, + m[1] * m0 + m[5] * m1, + m[2] * m0 + m[6] * m1, + m[3] * m0 + m[7] * m1, + m[0] * m4 + m[4] * m5, + m[1] * m4 + m[5] * m5, + m[2] * m4 + m[6] * m5, + m[3] * m4 + m[7] * m5, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2D(const GenoVector<2, T> & axis, T shearAngle) { + auto unitAxis = normalize(axis); + auto tanShear = tan(shearAngle); + auto m0 = unitAxis.v[1] * tanShear * unitAxis.v[0]; + auto m1 = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + auto m4 = unitAxis.v[1] * tanShear * unitAxis.v[1]; + auto m5 = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + T newM[] = { + m[0] * m0 + m[4] * m1, + m[1] * m0 + m[5] * m1, + m[2] * m0 + m[6] * m1, + m[3] * m0 + m[7] * m1, + m[0] * m4 + m[4] * m5, + m[1] * m4 + m[5] * m5, + m[2] * m4 + m[6] * m5, + m[3] * m4 + m[7] * m5, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2D(T axisAngle,const GenoVector<2, T> & shear) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = shear.v[1] / shear.v[0]; + auto m0 = sinAxis * tanShear * cosAxis; + auto m1 = -cosAxis * tanShear * cosAxis; + auto m4 = sinAxis * tanShear * sinAxis; + auto m5 = -cosAxis * tanShear * sinAxis; + T newM[] = { + m[0] * m0 + m[4] * m1, + m[1] * m0 + m[5] * m1, + m[2] * m0 + m[6] * m1, + m[3] * m0 + m[7] * m1, + m[0] * m4 + m[4] * m5, + m[1] * m4 + m[5] * m5, + m[2] * m4 + m[6] * m5, + m[3] * m4 + m[7] * m5, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2D(const GenoVector<2, T> & axis, const GenoVector<2, T> & shear) { + auto unitAxis = normalize(axis); + auto tanShear = shear.v[1] / shear.v[0]; + auto m0 = unitAxis.v[1] * tanShear * unitAxis.v[0]; + auto m1 = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + auto m4 = unitAxis.v[1] * tanShear * unitAxis.v[1]; + auto m5 = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + T newM[] = { + m[0] * m0 + m[4] * m1, + m[1] * m0 + m[5] * m1, + m[2] * m0 + m[6] * m1, + m[3] * m0 + m[7] * m1, + m[0] * m4 + m[4] * m5, + m[1] * m4 + m[5] * m5, + m[2] * m4 + m[6] * m5, + m[3] * m4 + m[7] * m5, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2DX(T angle) { + auto m1 = -tan(angle); + T newM[] = { + m[0] + m[4] * m1, + m[1] + m[5] * m1, + m[2] + m[6] * m1, + m[3] + m[7] * m1, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2DX(const GenoVector<2, T> & shear) { + auto m1 = -shear.v[1] / shear.v[0]; + T newM[] = { + m[0] + m[4] * m1, + m[1] + m[5] * m1, + m[2] + m[6] * m1, + m[3] + m[7] * m1, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2DY(T angle) { + auto m4 = tan(angle); + T newM[] = { + m[0] * m4 + m[4], + m[1] * m4 + m[5], + m[2] * m4 + m[6], + m[3] * m4 + m[7], + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & shear2DY(const GenoVector<2, T> & shear) { + auto m4 = shear.v[1] / shear.v[0]; + T newM[] = { + m[0] * m4 + m[4], + m[1] * m4 + m[5], + m[2] * m4 + m[6], + m[3] * m4 + m[7], + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & translate2D(T translateX, T translateY) { + T newM[] = { + m[0] * translateX + m[4] * translateY + m[12], + m[1] * translateX + m[5] * translateY + m[13], + m[2] * translateX + m[6] * translateY + m[14], + m[3] * translateX + m[7] * translateY + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translate2D(const GenoVector<2, T> & translate) { + T newM[] = { + m[0] * translate.v[0] + m[4] * translate.v[1] + m[12], + m[1] * translate.v[0] + m[5] * translate.v[1] + m[13], + m[2] * translate.v[0] + m[6] * translate.v[1] + m[14], + m[3] * translate.v[0] + m[7] * translate.v[1] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translate(T translateX, T translateY, T translateZ) { + T newM[] = { + m[0] * translateX + m[4] * translateY + m[8] * translateZ + m[12], + m[1] * translateX + m[5] * translateY + m[9] * translateZ + m[13], + m[2] * translateX + m[6] * translateY + m[10] * translateZ + m[14], + m[3] * translateX + m[7] * translateY + m[11] * translateZ + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translate(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[0] + m[4] * translate.v[1] + m[8] * translate.v[2] + m[12], + m[1] * translate.v[0] + m[5] * translate.v[1] + m[9] * translate.v[2] + m[13], + m[2] * translate.v[0] + m[6] * translate.v[1] + m[10] * translate.v[2] + m[14], + m[3] * translate.v[0] + m[7] * translate.v[1] + m[11] * translate.v[2] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & rotate2D(T rotation) { + auto sinZ = sin(rotation); + auto cosZ = cos(rotation); + T newM[] = { + m[0] * cosZ + m[4] * sinZ, + m[1] * cosZ + m[5] * sinZ, + m[2] * cosZ + m[6] * sinZ, + m[3] * cosZ + m[7] * sinZ, + m[0] * -sinZ + m[4] * cosZ, + m[1] * -sinZ + m[5] * cosZ, + m[2] * -sinZ + m[6] * cosZ, + m[3] * -sinZ + m[7] * cosZ, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scale2D(T scale) { + T newM[] = { + m[0] * scale, + m[1] * scale, + m[2] * scale, + m[3] * scale, + m[4] * scale, + m[5] * scale, + m[6] * scale, + m[7] * scale, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scale2D(T scaleX, T scaleY) { + T newM[] = { + m[0] * scaleX, + m[1] * scaleX, + m[2] * scaleX, + m[3] * scaleX, + m[4] * scaleY, + m[5] * scaleY, + m[6] * scaleY, + m[7] * scaleY, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scale2D(const GenoVector<2, T> & scale) { + T newM[] = { + m[0] * scale.v[0], + m[1] * scale.v[0], + m[2] * scale.v[0], + m[3] * scale.v[0], + m[4] * scale.v[1], + m[5] * scale.v[1], + m[6] * scale.v[1], + m[7] * scale.v[1], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scale(T scale) { + T newM[] = { + m[0] * scale, + m[1] * scale, + m[2] * scale, + m[3] * scale, + m[4] * scale, + m[5] * scale, + m[6] * scale, + m[7] * scale, + m[8] * scale, + m[9] * scale, + m[10] * scale, + m[11] * scale, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scale(T scaleX, T scaleY, T scaleZ) { + T newM[] = { + m[0] * scaleX, + m[1] * scaleX, + m[2] * scaleX, + m[3] * scaleX, + m[4] * scaleY, + m[5] * scaleY, + m[6] * scaleY, + m[7] * scaleY, + m[8] * scaleZ, + m[9] * scaleZ, + m[10] * scaleZ, + m[11] * scaleZ, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scale(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[0], + m[1] * scale.v[0], + m[2] * scale.v[0], + m[3] * scale.v[0], + m[4] * scale.v[1], + m[5] * scale.v[1], + m[6] * scale.v[1], + m[7] * scale.v[1], + m[8] * scale.v[2], + m[9] * scale.v[2], + m[10] * scale.v[2], + m[11] * scale.v[2], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & translateX(T translateX) { + T newM[] = { + m[0] * translateX + m[12], + m[1] * translateX + m[13], + m[2] * translateX + m[14], + m[3] * translateX + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateY(T translateY) { + T newM[] = { + m[4] * translateY + m[12], + m[5] * translateY + m[13], + m[6] * translateY + m[14], + m[7] * translateY + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateZ(T translateZ) { + T newM[] = { + m[8] * translateZ + m[12], + m[9] * translateZ + m[13], + m[10] * translateZ + m[14], + m[11] * translateZ + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXY(T translateX, T translateY) { + T newM[] = { + m[0] * translateX + m[4] * translateY + m[12], + m[1] * translateX + m[5] * translateY + m[13], + m[2] * translateX + m[6] * translateY + m[14], + m[3] * translateX + m[7] * translateY + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXY(const GenoVector<2, T> & translate) { + T newM[] = { + m[0] * translate.v[0] + m[4] * translate.v[1] + m[12], + m[1] * translate.v[0] + m[5] * translate.v[1] + m[13], + m[2] * translate.v[0] + m[6] * translate.v[1] + m[14], + m[3] * translate.v[0] + m[7] * translate.v[1] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXZ(T translateX, T translateZ) { + T newM[] = { + m[0] * translateX + m[8] * translateZ + m[12], + m[1] * translateX + m[9] * translateZ + m[13], + m[2] * translateX + m[10] * translateZ + m[14], + m[3] * translateX + m[11] * translateZ + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXZ(const GenoVector<2, T> & translate) { + T newM[] = { + m[0] * translate.v[0] + m[8] * translate.v[1] + m[12], + m[1] * translate.v[0] + m[9] * translate.v[1] + m[13], + m[2] * translate.v[0] + m[10] * translate.v[1] + m[14], + m[3] * translate.v[0] + m[11] * translate.v[1] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateYX(const GenoVector<2, T> & translate) { + T newM[] = { + m[0] * translate.v[1] + m[4] * translate.v[0] + m[12], + m[1] * translate.v[1] + m[5] * translate.v[0] + m[13], + m[2] * translate.v[1] + m[6] * translate.v[0] + m[14], + m[3] * translate.v[1] + m[7] * translate.v[0] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateYZ(T translateY, T translateZ) { + T newM[] = { + m[4] * translateY + m[8] * translateZ + m[12], + m[5] * translateY + m[9] * translateZ + m[13], + m[6] * translateY + m[10] * translateZ + m[14], + m[7] * translateY + m[11] * translateZ + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateYZ(const GenoVector<2, T> & translate) { + T newM[] = { + m[4] * translate.v[0] + m[8] * translate.v[1] + m[12], + m[5] * translate.v[0] + m[9] * translate.v[1] + m[13], + m[6] * translate.v[0] + m[10] * translate.v[1] + m[14], + m[7] * translate.v[0] + m[11] * translate.v[1] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateZX(const GenoVector<2, T> & translate) { + T newM[] = { + m[0] * translate.v[1] + m[8] * translate.v[0] + m[12], + m[1] * translate.v[1] + m[9] * translate.v[0] + m[13], + m[2] * translate.v[1] + m[10] * translate.v[0] + m[14], + m[3] * translate.v[1] + m[11] * translate.v[0] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateZY(const GenoVector<2, T> & translate) { + T newM[] = { + m[4] * translate.v[1] + m[8] * translate.v[0] + m[12], + m[5] * translate.v[1] + m[9] * translate.v[0] + m[13], + m[6] * translate.v[1] + m[10] * translate.v[0] + m[14], + m[7] * translate.v[1] + m[11] * translate.v[0] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXYZ(T translateX, T translateY, T translateZ) { + T newM[] = { + m[0] * translateX + m[4] * translateY + m[8] * translateZ + m[12], + m[1] * translateX + m[5] * translateY + m[9] * translateZ + m[13], + m[2] * translateX + m[6] * translateY + m[10] * translateZ + m[14], + m[3] * translateX + m[7] * translateY + m[11] * translateZ + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXYZ(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[0] + m[4] * translate.v[1] + m[8] * translate.v[2] + m[12], + m[1] * translate.v[0] + m[5] * translate.v[1] + m[9] * translate.v[2] + m[13], + m[2] * translate.v[0] + m[6] * translate.v[1] + m[10] * translate.v[2] + m[14], + m[3] * translate.v[0] + m[7] * translate.v[1] + m[11] * translate.v[2] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateXZY(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[0] + m[4] * translate.v[2] + m[8] * translate.v[1] + m[12], + m[1] * translate.v[0] + m[5] * translate.v[2] + m[9] * translate.v[1] + m[13], + m[2] * translate.v[0] + m[6] * translate.v[2] + m[10] * translate.v[1] + m[14], + m[3] * translate.v[0] + m[7] * translate.v[2] + m[11] * translate.v[1] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateYXZ(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[1] + m[4] * translate.v[0] + m[8] * translate.v[2] + m[12], + m[1] * translate.v[1] + m[5] * translate.v[0] + m[9] * translate.v[2] + m[13], + m[2] * translate.v[1] + m[6] * translate.v[0] + m[10] * translate.v[2] + m[14], + m[3] * translate.v[1] + m[7] * translate.v[0] + m[11] * translate.v[2] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateYZX(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[2] + m[4] * translate.v[0] + m[8] * translate.v[1] + m[12], + m[1] * translate.v[2] + m[5] * translate.v[0] + m[9] * translate.v[1] + m[13], + m[2] * translate.v[2] + m[6] * translate.v[0] + m[10] * translate.v[1] + m[14], + m[3] * translate.v[2] + m[7] * translate.v[0] + m[11] * translate.v[1] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateZXY(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[1] + m[4] * translate.v[2] + m[8] * translate.v[0] + m[12], + m[1] * translate.v[1] + m[5] * translate.v[2] + m[9] * translate.v[0] + m[13], + m[2] * translate.v[1] + m[6] * translate.v[2] + m[10] * translate.v[0] + m[14], + m[3] * translate.v[1] + m[7] * translate.v[2] + m[11] * translate.v[0] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & translateZYX(const GenoVector<3, T> & translate) { + T newM[] = { + m[0] * translate.v[2] + m[4] * translate.v[1] + m[8] * translate.v[0] + m[12], + m[1] * translate.v[2] + m[5] * translate.v[1] + m[9] * translate.v[0] + m[13], + m[2] * translate.v[2] + m[6] * translate.v[1] + m[10] * translate.v[0] + m[14], + m[3] * translate.v[2] + m[7] * translate.v[1] + m[11] * translate.v[0] + m[15] + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + m[12] = newM[0 ]; m[13] = newM[1 ]; m[14] = newM[2 ]; m[15] = newM[3 ]; + return *this; + } + + GenoMatrix<4, 4, T> & rotateX(T rotateX) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + T newM[] = { + m[4] * cosX + m[8] * sinX, + m[5] * cosX + m[9] * sinX, + m[6] * cosX + m[10] * sinX, + m[7] * cosX + m[11] * sinX, + m[4] * -sinX + m[8] * cosX, + m[5] * -sinX + m[9] * cosX, + m[6] * -sinX + m[10] * cosX, + m[7] * -sinX + m[11] * cosX, + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateY(T rotateY) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + T newM[] = { + m[0] * cosY + m[8] * -sinY, + m[1] * cosY + m[9] * -sinY, + m[2] * cosY + m[10] * -sinY, + m[3] * cosY + m[11] * -sinY, + m[0] * sinY + m[8] * cosY, + m[1] * sinY + m[9] * cosY, + m[2] * sinY + m[10] * cosY, + m[3] * sinY + m[11] * cosY, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateZ(T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + T newM[] = { + m[0] * cosZ + m[4] * sinZ, + m[1] * cosZ + m[5] * sinZ, + m[2] * cosZ + m[6] * sinZ, + m[3] * cosZ + m[7] * sinZ, + m[0] * -sinZ + m[4] * cosZ, + m[1] * -sinZ + m[5] * cosZ, + m[2] * -sinZ + m[6] * cosZ, + m[3] * -sinZ + m[7] * cosZ, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXY(T rotateX, T rotateY) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto m4 = sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + T newM[] = { + m[0] * cosY + m[8] * -sinY, + m[1] * cosY + m[9] * -sinY, + m[2] * cosY + m[10] * -sinY, + m[3] * cosY + m[11] * -sinY, + m[0] * m4 + m[4] * cosX + m[8] * m6, + m[1] * m4 + m[5] * cosX + m[9] * m6, + m[2] * m4 + m[6] * cosX + m[10] * m6, + m[3] * m4 + m[7] * cosX + m[11] * m6, + m[0] * m8 + m[4] * -sinX + m[8] * m10, + m[1] * m8 + m[5] * -sinX + m[9] * m10, + m[2] * m8 + m[6] * -sinX + m[10] * m10, + m[3] * m8 + m[7] * -sinX + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXY(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto m4 = sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + T newM[] = { + m[0] * cosY + m[8] * -sinY, + m[1] * cosY + m[9] * -sinY, + m[2] * cosY + m[10] * -sinY, + m[3] * cosY + m[11] * -sinY, + m[0] * m4 + m[4] * cosX + m[8] * m6, + m[1] * m4 + m[5] * cosX + m[9] * m6, + m[2] * m4 + m[6] * cosX + m[10] * m6, + m[3] * m4 + m[7] * cosX + m[11] * m6, + m[0] * m8 + m[4] * -sinX + m[8] * m10, + m[1] * m8 + m[5] * -sinX + m[9] * m10, + m[2] * m8 + m[6] * -sinX + m[10] * m10, + m[3] * m8 + m[7] * -sinX + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXZ(T rotateX, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = sinZ * sinX; + auto m9 = -cosZ * sinX; + T newM[] = { + m[0] * cosZ + m[4] * sinZ, + m[1] * cosZ + m[5] * sinZ, + m[2] * cosZ + m[6] * sinZ, + m[3] * cosZ + m[7] * sinZ, + m[0] * m4 + m[4] * m5 + m[8] * sinX, + m[1] * m4 + m[5] * m5 + m[9] * sinX, + m[2] * m4 + m[6] * m5 + m[10] * sinX, + m[3] * m4 + m[7] * m5 + m[11] * sinX, + m[0] * m8 + m[4] * m9 + m[8] * cosX, + m[1] * m8 + m[5] * m9 + m[9] * cosX, + m[2] * m8 + m[6] * m9 + m[10] * cosX, + m[3] * m8 + m[7] * m9 + m[11] * cosX, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXZ(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = sinZ * sinX; + auto m9 = -cosZ * sinX; + T newM[] = { + m[0] * cosZ + m[4] * sinZ, + m[1] * cosZ + m[5] * sinZ, + m[2] * cosZ + m[6] * sinZ, + m[3] * cosZ + m[7] * sinZ, + m[0] * m4 + m[4] * m5 + m[8] * sinX, + m[1] * m4 + m[5] * m5 + m[9] * sinX, + m[2] * m4 + m[6] * m5 + m[10] * sinX, + m[3] * m4 + m[7] * m5 + m[11] * sinX, + m[0] * m8 + m[4] * m9 + m[8] * cosX, + m[1] * m8 + m[5] * m9 + m[9] * cosX, + m[2] * m8 + m[6] * m9 + m[10] * cosX, + m[3] * m8 + m[7] * m9 + m[11] * cosX, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateYX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto m1 = sinX * sinY; + auto m2 = -cosX * sinY; + auto m9 = -sinX * cosY; + auto m10 = cosX * cosY; + T newM[] = { + m[0] * cosY + m[4] * m1 + m[8] * m2, + m[1] * cosY + m[5] * m1 + m[9] * m2, + m[2] * cosY + m[6] * m1 + m[10] * m2, + m[3] * cosY + m[7] * m1 + m[11] * m2, + m[4] * cosX + m[8] * sinX, + m[5] * cosX + m[9] * sinX, + m[6] * cosX + m[10] * sinX, + m[7] * cosX + m[11] * sinX, + m[0] * sinY + m[4] * m9 + m[8] * m10, + m[1] * sinY + m[5] * m9 + m[9] * m10, + m[2] * sinY + m[6] * m9 + m[10] * m10, + m[3] * sinY + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateYZ(T rotateY, T rotateZ) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m8 = cosZ * sinY; + auto m9 = sinZ * sinY; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * -sinY, + m[1] * m0 + m[5] * m1 + m[9] * -sinY, + m[2] * m0 + m[6] * m1 + m[10] * -sinY, + m[3] * m0 + m[7] * m1 + m[11] * -sinY, + m[0] * -sinZ + m[4] * cosZ, + m[1] * -sinZ + m[5] * cosZ, + m[2] * -sinZ + m[6] * cosZ, + m[3] * -sinZ + m[7] * cosZ, + m[0] * m8 + m[4] * m9 + m[8] * cosY, + m[1] * m8 + m[5] * m9 + m[9] * cosY, + m[2] * m8 + m[6] * m9 + m[10] * cosY, + m[3] * m8 + m[7] * m9 + m[11] * cosY, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateYZ(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m8 = cosZ * sinY; + auto m9 = sinZ * sinY; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * -sinY, + m[1] * m0 + m[5] * m1 + m[9] * -sinY, + m[2] * m0 + m[6] * m1 + m[10] * -sinY, + m[3] * m0 + m[7] * m1 + m[11] * -sinY, + m[0] * -sinZ + m[4] * cosZ, + m[1] * -sinZ + m[5] * cosZ, + m[2] * -sinZ + m[6] * cosZ, + m[3] * -sinZ + m[7] * cosZ, + m[0] * m8 + m[4] * m9 + m[8] * cosY, + m[1] * m8 + m[5] * m9 + m[9] * cosY, + m[2] * m8 + m[6] * m9 + m[10] * cosY, + m[3] * m8 + m[7] * m9 + m[11] * cosY, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateZX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m1 = cosX * sinZ; + auto m2 = sinX * sinZ; + auto m5 = cosX * cosZ; + auto m6 = sinX * cosZ; + T newM[] = { + m[0] * cosZ + m[4] * m1 + m[8] * m2, + m[1] * cosZ + m[5] * m1 + m[9] * m2, + m[2] * cosZ + m[6] * m1 + m[10] * m2, + m[3] * cosZ + m[7] * m1 + m[11] * m2, + m[0] * -sinZ + m[4] * m5 + m[8] * m6, + m[1] * -sinZ + m[5] * m5 + m[9] * m6, + m[2] * -sinZ + m[6] * m5 + m[10] * m6, + m[3] * -sinZ + m[7] * m5 + m[11] * m6, + m[4] * -sinX + m[8] * cosX, + m[5] * -sinX + m[9] * cosX, + m[6] * -sinX + m[10] * cosX, + m[7] * -sinX + m[11] * cosX, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateZY(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ; + auto m2 = -sinY * cosZ; + auto m4 = -cosY * sinZ; + auto m6 = sinY * sinZ; + T newM[] = { + m[0] * m0 + m[4] * sinZ + m[8] * m2, + m[1] * m0 + m[5] * sinZ + m[9] * m2, + m[2] * m0 + m[6] * sinZ + m[10] * m2, + m[3] * m0 + m[7] * sinZ + m[11] * m2, + m[0] * m4 + m[4] * cosZ + m[8] * m6, + m[1] * m4 + m[5] * cosZ + m[9] * m6, + m[2] * m4 + m[6] * cosZ + m[10] * m6, + m[3] * m4 + m[7] * cosZ + m[11] * m6, + m[0] * sinY + m[8] * cosY, + m[1] * sinY + m[9] * cosY, + m[2] * sinY + m[10] * cosY, + m[3] * sinY + m[11] * cosY, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXYZ(T rotateX, T rotateY, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m4 = -sinZ * cosX + cosZ * sinY * sinX; + auto m5 = cosZ * cosX + sinZ * sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinZ * sinX + cosZ * sinY * cosX; + auto m9 = -cosZ * sinX + sinZ * sinY * cosX; + auto m10 = cosY * cosX; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * -sinY, + m[1] * m0 + m[5] * m1 + m[9] * -sinY, + m[2] * m0 + m[6] * m1 + m[10] * -sinY, + m[3] * m0 + m[7] * m1 + m[11] * -sinY, + m[0] * m4 + m[4] * m5 + m[8] * m6, + m[1] * m4 + m[5] * m5 + m[9] * m6, + m[2] * m4 + m[6] * m5 + m[10] * m6, + m[3] * m4 + m[7] * m5 + m[11] * m6, + m[0] * m8 + m[4] * m9 + m[8] * m10, + m[1] * m8 + m[5] * m9 + m[9] * m10, + m[2] * m8 + m[6] * m9 + m[10] * m10, + m[3] * m8 + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXYZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m4 = -sinZ * cosX + cosZ * sinY * sinX; + auto m5 = cosZ * cosX + sinZ * sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinZ * sinX + cosZ * sinY * cosX; + auto m9 = -cosZ * sinX + sinZ * sinY * cosX; + auto m10 = cosY * cosX; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * -sinY, + m[1] * m0 + m[5] * m1 + m[9] * -sinY, + m[2] * m0 + m[6] * m1 + m[10] * -sinY, + m[3] * m0 + m[7] * m1 + m[11] * -sinY, + m[0] * m4 + m[4] * m5 + m[8] * m6, + m[1] * m4 + m[5] * m5 + m[9] * m6, + m[2] * m4 + m[6] * m5 + m[10] * m6, + m[3] * m4 + m[7] * m5 + m[11] * m6, + m[0] * m8 + m[4] * m9 + m[8] * m10, + m[1] * m8 + m[5] * m9 + m[9] * m10, + m[2] * m8 + m[6] * m9 + m[10] * m10, + m[3] * m8 + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateXZY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosY * cosZ; + auto m2 = -sinY * cosZ; + auto m4 = -cosY * sinZ * cosX + sinY * sinX; + auto m5 = cosZ * cosX; + auto m6 = sinY * sinZ * cosX + cosY * sinX; + auto m8 = cosY * sinZ * sinX + sinY * cosX; + auto m9 = -cosZ * sinX; + auto m10 = -sinY * sinZ * sinX + cosY * cosX; + T newM[] = { + m[0] * m0 + m[4] * sinZ + m[8] * m2, + m[1] * m0 + m[5] * sinZ + m[9] * m2, + m[2] * m0 + m[6] * sinZ + m[10] * m2, + m[3] * m0 + m[7] * sinZ + m[11] * m2, + m[0] * m4 + m[4] * m5 + m[8] * m6, + m[1] * m4 + m[5] * m5 + m[9] * m6, + m[2] * m4 + m[6] * m5 + m[10] * m6, + m[3] * m4 + m[7] * m5 + m[11] * m6, + m[0] * m8 + m[4] * m9 + m[8] * m10, + m[1] * m8 + m[5] * m9 + m[9] * m10, + m[2] * m8 + m[6] * m9 + m[10] * m10, + m[3] * m8 + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateYXZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto m0 = cosZ * cosY - sinZ * sinX * sinY; + auto m1 = sinZ * cosY + cosZ * sinX * sinY; + auto m2 = -cosX * sinY; + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = cosZ * sinY + sinZ * sinX * cosY; + auto m9 = sinZ * sinY - cosZ * sinX * cosY; + auto m10 = cosX * cosY; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * m2, + m[1] * m0 + m[5] * m1 + m[9] * m2, + m[2] * m0 + m[6] * m1 + m[10] * m2, + m[3] * m0 + m[7] * m1 + m[11] * m2, + m[0] * m4 + m[4] * m5 + m[8] * sinX, + m[1] * m4 + m[5] * m5 + m[9] * sinX, + m[2] * m4 + m[6] * m5 + m[10] * sinX, + m[3] * m4 + m[7] * m5 + m[11] * sinX, + m[0] * m8 + m[4] * m9 + m[8] * m10, + m[1] * m8 + m[5] * m9 + m[9] * m10, + m[2] * m8 + m[6] * m9 + m[10] * m10, + m[3] * m8 + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateYZX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosZ * cosY; + auto m1 = cosX * sinZ * cosY + sinX * sinY; + auto m2 = sinX * sinZ * cosY - cosX * sinY; + auto m5 = cosX * cosZ; + auto m6 = sinX * cosZ; + auto m8 = cosZ * sinY; + auto m9 = cosX * sinZ * sinY - sinX * cosY; + auto m10 = sinX * sinZ * sinY + cosX * cosY; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * m2, + m[1] * m0 + m[5] * m1 + m[9] * m2, + m[2] * m0 + m[6] * m1 + m[10] * m2, + m[3] * m0 + m[7] * m1 + m[11] * m2, + m[0] * -sinZ + m[4] * m5 + m[8] * m6, + m[1] * -sinZ + m[5] * m5 + m[9] * m6, + m[2] * -sinZ + m[6] * m5 + m[10] * m6, + m[3] * -sinZ + m[7] * m5 + m[11] * m6, + m[0] * m8 + m[4] * m9 + m[8] * m10, + m[1] * m8 + m[5] * m9 + m[9] * m10, + m[2] * m8 + m[6] * m9 + m[10] * m10, + m[3] * m8 + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateZXY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ + sinY * sinX * sinZ; + auto m1 = cosX * sinZ; + auto m2 = -sinY * cosZ + cosY * sinX * sinZ; + auto m4 = -cosY * sinZ + sinY * sinX * cosZ; + auto m5 = cosX * cosZ; + auto m6 = sinY * sinZ + cosY * sinX * cosZ; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * m2, + m[1] * m0 + m[5] * m1 + m[9] * m2, + m[2] * m0 + m[6] * m1 + m[10] * m2, + m[3] * m0 + m[7] * m1 + m[11] * m2, + m[0] * m4 + m[4] * m5 + m[8] * m6, + m[1] * m4 + m[5] * m5 + m[9] * m6, + m[2] * m4 + m[6] * m5 + m[10] * m6, + m[3] * m4 + m[7] * m5 + m[11] * m6, + m[0] * m8 + m[4] * -sinX + m[8] * m10, + m[1] * m8 + m[5] * -sinX + m[9] * m10, + m[2] * m8 + m[6] * -sinX + m[10] * m10, + m[3] * m8 + m[7] * -sinX + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & rotateZYX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ; + auto m1 = sinX * sinY * cosZ + cosX * sinZ; + auto m2 = -cosX * sinY * cosZ + sinX * sinZ; + auto m4 = -cosY * sinZ; + auto m5 = -sinX * sinY * sinZ + cosX * cosZ; + auto m6 = cosX * sinY * sinZ + sinX * cosZ; + auto m9 = -sinX * cosY; + auto m10 = cosX * cosY; + T newM[] = { + m[0] * m0 + m[4] * m1 + m[8] * m2, + m[1] * m0 + m[5] * m1 + m[9] * m2, + m[2] * m0 + m[6] * m1 + m[10] * m2, + m[3] * m0 + m[7] * m1 + m[11] * m2, + m[0] * m4 + m[4] * m5 + m[8] * m6, + m[1] * m4 + m[5] * m5 + m[9] * m6, + m[2] * m4 + m[6] * m5 + m[10] * m6, + m[3] * m4 + m[7] * m5 + m[11] * m6, + m[0] * sinY + m[4] * m9 + m[8] * m10, + m[1] * sinY + m[5] * m9 + m[9] * m10, + m[2] * sinY + m[6] * m9 + m[10] * m10, + m[3] * sinY + m[7] * m9 + m[11] * m10, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleX(T scaleX) { + T newM[] = { + m[0] * scaleX, + m[1] * scaleX, + m[2] * scaleX, + m[3] * scaleX, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleY(T scaleY) { + T newM[] = { + m[4] * scaleY, + m[5] * scaleY, + m[6] * scaleY, + m[7] * scaleY, + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleZ(T scaleZ) { + T newM[] = { + m[8] * scaleZ, + m[9] * scaleZ, + m[10] * scaleZ, + m[11] * scaleZ, + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + m[8 ] = newM[0 ]; m[9 ] = newM[1 ]; m[10] = newM[2 ]; m[11] = newM[3 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXY(T scale) { + T newM[] = { + m[0] * scale, + m[1] * scale, + m[2] * scale, + m[3] * scale, + m[4] * scale, + m[5] * scale, + m[6] * scale, + m[7] * scale, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXY(T scaleX, T scaleY) { + T newM[] = { + m[0] * scaleX, + m[1] * scaleX, + m[2] * scaleX, + m[3] * scaleX, + m[4] * scaleY, + m[5] * scaleY, + m[6] * scaleY, + m[7] * scaleY, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXY(const GenoVector<2, T> & scale) { + T newM[] = { + m[0] * scale.v[0], + m[1] * scale.v[0], + m[2] * scale.v[0], + m[3] * scale.v[0], + m[4] * scale.v[1], + m[5] * scale.v[1], + m[6] * scale.v[1], + m[7] * scale.v[1], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXZ(T scale) { + T newM[] = { + m[0] * scale, + m[1] * scale, + m[2] * scale, + m[3] * scale, + m[8] * scale, + m[9] * scale, + m[10] * scale, + m[11] * scale, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXZ(T scaleX, T scaleZ) { + T newM[] = { + m[0] * scaleX, + m[1] * scaleX, + m[2] * scaleX, + m[3] * scaleX, + m[8] * scaleZ, + m[9] * scaleZ, + m[10] * scaleZ, + m[11] * scaleZ, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXZ(const GenoVector<2, T> & scale) { + T newM[] = { + m[0] * scale.v[0], + m[1] * scale.v[0], + m[2] * scale.v[0], + m[3] * scale.v[0], + m[8] * scale.v[1], + m[9] * scale.v[1], + m[10] * scale.v[1], + m[11] * scale.v[1], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleYX(const GenoVector<2, T> & scale) { + T newM[] = { + m[0] * scale.v[1], + m[1] * scale.v[1], + m[2] * scale.v[1], + m[3] * scale.v[1], + m[4] * scale.v[0], + m[5] * scale.v[0], + m[6] * scale.v[0], + m[7] * scale.v[0], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + /**** m[8 ] ****/ /**** m[9 ] ****/ /**** m[10] ****/ /**** m[11] ****/ + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleYZ(T scale) { + T newM[] = { + m[4] * scale, + m[5] * scale, + m[6] * scale, + m[7] * scale, + m[8] * scale, + m[9] * scale, + m[10] * scale, + m[11] * scale, + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleYZ(T scaleY, T scaleZ) { + T newM[] = { + m[4] * scaleY, + m[5] * scaleY, + m[6] * scaleY, + m[7] * scaleY, + m[8] * scaleZ, + m[9] * scaleZ, + m[10] * scaleZ, + m[11] * scaleZ, + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleYZ(const GenoVector<2, T> & scale) { + T newM[] = { + m[4] * scale.v[0], + m[5] * scale.v[0], + m[6] * scale.v[0], + m[7] * scale.v[0], + m[8] * scale.v[1], + m[9] * scale.v[1], + m[10] * scale.v[1], + m[11] * scale.v[1], + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleZX(const GenoVector<2, T> & scale) { + T newM[] = { + m[0] * scale.v[1], + m[1] * scale.v[1], + m[2] * scale.v[1], + m[3] * scale.v[1], + m[8] * scale.v[0], + m[9] * scale.v[0], + m[10] * scale.v[0], + m[11] * scale.v[0], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + /**** m[4 ] ****/ /**** m[5 ] ****/ /**** m[6 ] ****/ /**** m[7 ] ****/ + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleZY(const GenoVector<2, T> & scale) { + T newM[] = { + m[4] * scale.v[1], + m[5] * scale.v[1], + m[6] * scale.v[1], + m[7] * scale.v[1], + m[8] * scale.v[0], + m[9] * scale.v[0], + m[10] * scale.v[0], + m[11] * scale.v[0], + }; + /**** m[0 ] ****/ /**** m[1 ] ****/ /**** m[2 ] ****/ /**** m[3 ] ****/ + m[4 ] = newM[0 ]; m[5 ] = newM[1 ]; m[6 ] = newM[2 ]; m[7 ] = newM[3 ]; + m[8 ] = newM[4 ]; m[9 ] = newM[5 ]; m[10] = newM[6 ]; m[11] = newM[7 ]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXYZ(T scale) { + T newM[] = { + m[0] * scale, + m[1] * scale, + m[2] * scale, + m[3] * scale, + m[4] * scale, + m[5] * scale, + m[6] * scale, + m[7] * scale, + m[8] * scale, + m[9] * scale, + m[10] * scale, + m[11] * scale, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXYZ(T scaleX, T scaleY, T scaleZ) { + T newM[] = { + m[0] * scaleX, + m[1] * scaleX, + m[2] * scaleX, + m[3] * scaleX, + m[4] * scaleY, + m[5] * scaleY, + m[6] * scaleY, + m[7] * scaleY, + m[8] * scaleZ, + m[9] * scaleZ, + m[10] * scaleZ, + m[11] * scaleZ, + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXYZ(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[0], + m[1] * scale.v[0], + m[2] * scale.v[0], + m[3] * scale.v[0], + m[4] * scale.v[1], + m[5] * scale.v[1], + m[6] * scale.v[1], + m[7] * scale.v[1], + m[8] * scale.v[2], + m[9] * scale.v[2], + m[10] * scale.v[2], + m[11] * scale.v[2], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleXZY(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[0], + m[1] * scale.v[0], + m[2] * scale.v[0], + m[3] * scale.v[0], + m[4] * scale.v[2], + m[5] * scale.v[2], + m[6] * scale.v[2], + m[7] * scale.v[2], + m[8] * scale.v[1], + m[9] * scale.v[1], + m[10] * scale.v[1], + m[11] * scale.v[1], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleYXZ(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[1], + m[1] * scale.v[1], + m[2] * scale.v[1], + m[3] * scale.v[1], + m[4] * scale.v[0], + m[5] * scale.v[0], + m[6] * scale.v[0], + m[7] * scale.v[0], + m[8] * scale.v[2], + m[9] * scale.v[2], + m[10] * scale.v[2], + m[11] * scale.v[2], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleYZX(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[2], + m[1] * scale.v[2], + m[2] * scale.v[2], + m[3] * scale.v[2], + m[4] * scale.v[0], + m[5] * scale.v[0], + m[6] * scale.v[0], + m[7] * scale.v[0], + m[8] * scale.v[1], + m[9] * scale.v[1], + m[10] * scale.v[1], + m[11] * scale.v[1], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleZXY(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[1], + m[1] * scale.v[1], + m[2] * scale.v[1], + m[3] * scale.v[1], + m[4] * scale.v[2], + m[5] * scale.v[2], + m[6] * scale.v[2], + m[7] * scale.v[2], + m[8] * scale.v[0], + m[9] * scale.v[0], + m[10] * scale.v[0], + m[11] * scale.v[0], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + GenoMatrix<4, 4, T> & scaleZYX(const GenoVector<3, T> & scale) { + T newM[] = { + m[0] * scale.v[2], + m[1] * scale.v[2], + m[2] * scale.v[2], + m[3] * scale.v[2], + m[4] * scale.v[1], + m[5] * scale.v[1], + m[6] * scale.v[1], + m[7] * scale.v[1], + m[8] * scale.v[0], + m[9] * scale.v[0], + m[10] * scale.v[0], + m[11] * scale.v[0], + }; + m[0 ] = newM[0 ]; m[1 ] = newM[1 ]; m[2 ] = newM[2 ]; m[3 ] = newM[3 ]; + m[4 ] = newM[4 ]; m[5 ] = newM[5 ]; m[6 ] = newM[6 ]; m[7 ] = newM[7 ]; + m[8 ] = newM[8 ]; m[9 ] = newM[9 ]; m[10] = newM[10]; m[11] = newM[11]; + /**** m[12] ****/ /**** m[13] ****/ /**** m[14] ****/ /**** m[15] ****/ + return *this; + } + + ~GenoMatrix() { + clean(); + } +}; + +template +GenoMatrix<4, 4, T> operator+(const GenoMatrix<4, 4, T> & left, const GenoMatrix<4, 4, T> & right) { + return new T[4 * 4] { + left.m[0 ] + right.m[0 ], left.m[1 ] + right.m[1 ], left.m[2 ] + right.m[2 ], left.m[3 ] + right.m[3 ], + left.m[4 ] + right.m[4 ], left.m[5 ] + right.m[5 ], left.m[6 ] + right.m[6 ], left.m[7 ] + right.m[7 ], + left.m[8 ] + right.m[8 ], left.m[9 ] + right.m[9 ], left.m[10] + right.m[10], left.m[11] + right.m[11], + left.m[12] + right.m[12], left.m[13] + right.m[13], left.m[14] + right.m[14], left.m[15] + right.m[15] + }; +} + +template +GenoMatrix<4, 4, T> operator-(const GenoMatrix<4, 4, T> & left, const GenoMatrix<4, 4, T> & right) { + return new T[4 * 4] { + left.m[0 ] - right.m[0 ], left.m[1 ] - right.m[1 ], left.m[2 ] - right.m[2 ], left.m[3 ] - right.m[3 ], + left.m[4 ] - right.m[4 ], left.m[5 ] - right.m[5 ], left.m[6 ] - right.m[6 ], left.m[7 ] - right.m[7 ], + left.m[8 ] - right.m[8 ], left.m[9 ] - right.m[9 ], left.m[10] - right.m[10], left.m[11] - right.m[11], + left.m[12] - right.m[12], left.m[13] - right.m[13], left.m[14] - right.m[14], left.m[15] - right.m[15] + }; +} + +template +GenoMatrix<4, 4, T> operator*(const GenoMatrix<4, 4, T> & left, const GenoMatrix<4, 4, T> & right) { + return new T[4 * 4] { + left.m[0] * right.m[0 ] + left.m[4] * right.m[1 ] + left.m[8 ] * right.m[2 ] + left.m[12] * right.m[3 ], + left.m[1] * right.m[0 ] + left.m[5] * right.m[1 ] + left.m[9 ] * right.m[2 ] + left.m[13] * right.m[3 ], + left.m[2] * right.m[0 ] + left.m[6] * right.m[1 ] + left.m[10] * right.m[2 ] + left.m[14] * right.m[3 ], + left.m[3] * right.m[0 ] + left.m[7] * right.m[1 ] + left.m[11] * right.m[2 ] + left.m[15] * right.m[3 ], + left.m[0] * right.m[4 ] + left.m[4] * right.m[5 ] + left.m[8 ] * right.m[6 ] + left.m[12] * right.m[7 ], + left.m[1] * right.m[4 ] + left.m[5] * right.m[5 ] + left.m[9 ] * right.m[6 ] + left.m[13] * right.m[7 ], + left.m[2] * right.m[4 ] + left.m[6] * right.m[5 ] + left.m[10] * right.m[6 ] + left.m[14] * right.m[7 ], + left.m[3] * right.m[4 ] + left.m[7] * right.m[5 ] + left.m[11] * right.m[6 ] + left.m[15] * right.m[7 ], + left.m[0] * right.m[8 ] + left.m[4] * right.m[9 ] + left.m[8 ] * right.m[10] + left.m[12] * right.m[11], + left.m[1] * right.m[8 ] + left.m[5] * right.m[9 ] + left.m[9 ] * right.m[10] + left.m[13] * right.m[11], + left.m[2] * right.m[8 ] + left.m[6] * right.m[9 ] + left.m[10] * right.m[10] + left.m[14] * right.m[11], + left.m[3] * right.m[8 ] + left.m[7] * right.m[9 ] + left.m[11] * right.m[10] + left.m[15] * right.m[11], + left.m[0] * right.m[12] + left.m[4] * right.m[13] + left.m[8 ] * right.m[14] + left.m[12] * right.m[15], + left.m[1] * right.m[12] + left.m[5] * right.m[13] + left.m[9 ] * right.m[14] + left.m[13] * right.m[15], + left.m[2] * right.m[12] + left.m[6] * right.m[13] + left.m[10] * right.m[14] + left.m[14] * right.m[15], + left.m[3] * right.m[12] + left.m[7] * right.m[13] + left.m[11] * right.m[14] + left.m[15] * right.m[15] + }; +} + +template +GenoMatrix<4, 4, T> projectOrthographic(const GenoMatrix<4, 4, T> & matrix, T left, T right, T bottom, T top, T near, T far) { + auto m0 = 2 / (right - left); + auto m5 = 2 / (top - bottom); + auto m10 = 2 / (far - near); + auto m12 = (left + right) / (left - right); + auto m13 = (bottom + top) / (bottom - top); + auto m14 = (near + far) / (near - far); + return new T[4 * 4] { + matrix.m[0 ] * m0, + matrix.m[1 ] * m0, + matrix.m[2 ] * m0, + matrix.m[3 ] * m0, + matrix.m[4 ] * m5, + matrix.m[5 ] * m5, + matrix.m[6 ] * m5, + matrix.m[7 ] * m5, + matrix.m[8 ] * m10, + matrix.m[9 ] * m10, + matrix.m[10] * m10, + matrix.m[11] * m10, + matrix.m[0 ] * m12 + matrix.m[4] * m13 + matrix.m[8 ] * m14 + matrix.m[12], + matrix.m[1 ] * m12 + matrix.m[5] * m13 + matrix.m[9 ] * m14 + matrix.m[13], + matrix.m[2 ] * m12 + matrix.m[6] * m13 + matrix.m[10] * m14 + matrix.m[14], + matrix.m[3 ] * m12 + matrix.m[7] * m13 + matrix.m[11] * m14 + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & projectOrthographic(const GenoMatrix<4, 4, T> & matrix, T left, T right, T bottom, T top, T near, T far, GenoMatrix<4, 4, T> & target) { + auto m0 = 2 / (right - left); + auto m5 = 2 / (top - bottom); + auto m10 = 2 / (far - near); + auto m12 = (left + right) / (left - right); + auto m13 = (bottom + top) / (bottom - top); + auto m14 = (near + far) / (near - far); + target.m[0 ] = matrix.m[0 ] * m0; + target.m[1 ] = matrix.m[1 ] * m0; + target.m[2 ] = matrix.m[2 ] * m0; + target.m[3 ] = matrix.m[3 ] * m0; + target.m[4 ] = matrix.m[4 ] * m5; + target.m[5 ] = matrix.m[5 ] * m5; + target.m[6 ] = matrix.m[6 ] * m5; + target.m[7 ] = matrix.m[7 ] * m5; + target.m[8 ] = matrix.m[8 ] * m10; + target.m[9 ] = matrix.m[9 ] * m10; + target.m[10] = matrix.m[10] * m10; + target.m[11] = matrix.m[11] * m10; + target.m[12] = matrix.m[0 ] * m12 + matrix.m[4] * m13 + matrix.m[8 ] * m14 + matrix.m[12]; + target.m[13] = matrix.m[1 ] * m12 + matrix.m[5] * m13 + matrix.m[9 ] * m14 + matrix.m[13]; + target.m[14] = matrix.m[2 ] * m12 + matrix.m[6] * m13 + matrix.m[10] * m14 + matrix.m[14]; + target.m[15] = matrix.m[3 ] * m12 + matrix.m[7] * m13 + matrix.m[11] * m14 + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> projectPerspective(const GenoMatrix<4, 4, T> & matrix, T fovY, T aspectRatio, T near, T far) { + auto vertical = 1 / tan(fovY / 2); + auto m0 = vertical / aspectRatio; + auto m10 = (near + far) / (near - far); + auto m14 = (2 * far * near) / (near - far); + return new T[4 * 4] { + matrix.m[0 ] * m0, + matrix.m[1 ] * m0, + matrix.m[2 ] * m0, + matrix.m[3 ] * m0, + matrix.m[4 ] * vertical, + matrix.m[5 ] * vertical, + matrix.m[6 ] * vertical, + matrix.m[7 ] * vertical, + matrix.m[8 ] * m10 - matrix.m[12], + matrix.m[9 ] * m10 - matrix.m[13], + matrix.m[10] * m10 - matrix.m[14], + matrix.m[11] * m10 - matrix.m[15], + matrix.m[8 ] * m14, + matrix.m[9 ] * m14, + matrix.m[10] * m14, + matrix.m[11] * m14 + }; +} + +template +GenoMatrix<4, 4, T> & projectPerspective(const GenoMatrix<4, 4, T> & matrix, T fovY, T aspectRatio, T near, T far, GenoMatrix<4, 4, T> & target) { + auto vertical = 1 / tan(fovY / 2); + auto m0 = vertical / aspectRatio; + auto m10 = (near + far) / (near - far); + auto m14 = (2 * far * near) / (near - far); + target.m[0 ] = matrix.m[0 ] * m0; + target.m[1 ] = matrix.m[1 ] * m0; + target.m[2 ] = matrix.m[2 ] * m0; + target.m[3 ] = matrix.m[3 ] * m0; + target.m[4 ] = matrix.m[4 ] * vertical; + target.m[5 ] = matrix.m[5 ] * vertical; + target.m[6 ] = matrix.m[6 ] * vertical; + target.m[7 ] = matrix.m[7 ] * vertical; + target.m[8 ] = matrix.m[8 ] * m10 - matrix.m[12]; + target.m[9 ] = matrix.m[9 ] * m10 - matrix.m[13]; + target.m[10] = matrix.m[10] * m10 - matrix.m[14]; + target.m[11] = matrix.m[11] * m10 - matrix.m[15]; + target.m[12] = matrix.m[8 ] * m14; + target.m[13] = matrix.m[9 ] * m14; + target.m[14] = matrix.m[10] * m14; + target.m[15] = matrix.m[11] * m14; + return target; +} + +template +GenoMatrix<4, 4, T> shear2D(const GenoMatrix<4, 4, T> & matrix, T axisAngle, T shearAngle) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = tan(shearAngle); + auto m0 = sinAxis * tanShear * cosAxis; + auto m1 = -cosAxis * tanShear * cosAxis; + auto m4 = sinAxis * tanShear * sinAxis; + auto m5 = -cosAxis * tanShear * sinAxis; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1, + matrix.m[1] * m0 + matrix.m[5] * m1, + matrix.m[2] * m0 + matrix.m[6] * m1, + matrix.m[3] * m0 + matrix.m[7] * m1, + matrix.m[0] * m4 + matrix.m[4] * m5, + matrix.m[1] * m4 + matrix.m[5] * m5, + matrix.m[2] * m4 + matrix.m[6] * m5, + matrix.m[3] * m4 + matrix.m[7] * m5, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & axis, T shearAngle) { + auto unitAxis = normalize(axis); + auto tanShear = tan(shearAngle); + auto m0 = unitAxis.v[1] * tanShear * unitAxis.v[0]; + auto m1 = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + auto m4 = unitAxis.v[1] * tanShear * unitAxis.v[1]; + auto m5 = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1, + matrix.m[1] * m0 + matrix.m[5] * m1, + matrix.m[2] * m0 + matrix.m[6] * m1, + matrix.m[3] * m0 + matrix.m[7] * m1, + matrix.m[0] * m4 + matrix.m[4] * m5, + matrix.m[1] * m4 + matrix.m[5] * m5, + matrix.m[2] * m4 + matrix.m[6] * m5, + matrix.m[3] * m4 + matrix.m[7] * m5, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2D(const GenoMatrix<4, 4, T> & matrix, T axisAngle,const GenoVector<2, T> & shear) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = shear.v[1] / shear.v[0]; + auto m0 = sinAxis * tanShear * cosAxis; + auto m1 = -cosAxis * tanShear * cosAxis; + auto m4 = sinAxis * tanShear * sinAxis; + auto m5 = -cosAxis * tanShear * sinAxis; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1, + matrix.m[1] * m0 + matrix.m[5] * m1, + matrix.m[2] * m0 + matrix.m[6] * m1, + matrix.m[3] * m0 + matrix.m[7] * m1, + matrix.m[0] * m4 + matrix.m[4] * m5, + matrix.m[1] * m4 + matrix.m[5] * m5, + matrix.m[2] * m4 + matrix.m[6] * m5, + matrix.m[3] * m4 + matrix.m[7] * m5, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & axis, const GenoVector<2, T> & shear) { + auto unitAxis = normalize(axis); + auto tanShear = shear.v[1] / shear.v[0]; + auto m0 = unitAxis.v[1] * tanShear * unitAxis.v[0]; + auto m1 = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + auto m4 = unitAxis.v[1] * tanShear * unitAxis.v[1]; + auto m5 = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1, + matrix.m[1] * m0 + matrix.m[5] * m1, + matrix.m[2] * m0 + matrix.m[6] * m1, + matrix.m[3] * m0 + matrix.m[7] * m1, + matrix.m[0] * m4 + matrix.m[4] * m5, + matrix.m[1] * m4 + matrix.m[5] * m5, + matrix.m[2] * m4 + matrix.m[6] * m5, + matrix.m[3] * m4 + matrix.m[7] * m5, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2DX(const GenoMatrix<4, 4, T> & matrix, T angle) { + auto m1 = -tan(angle); + return new T[4 * 4] { + matrix.m[0] + matrix.m[4] * m1, + matrix.m[1] + matrix.m[5] * m1, + matrix.m[2] + matrix.m[6] * m1, + matrix.m[3] + matrix.m[7] * m1, + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2DX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & shear) { + auto m1 = -shear.v[1] / shear.v[0]; + return new T[4 * 4] { + matrix.m[0] + matrix.m[4] * m1, + matrix.m[1] + matrix.m[5] * m1, + matrix.m[2] + matrix.m[6] * m1, + matrix.m[3] + matrix.m[7] * m1, + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2DY(const GenoMatrix<4, 4, T> & matrix, T angle) { + auto m4 = tan(angle); + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[0] * m4 + matrix.m[4], + matrix.m[1] * m4 + matrix.m[5], + matrix.m[2] * m4 + matrix.m[6], + matrix.m[3] * m4 + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> shear2DY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & shear) { + auto m4 = shear.v[1] / shear.v[0]; + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[0] * m4 + matrix.m[4], + matrix.m[1] * m4 + matrix.m[5], + matrix.m[2] * m4 + matrix.m[6], + matrix.m[3] * m4 + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & shear2D(const GenoMatrix<4, 4, T> & matrix, T axisAngle, T shearAngle, GenoMatrix<4, 4, T> & target) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = tan(shearAngle); + auto m0 = sinAxis * tanShear * cosAxis; + auto m1 = -cosAxis * tanShear * cosAxis; + auto m4 = sinAxis * tanShear * sinAxis; + auto m5 = -cosAxis * tanShear * sinAxis; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & axis, T shearAngle, GenoMatrix<4, 4, T> & target) { + auto unitAxis = normalize(axis); + auto tanShear = tan(shearAngle); + auto m0 = unitAxis.v[1] * tanShear * unitAxis.v[0]; + auto m1 = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + auto m4 = unitAxis.v[1] * tanShear * unitAxis.v[1]; + auto m5 = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2D(const GenoMatrix<4, 4, T> & matrix, T axisAngle,const GenoVector<2, T> & shear, GenoMatrix<4, 4, T> & target) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto tanShear = shear.v[1] / shear.v[0]; + auto m0 = sinAxis * tanShear * cosAxis; + auto m1 = -cosAxis * tanShear * cosAxis; + auto m4 = sinAxis * tanShear * sinAxis; + auto m5 = -cosAxis * tanShear * sinAxis; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & axis, const GenoVector<2, T> & shear, GenoMatrix<4, 4, T> & target) { + auto unitAxis = normalize(axis); + auto tanShear = shear.v[1] / shear.v[0]; + auto m0 = unitAxis.v[1] * tanShear * unitAxis.v[0]; + auto m1 = -unitAxis.v[0] * tanShear * unitAxis.v[0]; + auto m4 = unitAxis.v[1] * tanShear * unitAxis.v[1]; + auto m5 = -unitAxis.v[0] * tanShear * unitAxis.v[1]; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2DX(const GenoMatrix<4, 4, T> & matrix, T angle, GenoMatrix<4, 4, T> & target) { + auto m1 = -tan(angle); + target.m[0] = matrix.m[0] + matrix.m[4] * m1; + target.m[1] = matrix.m[1] + matrix.m[5] * m1; + target.m[2] = matrix.m[2] + matrix.m[6] * m1; + target.m[3] = matrix.m[3] + matrix.m[7] * m1; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2DX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & shear, GenoMatrix<4, 4, T> & target) { + auto m1 = -shear.v[1] / shear.v[0]; + target.m[0] = matrix.m[0] + matrix.m[4] * m1; + target.m[1] = matrix.m[1] + matrix.m[5] * m1; + target.m[2] = matrix.m[2] + matrix.m[6] * m1; + target.m[3] = matrix.m[3] + matrix.m[7] * m1; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2DY(const GenoMatrix<4, 4, T> & matrix, T angle, GenoMatrix<4, 4, T> & target) { + auto m4 = tan(angle); + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[0] * m4 + matrix.m[4]; + target.m[5] = matrix.m[1] * m4 + matrix.m[5]; + target.m[6] = matrix.m[2] * m4 + matrix.m[6]; + target.m[7] = matrix.m[3] * m4 + matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & shear2DY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & shear, GenoMatrix<4, 4, T> & target) { + auto m4 = shear.v[1] / shear.v[0]; + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[0] * m4 + matrix.m[4]; + target.m[5] = matrix.m[1] * m4 + matrix.m[5]; + target.m[6] = matrix.m[2] * m4 + matrix.m[6]; + target.m[7] = matrix.m[3] * m4 + matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> translate2D(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[12], + matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[13], + matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[14], + matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translate2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[12], + matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[13], + matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[14], + matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & translate2D(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[12]; + target.m[13] = matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[13]; + target.m[14] = matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[14]; + target.m[15] = matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translate2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> translate(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY, T translateZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[8] * translateZ + matrix.m[12], + matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[9] * translateZ + matrix.m[13], + matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[10] * translateZ + matrix.m[14], + matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[11] * translateZ + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translate(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[2] + matrix.m[12], + matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[2] + matrix.m[13], + matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[2] + matrix.m[14], + matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[2] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & translate(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY, T translateZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[8] * translateZ + matrix.m[12]; + target.m[13] = matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[9] * translateZ + matrix.m[13]; + target.m[14] = matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[10] * translateZ + matrix.m[14]; + target.m[15] = matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[11] * translateZ + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translate(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[2] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[2] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[2] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[2] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> rotate2D(const GenoMatrix<4, 4, T> & matrix, T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return new T[4 * 4] { + matrix.m[0] * cosZ + matrix.m[4] * sinZ, + matrix.m[1] * cosZ + matrix.m[5] * sinZ, + matrix.m[2] * cosZ + matrix.m[6] * sinZ, + matrix.m[3] * cosZ + matrix.m[7] * sinZ, + matrix.m[0] * -sinZ + matrix.m[4] * cosZ, + matrix.m[1] * -sinZ + matrix.m[5] * cosZ, + matrix.m[2] * -sinZ + matrix.m[6] * cosZ, + matrix.m[3] * -sinZ + matrix.m[7] * cosZ, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotate2D(const GenoMatrix<4, 4, T> & matrix, T rotateZ, GenoMatrix<4, 4, T> & target) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + target.m[0] = matrix.m[0] * cosZ + matrix.m[4] * sinZ; + target.m[1] = matrix.m[1] * cosZ + matrix.m[5] * sinZ; + target.m[2] = matrix.m[2] * cosZ + matrix.m[6] * sinZ; + target.m[3] = matrix.m[3] * cosZ + matrix.m[7] * sinZ; + target.m[4] = matrix.m[0] * -sinZ + matrix.m[4] * cosZ; + target.m[5] = matrix.m[1] * -sinZ + matrix.m[5] * cosZ; + target.m[6] = matrix.m[2] * -sinZ + matrix.m[6] * cosZ; + target.m[7] = matrix.m[3] * -sinZ + matrix.m[7] * cosZ; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> scale2D(const GenoMatrix<4, 4, T> & matrix, T scale) { + return new T[4 * 4] { + matrix.m[0] * scale, + matrix.m[1] * scale, + matrix.m[2] * scale, + matrix.m[3] * scale, + matrix.m[4] * scale, + matrix.m[5] * scale, + matrix.m[6] * scale, + matrix.m[7] * scale, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scale2D(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY) { + return new T[4 * 4] { + matrix.m[0] * scaleX, + matrix.m[1] * scaleX, + matrix.m[2] * scaleX, + matrix.m[3] * scaleX, + matrix.m[4] * scaleY, + matrix.m[5] * scaleY, + matrix.m[6] * scaleY, + matrix.m[7] * scaleY, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scale2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[0], + matrix.m[1] * scale.v[0], + matrix.m[2] * scale.v[0], + matrix.m[3] * scale.v[0], + matrix.m[4] * scale.v[1], + matrix.m[5] * scale.v[1], + matrix.m[6] * scale.v[1], + matrix.m[7] * scale.v[1], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & scale2D(const GenoMatrix<4, 4, T> & matrix, T scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale; + target.m[1] = matrix.m[1] * scale; + target.m[2] = matrix.m[2] * scale; + target.m[3] = matrix.m[3] * scale; + target.m[4] = matrix.m[4] * scale; + target.m[5] = matrix.m[5] * scale; + target.m[6] = matrix.m[6] * scale; + target.m[7] = matrix.m[7] * scale; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scale2D(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scaleX; + target.m[1] = matrix.m[1] * scaleX; + target.m[2] = matrix.m[2] * scaleX; + target.m[3] = matrix.m[3] * scaleX; + target.m[4] = matrix.m[4] * scaleY; + target.m[5] = matrix.m[5] * scaleY; + target.m[6] = matrix.m[6] * scaleY; + target.m[7] = matrix.m[7] * scaleY; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scale2D(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[0]; + target.m[1] = matrix.m[1] * scale.v[0]; + target.m[2] = matrix.m[2] * scale.v[0]; + target.m[3] = matrix.m[3] * scale.v[0]; + target.m[4] = matrix.m[4] * scale.v[1]; + target.m[5] = matrix.m[5] * scale.v[1]; + target.m[6] = matrix.m[6] * scale.v[1]; + target.m[7] = matrix.m[7] * scale.v[1]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> scale(const GenoMatrix<4, 4, T> & matrix, T scale) { + return new T[4 * 4] { + matrix.m[0] * scale, + matrix.m[1] * scale, + matrix.m[2] * scale, + matrix.m[3] * scale, + matrix.m[4] * scale, + matrix.m[5] * scale, + matrix.m[6] * scale, + matrix.m[7] * scale, + matrix.m[8] * scale, + matrix.m[9] * scale, + matrix.m[10] * scale, + matrix.m[11] * scale, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scale(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY, T scaleZ) { + return new T[4 * 4] { + matrix.m[0] * scaleX, + matrix.m[1] * scaleX, + matrix.m[2] * scaleX, + matrix.m[3] * scaleX, + matrix.m[4] * scaleY, + matrix.m[5] * scaleY, + matrix.m[6] * scaleY, + matrix.m[7] * scaleY, + matrix.m[8] * scaleZ, + matrix.m[9] * scaleZ, + matrix.m[10] * scaleZ, + matrix.m[11] * scaleZ, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scale(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[0], + matrix.m[1] * scale.v[0], + matrix.m[2] * scale.v[0], + matrix.m[3] * scale.v[0], + matrix.m[4] * scale.v[1], + matrix.m[5] * scale.v[1], + matrix.m[6] * scale.v[1], + matrix.m[7] * scale.v[1], + matrix.m[8] * scale.v[2], + matrix.m[9] * scale.v[2], + matrix.m[10] * scale.v[2], + matrix.m[11] * scale.v[2], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & scale(const GenoMatrix<4, 4, T> & matrix, T scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale; + target.m[1] = matrix.m[1] * scale; + target.m[2] = matrix.m[2] * scale; + target.m[3] = matrix.m[3] * scale; + target.m[4] = matrix.m[4] * scale; + target.m[5] = matrix.m[5] * scale; + target.m[6] = matrix.m[6] * scale; + target.m[7] = matrix.m[7] * scale; + target.m[8] = matrix.m[8] * scale; + target.m[9] = matrix.m[9] * scale; + target.m[10] = matrix.m[10] * scale; + target.m[11] = matrix.m[11] * scale; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scale(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY, T scaleZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scaleX; + target.m[1] = matrix.m[1] * scaleX; + target.m[2] = matrix.m[2] * scaleX; + target.m[3] = matrix.m[3] * scaleX; + target.m[4] = matrix.m[4] * scaleY; + target.m[5] = matrix.m[5] * scaleY; + target.m[6] = matrix.m[6] * scaleY; + target.m[7] = matrix.m[7] * scaleY; + target.m[8] = matrix.m[8] * scaleZ; + target.m[9] = matrix.m[9] * scaleZ; + target.m[10] = matrix.m[10] * scaleZ; + target.m[11] = matrix.m[11] * scaleZ; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scale(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[0]; + target.m[1] = matrix.m[1] * scale.v[0]; + target.m[2] = matrix.m[2] * scale.v[0]; + target.m[3] = matrix.m[3] * scale.v[0]; + target.m[4] = matrix.m[4] * scale.v[1]; + target.m[5] = matrix.m[5] * scale.v[1]; + target.m[6] = matrix.m[6] * scale.v[1]; + target.m[7] = matrix.m[7] * scale.v[1]; + target.m[8] = matrix.m[8] * scale.v[2]; + target.m[9] = matrix.m[9] * scale.v[2]; + target.m[10] = matrix.m[10] * scale.v[2]; + target.m[11] = matrix.m[11] * scale.v[2]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> translateX(const GenoMatrix<4, 4, T> & matrix, T translateX) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translateX + matrix.m[12], + matrix.m[1] * translateX + matrix.m[13], + matrix.m[2] * translateX + matrix.m[14], + matrix.m[3] * translateX + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateY(const GenoMatrix<4, 4, T> & matrix, T translateY) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[4] * translateY + matrix.m[12], + matrix.m[5] * translateY + matrix.m[13], + matrix.m[6] * translateY + matrix.m[14], + matrix.m[7] * translateY + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateZ(const GenoMatrix<4, 4, T> & matrix, T translateZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[8] * translateZ + matrix.m[12], + matrix.m[9] * translateZ + matrix.m[13], + matrix.m[10] * translateZ + matrix.m[14], + matrix.m[11] * translateZ + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXY(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[12], + matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[13], + matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[14], + matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[12], + matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[13], + matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[14], + matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXZ(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translateX + matrix.m[8] * translateZ + matrix.m[12], + matrix.m[1] * translateX + matrix.m[9] * translateZ + matrix.m[13], + matrix.m[2] * translateX + matrix.m[10] * translateZ + matrix.m[14], + matrix.m[3] * translateX + matrix.m[11] * translateZ + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[0] + matrix.m[8] * translate.v[1] + matrix.m[12], + matrix.m[1] * translate.v[0] + matrix.m[9] * translate.v[1] + matrix.m[13], + matrix.m[2] * translate.v[0] + matrix.m[10] * translate.v[1] + matrix.m[14], + matrix.m[3] * translate.v[0] + matrix.m[11] * translate.v[1] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[1] + matrix.m[4] * translate.v[0] + matrix.m[12], + matrix.m[1] * translate.v[1] + matrix.m[5] * translate.v[0] + matrix.m[13], + matrix.m[2] * translate.v[1] + matrix.m[6] * translate.v[0] + matrix.m[14], + matrix.m[3] * translate.v[1] + matrix.m[7] * translate.v[0] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateYZ(const GenoMatrix<4, 4, T> & matrix, T translateY, T translateZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[4] * translateY + matrix.m[8] * translateZ + matrix.m[12], + matrix.m[5] * translateY + matrix.m[9] * translateZ + matrix.m[13], + matrix.m[6] * translateY + matrix.m[10] * translateZ + matrix.m[14], + matrix.m[7] * translateY + matrix.m[11] * translateZ + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[4] * translate.v[0] + matrix.m[8] * translate.v[1] + matrix.m[12], + matrix.m[5] * translate.v[0] + matrix.m[9] * translate.v[1] + matrix.m[13], + matrix.m[6] * translate.v[0] + matrix.m[10] * translate.v[1] + matrix.m[14], + matrix.m[7] * translate.v[0] + matrix.m[11] * translate.v[1] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[1] + matrix.m[8] * translate.v[0] + matrix.m[12], + matrix.m[1] * translate.v[1] + matrix.m[9] * translate.v[0] + matrix.m[13], + matrix.m[2] * translate.v[1] + matrix.m[10] * translate.v[0] + matrix.m[14], + matrix.m[3] * translate.v[1] + matrix.m[11] * translate.v[0] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[0] + matrix.m[12], + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[0] + matrix.m[13], + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[0] + matrix.m[14], + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[0] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXYZ(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY, T translateZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[8] * translateZ + matrix.m[12], + matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[9] * translateZ + matrix.m[13], + matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[10] * translateZ + matrix.m[14], + matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[11] * translateZ + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[2] + matrix.m[12], + matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[2] + matrix.m[13], + matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[2] + matrix.m[14], + matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[2] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateXZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[2] + matrix.m[8] * translate.v[1] + matrix.m[12], + matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[2] + matrix.m[9] * translate.v[1] + matrix.m[13], + matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[2] + matrix.m[10] * translate.v[1] + matrix.m[14], + matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[2] + matrix.m[11] * translate.v[1] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateYXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[1] + matrix.m[4] * translate.v[0] + matrix.m[8] * translate.v[2] + matrix.m[12], + matrix.m[1] * translate.v[1] + matrix.m[5] * translate.v[0] + matrix.m[9] * translate.v[2] + matrix.m[13], + matrix.m[2] * translate.v[1] + matrix.m[6] * translate.v[0] + matrix.m[10] * translate.v[2] + matrix.m[14], + matrix.m[3] * translate.v[1] + matrix.m[7] * translate.v[0] + matrix.m[11] * translate.v[2] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateYZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[2] + matrix.m[4] * translate.v[0] + matrix.m[8] * translate.v[1] + matrix.m[12], + matrix.m[1] * translate.v[2] + matrix.m[5] * translate.v[0] + matrix.m[9] * translate.v[1] + matrix.m[13], + matrix.m[2] * translate.v[2] + matrix.m[6] * translate.v[0] + matrix.m[10] * translate.v[1] + matrix.m[14], + matrix.m[3] * translate.v[2] + matrix.m[7] * translate.v[0] + matrix.m[11] * translate.v[1] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateZXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[1] + matrix.m[4] * translate.v[2] + matrix.m[8] * translate.v[0] + matrix.m[12], + matrix.m[1] * translate.v[1] + matrix.m[5] * translate.v[2] + matrix.m[9] * translate.v[0] + matrix.m[13], + matrix.m[2] * translate.v[1] + matrix.m[6] * translate.v[2] + matrix.m[10] * translate.v[0] + matrix.m[14], + matrix.m[3] * translate.v[1] + matrix.m[7] * translate.v[2] + matrix.m[11] * translate.v[0] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> translateZYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[0] * translate.v[2] + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[0] + matrix.m[12], + matrix.m[1] * translate.v[2] + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[0] + matrix.m[13], + matrix.m[2] * translate.v[2] + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[0] + matrix.m[14], + matrix.m[3] * translate.v[2] + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[0] + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & translateX(const GenoMatrix<4, 4, T> & matrix, T translateX, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translateX + matrix.m[12]; + target.m[13] = matrix.m[1] * translateX + matrix.m[13]; + target.m[14] = matrix.m[2] * translateX + matrix.m[14]; + target.m[15] = matrix.m[3] * translateX + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateY(const GenoMatrix<4, 4, T> & matrix, T translateY, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[4] * translateY + matrix.m[12]; + target.m[13] = matrix.m[5] * translateY + matrix.m[13]; + target.m[14] = matrix.m[6] * translateY + matrix.m[14]; + target.m[15] = matrix.m[7] * translateY + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateZ(const GenoMatrix<4, 4, T> & matrix, T translateZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[8] * translateZ + matrix.m[12]; + target.m[13] = matrix.m[9] * translateZ + matrix.m[13]; + target.m[14] = matrix.m[10] * translateZ + matrix.m[14]; + target.m[15] = matrix.m[11] * translateZ + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXY(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[12]; + target.m[13] = matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[13]; + target.m[14] = matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[14]; + target.m[15] = matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXZ(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translateX + matrix.m[8] * translateZ + matrix.m[12]; + target.m[13] = matrix.m[1] * translateX + matrix.m[9] * translateZ + matrix.m[13]; + target.m[14] = matrix.m[2] * translateX + matrix.m[10] * translateZ + matrix.m[14]; + target.m[15] = matrix.m[3] * translateX + matrix.m[11] * translateZ + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[0] + matrix.m[8] * translate.v[1] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[0] + matrix.m[9] * translate.v[1] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[0] + matrix.m[10] * translate.v[1] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[0] + matrix.m[11] * translate.v[1] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[1] + matrix.m[4] * translate.v[0] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[1] + matrix.m[5] * translate.v[0] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[1] + matrix.m[6] * translate.v[0] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[1] + matrix.m[7] * translate.v[0] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateYZ(const GenoMatrix<4, 4, T> & matrix, T translateY, T translateZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[4] * translateY + matrix.m[8] * translateZ + matrix.m[12]; + target.m[13] = matrix.m[5] * translateY + matrix.m[9] * translateZ + matrix.m[13]; + target.m[14] = matrix.m[6] * translateY + matrix.m[10] * translateZ + matrix.m[14]; + target.m[15] = matrix.m[7] * translateY + matrix.m[11] * translateZ + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[4] * translate.v[0] + matrix.m[8] * translate.v[1] + matrix.m[12]; + target.m[13] = matrix.m[5] * translate.v[0] + matrix.m[9] * translate.v[1] + matrix.m[13]; + target.m[14] = matrix.m[6] * translate.v[0] + matrix.m[10] * translate.v[1] + matrix.m[14]; + target.m[15] = matrix.m[7] * translate.v[0] + matrix.m[11] * translate.v[1] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[1] + matrix.m[8] * translate.v[0] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[1] + matrix.m[9] * translate.v[0] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[1] + matrix.m[10] * translate.v[0] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[1] + matrix.m[11] * translate.v[0] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[0] + matrix.m[12]; + target.m[13] = matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[0] + matrix.m[13]; + target.m[14] = matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[0] + matrix.m[14]; + target.m[15] = matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[0] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXYZ(const GenoMatrix<4, 4, T> & matrix, T translateX, T translateY, T translateZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translateX + matrix.m[4] * translateY + matrix.m[8] * translateZ + matrix.m[12]; + target.m[13] = matrix.m[1] * translateX + matrix.m[5] * translateY + matrix.m[9] * translateZ + matrix.m[13]; + target.m[14] = matrix.m[2] * translateX + matrix.m[6] * translateY + matrix.m[10] * translateZ + matrix.m[14]; + target.m[15] = matrix.m[3] * translateX + matrix.m[7] * translateY + matrix.m[11] * translateZ + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[2] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[2] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[2] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[2] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateXZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[0] + matrix.m[4] * translate.v[2] + matrix.m[8] * translate.v[1] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[0] + matrix.m[5] * translate.v[2] + matrix.m[9] * translate.v[1] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[0] + matrix.m[6] * translate.v[2] + matrix.m[10] * translate.v[1] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[0] + matrix.m[7] * translate.v[2] + matrix.m[11] * translate.v[1] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateYXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[1] + matrix.m[4] * translate.v[0] + matrix.m[8] * translate.v[2] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[1] + matrix.m[5] * translate.v[0] + matrix.m[9] * translate.v[2] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[1] + matrix.m[6] * translate.v[0] + matrix.m[10] * translate.v[2] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[1] + matrix.m[7] * translate.v[0] + matrix.m[11] * translate.v[2] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateYZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[2] + matrix.m[4] * translate.v[0] + matrix.m[8] * translate.v[1] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[2] + matrix.m[5] * translate.v[0] + matrix.m[9] * translate.v[1] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[2] + matrix.m[6] * translate.v[0] + matrix.m[10] * translate.v[1] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[2] + matrix.m[7] * translate.v[0] + matrix.m[11] * translate.v[1] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateZXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[1] + matrix.m[4] * translate.v[2] + matrix.m[8] * translate.v[0] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[1] + matrix.m[5] * translate.v[2] + matrix.m[9] * translate.v[0] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[1] + matrix.m[6] * translate.v[2] + matrix.m[10] * translate.v[0] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[1] + matrix.m[7] * translate.v[2] + matrix.m[11] * translate.v[0] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & translateZYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & translate, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[0] * translate.v[2] + matrix.m[4] * translate.v[1] + matrix.m[8] * translate.v[0] + matrix.m[12]; + target.m[13] = matrix.m[1] * translate.v[2] + matrix.m[5] * translate.v[1] + matrix.m[9] * translate.v[0] + matrix.m[13]; + target.m[14] = matrix.m[2] * translate.v[2] + matrix.m[6] * translate.v[1] + matrix.m[10] * translate.v[0] + matrix.m[14]; + target.m[15] = matrix.m[3] * translate.v[2] + matrix.m[7] * translate.v[1] + matrix.m[11] * translate.v[0] + matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> rotateX(const GenoMatrix<4, 4, T> & matrix, T rotateX) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4] * cosX + matrix.m[8] * sinX, + matrix.m[5] * cosX + matrix.m[9] * sinX, + matrix.m[6] * cosX + matrix.m[10] * sinX, + matrix.m[7] * cosX + matrix.m[11] * sinX, + matrix.m[4] * -sinX + matrix.m[8] * cosX, + matrix.m[5] * -sinX + matrix.m[9] * cosX, + matrix.m[6] * -sinX + matrix.m[10] * cosX, + matrix.m[7] * -sinX + matrix.m[11] * cosX, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> rotateY(const GenoMatrix<4, 4, T> & matrix, T rotateY) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + return new T[4 * 4] { + matrix.m[0] * cosY + matrix.m[8] * -sinY, + matrix.m[1] * cosY + matrix.m[9] * -sinY, + matrix.m[2] * cosY + matrix.m[10] * -sinY, + matrix.m[3] * cosY + matrix.m[11] * -sinY, + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[0] * sinY + matrix.m[8] * cosY, + matrix.m[1] * sinY + matrix.m[9] * cosY, + matrix.m[2] * sinY + matrix.m[10] * cosY, + matrix.m[3] * sinY + matrix.m[11] * cosY, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> rotateZ(const GenoMatrix<4, 4, T> & matrix, T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return new T[4 * 4] { + matrix.m[0] * cosZ + matrix.m[4] * sinZ, + matrix.m[1] * cosZ + matrix.m[5] * sinZ, + matrix.m[2] * cosZ + matrix.m[6] * sinZ, + matrix.m[3] * cosZ + matrix.m[7] * sinZ, + matrix.m[0] * -sinZ + matrix.m[4] * cosZ, + matrix.m[1] * -sinZ + matrix.m[5] * cosZ, + matrix.m[2] * -sinZ + matrix.m[6] * cosZ, + matrix.m[3] * -sinZ + matrix.m[7] * cosZ, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> rotateXY(const GenoMatrix<4, 4, T> & matrix, T rotateX, T rotateY) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto m4 = sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + return new T[4 * 4] { + matrix.m[0] * cosY + matrix.m[8] * -sinY, + matrix.m[1] * cosY + matrix.m[9] * -sinY, + matrix.m[2] * cosY + matrix.m[10] * -sinY, + matrix.m[3] * cosY + matrix.m[11] * -sinY, + matrix.m[0] * m4 + matrix.m[4] * cosX + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * cosX + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * cosX + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * cosX + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * -sinX + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * -sinX + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * -sinX + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * -sinX + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto m4 = sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + return new T[4 * 4] { + matrix.m[0] * cosY + matrix.m[8] * -sinY, + matrix.m[1] * cosY + matrix.m[9] * -sinY, + matrix.m[2] * cosY + matrix.m[10] * -sinY, + matrix.m[3] * cosY + matrix.m[11] * -sinY, + matrix.m[0] * m4 + matrix.m[4] * cosX + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * cosX + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * cosX + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * cosX + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * -sinX + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * -sinX + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * -sinX + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * -sinX + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> rotateXZ(const GenoMatrix<4, 4, T> & matrix, T rotateX, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = sinZ * sinX; + auto m9 = -cosZ * sinX; + return new T[4 * 4] { + matrix.m[0] * cosZ + matrix.m[4] * sinZ, + matrix.m[1] * cosZ + matrix.m[5] * sinZ, + matrix.m[2] * cosZ + matrix.m[6] * sinZ, + matrix.m[3] * cosZ + matrix.m[7] * sinZ, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * sinX, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * sinX, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * sinX, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * sinX, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosX, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosX, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosX, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosX, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = sinZ * sinX; + auto m9 = -cosZ * sinX; + return new T[4 * 4] { + matrix.m[0] * cosZ + matrix.m[4] * sinZ, + matrix.m[1] * cosZ + matrix.m[5] * sinZ, + matrix.m[2] * cosZ + matrix.m[6] * sinZ, + matrix.m[3] * cosZ + matrix.m[7] * sinZ, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * sinX, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * sinX, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * sinX, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * sinX, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosX, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosX, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosX, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosX, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto m1 = sinX * sinY; + auto m2 = -cosX * sinY; + auto m9 = -sinX * cosY; + auto m10 = cosX * cosY; + return new T[4 * 4] { + matrix.m[0] * cosY + matrix.m[4] * m1 + matrix.m[8] * m2, + matrix.m[1] * cosY + matrix.m[5] * m1 + matrix.m[9] * m2, + matrix.m[2] * cosY + matrix.m[6] * m1 + matrix.m[10] * m2, + matrix.m[3] * cosY + matrix.m[7] * m1 + matrix.m[11] * m2, + matrix.m[4] * cosX + matrix.m[8] * sinX, + matrix.m[5] * cosX + matrix.m[9] * sinX, + matrix.m[6] * cosX + matrix.m[10] * sinX, + matrix.m[7] * cosX + matrix.m[11] * sinX, + matrix.m[0] * sinY + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * sinY + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * sinY + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * sinY + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> rotateYZ(const GenoMatrix<4, 4, T> & matrix, T rotateY, T rotateZ) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m8 = cosZ * sinY; + auto m9 = sinZ * sinY; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY, + matrix.m[0] * -sinZ + matrix.m[4] * cosZ, + matrix.m[1] * -sinZ + matrix.m[5] * cosZ, + matrix.m[2] * -sinZ + matrix.m[6] * cosZ, + matrix.m[3] * -sinZ + matrix.m[7] * cosZ, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosY, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosY, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosY, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosY, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m8 = cosZ * sinY; + auto m9 = sinZ * sinY; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY, + matrix.m[0] * -sinZ + matrix.m[4] * cosZ, + matrix.m[1] * -sinZ + matrix.m[5] * cosZ, + matrix.m[2] * -sinZ + matrix.m[6] * cosZ, + matrix.m[3] * -sinZ + matrix.m[7] * cosZ, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosY, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosY, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosY, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosY, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m1 = cosX * sinZ; + auto m2 = sinX * sinZ; + auto m5 = cosX * cosZ; + auto m6 = sinX * cosZ; + return new T[4 * 4] { + matrix.m[0] * cosZ + matrix.m[4] * m1 + matrix.m[8] * m2, + matrix.m[1] * cosZ + matrix.m[5] * m1 + matrix.m[9] * m2, + matrix.m[2] * cosZ + matrix.m[6] * m1 + matrix.m[10] * m2, + matrix.m[3] * cosZ + matrix.m[7] * m1 + matrix.m[11] * m2, + matrix.m[0] * -sinZ + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * -sinZ + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * -sinZ + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * -sinZ + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[4] * -sinX + matrix.m[8] * cosX, + matrix.m[5] * -sinX + matrix.m[9] * cosX, + matrix.m[6] * -sinX + matrix.m[10] * cosX, + matrix.m[7] * -sinX + matrix.m[11] * cosX, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ; + auto m2 = -sinY * cosZ; + auto m4 = -cosY * sinZ; + auto m6 = sinY * sinZ; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * sinZ + matrix.m[8] * m2, + matrix.m[1] * m0 + matrix.m[5] * sinZ + matrix.m[9] * m2, + matrix.m[2] * m0 + matrix.m[6] * sinZ + matrix.m[10] * m2, + matrix.m[3] * m0 + matrix.m[7] * sinZ + matrix.m[11] * m2, + matrix.m[0] * m4 + matrix.m[4] * cosZ + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * cosZ + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * cosZ + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * cosZ + matrix.m[11] * m6, + matrix.m[0] * sinY + matrix.m[8] * cosY, + matrix.m[1] * sinY + matrix.m[9] * cosY, + matrix.m[2] * sinY + matrix.m[10] * cosY, + matrix.m[3] * sinY + matrix.m[11] * cosY, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> rotateXYZ(const GenoMatrix<4, 4, T> & matrix, T rotateX, T rotateY, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m4 = -sinZ * cosX + cosZ * sinY * sinX; + auto m5 = cosZ * cosX + sinZ * sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinZ * sinX + cosZ * sinY * cosX; + auto m9 = -cosZ * sinX + sinZ * sinY * cosX; + auto m10 = cosY * cosX; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateXYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m4 = -sinZ * cosX + cosZ * sinY * sinX; + auto m5 = cosZ * cosX + sinZ * sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinZ * sinX + cosZ * sinY * cosX; + auto m9 = -cosZ * sinX + sinZ * sinY * cosX; + auto m10 = cosY * cosX; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateXZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosY * cosZ; + auto m2 = -sinY * cosZ; + auto m4 = -cosY * sinZ * cosX + sinY * sinX; + auto m5 = cosZ * cosX; + auto m6 = sinY * sinZ * cosX + cosY * sinX; + auto m8 = cosY * sinZ * sinX + sinY * cosX; + auto m9 = -cosZ * sinX; + auto m10 = -sinY * sinZ * sinX + cosY * cosX; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * sinZ + matrix.m[8] * m2, + matrix.m[1] * m0 + matrix.m[5] * sinZ + matrix.m[9] * m2, + matrix.m[2] * m0 + matrix.m[6] * sinZ + matrix.m[10] * m2, + matrix.m[3] * m0 + matrix.m[7] * sinZ + matrix.m[11] * m2, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateYXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto m0 = cosZ * cosY - sinZ * sinX * sinY; + auto m1 = sinZ * cosY + cosZ * sinX * sinY; + auto m2 = -cosX * sinY; + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = cosZ * sinY + sinZ * sinX * cosY; + auto m9 = sinZ * sinY - cosZ * sinX * cosY; + auto m10 = cosX * cosY; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * sinX, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * sinX, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * sinX, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * sinX, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateYZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosZ * cosY; + auto m1 = cosX * sinZ * cosY + sinX * sinY; + auto m2 = sinX * sinZ * cosY - cosX * sinY; + auto m5 = cosX * cosZ; + auto m6 = sinX * cosZ; + auto m8 = cosZ * sinY; + auto m9 = cosX * sinZ * sinY - sinX * cosY; + auto m10 = sinX * sinZ * sinY + cosX * cosY; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2, + matrix.m[0] * -sinZ + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * -sinZ + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * -sinZ + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * -sinZ + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateZXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ + sinY * sinX * sinZ; + auto m1 = cosX * sinZ; + auto m2 = -sinY * cosZ + cosY * sinX * sinZ; + auto m4 = -cosY * sinZ + sinY * sinX * cosZ; + auto m5 = cosX * cosZ; + auto m6 = sinY * sinZ + cosY * sinX * cosZ; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[0] * m8 + matrix.m[4] * -sinX + matrix.m[8] * m10, + matrix.m[1] * m8 + matrix.m[5] * -sinX + matrix.m[9] * m10, + matrix.m[2] * m8 + matrix.m[6] * -sinX + matrix.m[10] * m10, + matrix.m[3] * m8 + matrix.m[7] * -sinX + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateZYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ; + auto m1 = sinX * sinY * cosZ + cosX * sinZ; + auto m2 = -cosX * sinY * cosZ + sinX * sinZ; + auto m4 = -cosY * sinZ; + auto m5 = -sinX * sinY * sinZ + cosX * cosZ; + auto m6 = cosX * sinY * sinZ + sinX * cosZ; + auto m9 = -sinX * cosY; + auto m10 = cosX * cosY; + return new T[4 * 4] { + matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2, + matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2, + matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2, + matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2, + matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6, + matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6, + matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6, + matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6, + matrix.m[0] * sinY + matrix.m[4] * m9 + matrix.m[8] * m10, + matrix.m[1] * sinY + matrix.m[5] * m9 + matrix.m[9] * m10, + matrix.m[2] * sinY + matrix.m[6] * m9 + matrix.m[10] * m10, + matrix.m[3] * sinY + matrix.m[7] * m9 + matrix.m[11] * m10, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & rotateX(const GenoMatrix<4, 4, T> & matrix, T rotateX, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4] * cosX + matrix.m[8] * sinX; + target.m[5] = matrix.m[5] * cosX + matrix.m[9] * sinX; + target.m[6] = matrix.m[6] * cosX + matrix.m[10] * sinX; + target.m[7] = matrix.m[7] * cosX + matrix.m[11] * sinX; + target.m[8] = matrix.m[4] * -sinX + matrix.m[8] * cosX; + target.m[9] = matrix.m[5] * -sinX + matrix.m[9] * cosX; + target.m[10] = matrix.m[6] * -sinX + matrix.m[10] * cosX; + target.m[11] = matrix.m[7] * -sinX + matrix.m[11] * cosX; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateY(const GenoMatrix<4, 4, T> & matrix, T rotateY, GenoMatrix<4, 4, T> & target) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + target.m[0] = matrix.m[0] * cosY + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * cosY + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * cosY + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * cosY + matrix.m[11] * -sinY; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[0] * sinY + matrix.m[8] * cosY; + target.m[9] = matrix.m[1] * sinY + matrix.m[9] * cosY; + target.m[10] = matrix.m[2] * sinY + matrix.m[10] * cosY; + target.m[11] = matrix.m[3] * sinY + matrix.m[11] * cosY; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateZ(const GenoMatrix<4, 4, T> & matrix, T rotateZ, GenoMatrix<4, 4, T> & target) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + target.m[0] = matrix.m[0] * cosZ + matrix.m[4] * sinZ; + target.m[1] = matrix.m[1] * cosZ + matrix.m[5] * sinZ; + target.m[2] = matrix.m[2] * cosZ + matrix.m[6] * sinZ; + target.m[3] = matrix.m[3] * cosZ + matrix.m[7] * sinZ; + target.m[4] = matrix.m[0] * -sinZ + matrix.m[4] * cosZ; + target.m[5] = matrix.m[1] * -sinZ + matrix.m[5] * cosZ; + target.m[6] = matrix.m[2] * -sinZ + matrix.m[6] * cosZ; + target.m[7] = matrix.m[3] * -sinZ + matrix.m[7] * cosZ; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXY(const GenoMatrix<4, 4, T> & matrix, T rotateX, T rotateY, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto m4 = sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + target.m[0] = matrix.m[0] * cosY + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * cosY + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * cosY + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * cosY + matrix.m[11] * -sinY; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * cosX + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * cosX + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * cosX + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * cosX + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * -sinX + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * -sinX + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * -sinX + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * -sinX + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto m4 = sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + target.m[0] = matrix.m[0] * cosY + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * cosY + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * cosY + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * cosY + matrix.m[11] * -sinY; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * cosX + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * cosX + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * cosX + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * cosX + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * -sinX + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * -sinX + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * -sinX + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * -sinX + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXZ(const GenoMatrix<4, 4, T> & matrix, T rotateX, T rotateZ, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = sinZ * sinX; + auto m9 = -cosZ * sinX; + target.m[0] = matrix.m[0] * cosZ + matrix.m[4] * sinZ; + target.m[1] = matrix.m[1] * cosZ + matrix.m[5] * sinZ; + target.m[2] = matrix.m[2] * cosZ + matrix.m[6] * sinZ; + target.m[3] = matrix.m[3] * cosZ + matrix.m[7] * sinZ; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * sinX; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * sinX; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * sinX; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * sinX; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosX; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosX; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosX; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosX; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = sinZ * sinX; + auto m9 = -cosZ * sinX; + target.m[0] = matrix.m[0] * cosZ + matrix.m[4] * sinZ; + target.m[1] = matrix.m[1] * cosZ + matrix.m[5] * sinZ; + target.m[2] = matrix.m[2] * cosZ + matrix.m[6] * sinZ; + target.m[3] = matrix.m[3] * cosZ + matrix.m[7] * sinZ; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * sinX; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * sinX; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * sinX; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * sinX; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosX; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosX; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosX; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosX; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto m1 = sinX * sinY; + auto m2 = -cosX * sinY; + auto m9 = -sinX * cosY; + auto m10 = cosX * cosY; + target.m[0] = matrix.m[0] * cosY + matrix.m[4] * m1 + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * cosY + matrix.m[5] * m1 + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * cosY + matrix.m[6] * m1 + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * cosY + matrix.m[7] * m1 + matrix.m[11] * m2; + target.m[4] = matrix.m[4] * cosX + matrix.m[8] * sinX; + target.m[5] = matrix.m[5] * cosX + matrix.m[9] * sinX; + target.m[6] = matrix.m[6] * cosX + matrix.m[10] * sinX; + target.m[7] = matrix.m[7] * cosX + matrix.m[11] * sinX; + target.m[8] = matrix.m[0] * sinY + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * sinY + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * sinY + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * sinY + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateYZ(const GenoMatrix<4, 4, T> & matrix, T rotateY, T rotateZ, GenoMatrix<4, 4, T> & target) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m8 = cosZ * sinY; + auto m9 = sinZ * sinY; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY; + target.m[4] = matrix.m[0] * -sinZ + matrix.m[4] * cosZ; + target.m[5] = matrix.m[1] * -sinZ + matrix.m[5] * cosZ; + target.m[6] = matrix.m[2] * -sinZ + matrix.m[6] * cosZ; + target.m[7] = matrix.m[3] * -sinZ + matrix.m[7] * cosZ; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosY; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosY; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosY; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosY; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m8 = cosZ * sinY; + auto m9 = sinZ * sinY; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY; + target.m[4] = matrix.m[0] * -sinZ + matrix.m[4] * cosZ; + target.m[5] = matrix.m[1] * -sinZ + matrix.m[5] * cosZ; + target.m[6] = matrix.m[2] * -sinZ + matrix.m[6] * cosZ; + target.m[7] = matrix.m[3] * -sinZ + matrix.m[7] * cosZ; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * cosY; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * cosY; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * cosY; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * cosY; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m1 = cosX * sinZ; + auto m2 = sinX * sinZ; + auto m5 = cosX * cosZ; + auto m6 = sinX * cosZ; + target.m[0] = matrix.m[0] * cosZ + matrix.m[4] * m1 + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * cosZ + matrix.m[5] * m1 + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * cosZ + matrix.m[6] * m1 + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * cosZ + matrix.m[7] * m1 + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * -sinZ + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * -sinZ + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * -sinZ + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * -sinZ + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[4] * -sinX + matrix.m[8] * cosX; + target.m[9] = matrix.m[5] * -sinX + matrix.m[9] * cosX; + target.m[10] = matrix.m[6] * -sinX + matrix.m[10] * cosX; + target.m[11] = matrix.m[7] * -sinX + matrix.m[11] * cosX; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ; + auto m2 = -sinY * cosZ; + auto m4 = -cosY * sinZ; + auto m6 = sinY * sinZ; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * sinZ + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * sinZ + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * sinZ + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * sinZ + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * cosZ + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * cosZ + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * cosZ + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * cosZ + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * sinY + matrix.m[8] * cosY; + target.m[9] = matrix.m[1] * sinY + matrix.m[9] * cosY; + target.m[10] = matrix.m[2] * sinY + matrix.m[10] * cosY; + target.m[11] = matrix.m[3] * sinY + matrix.m[11] * cosY; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXYZ(const GenoMatrix<4, 4, T> & matrix, T rotateX, T rotateY, T rotateZ, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m4 = -sinZ * cosX + cosZ * sinY * sinX; + auto m5 = cosZ * cosX + sinZ * sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinZ * sinX + cosZ * sinY * cosX; + auto m9 = -cosZ * sinX + sinZ * sinY * cosX; + auto m10 = cosY * cosX; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto m0 = cosZ * cosY; + auto m1 = sinZ * cosY; + auto m4 = -sinZ * cosX + cosZ * sinY * sinX; + auto m5 = cosZ * cosX + sinZ * sinY * sinX; + auto m6 = cosY * sinX; + auto m8 = sinZ * sinX + cosZ * sinY * cosX; + auto m9 = -cosZ * sinX + sinZ * sinY * cosX; + auto m10 = cosY * cosX; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * -sinY; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * -sinY; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * -sinY; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * -sinY; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateXZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosY * cosZ; + auto m2 = -sinY * cosZ; + auto m4 = -cosY * sinZ * cosX + sinY * sinX; + auto m5 = cosZ * cosX; + auto m6 = sinY * sinZ * cosX + cosY * sinX; + auto m8 = cosY * sinZ * sinX + sinY * cosX; + auto m9 = -cosZ * sinX; + auto m10 = -sinY * sinZ * sinX + cosY * cosX; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * sinZ + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * sinZ + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * sinZ + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * sinZ + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateYXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto m0 = cosZ * cosY - sinZ * sinX * sinY; + auto m1 = sinZ * cosY + cosZ * sinX * sinY; + auto m2 = -cosX * sinY; + auto m4 = -sinZ * cosX; + auto m5 = cosZ * cosX; + auto m8 = cosZ * sinY + sinZ * sinX * cosY; + auto m9 = sinZ * sinY - cosZ * sinX * cosY; + auto m10 = cosX * cosY; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * sinX; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * sinX; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * sinX; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * sinX; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateYZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto m0 = cosZ * cosY; + auto m1 = cosX * sinZ * cosY + sinX * sinY; + auto m2 = sinX * sinZ * cosY - cosX * sinY; + auto m5 = cosX * cosZ; + auto m6 = sinX * cosZ; + auto m8 = cosZ * sinY; + auto m9 = cosX * sinZ * sinY - sinX * cosY; + auto m10 = sinX * sinZ * sinY + cosX * cosY; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * -sinZ + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * -sinZ + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * -sinZ + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * -sinZ + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateZXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ + sinY * sinX * sinZ; + auto m1 = cosX * sinZ; + auto m2 = -sinY * cosZ + cosY * sinX * sinZ; + auto m4 = -cosY * sinZ + sinY * sinX * cosZ; + auto m5 = cosX * cosZ; + auto m6 = sinY * sinZ + cosY * sinX * cosZ; + auto m8 = sinY * cosX; + auto m10 = cosY * cosX; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * m8 + matrix.m[4] * -sinX + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * m8 + matrix.m[5] * -sinX + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * m8 + matrix.m[6] * -sinX + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * m8 + matrix.m[7] * -sinX + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & rotateZYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & rotate, GenoMatrix<4, 4, T> & target) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto m0 = cosY * cosZ; + auto m1 = sinX * sinY * cosZ + cosX * sinZ; + auto m2 = -cosX * sinY * cosZ + sinX * sinZ; + auto m4 = -cosY * sinZ; + auto m5 = -sinX * sinY * sinZ + cosX * cosZ; + auto m6 = cosX * sinY * sinZ + sinX * cosZ; + auto m9 = -sinX * cosY; + auto m10 = cosX * cosY; + target.m[0] = matrix.m[0] * m0 + matrix.m[4] * m1 + matrix.m[8] * m2; + target.m[1] = matrix.m[1] * m0 + matrix.m[5] * m1 + matrix.m[9] * m2; + target.m[2] = matrix.m[2] * m0 + matrix.m[6] * m1 + matrix.m[10] * m2; + target.m[3] = matrix.m[3] * m0 + matrix.m[7] * m1 + matrix.m[11] * m2; + target.m[4] = matrix.m[0] * m4 + matrix.m[4] * m5 + matrix.m[8] * m6; + target.m[5] = matrix.m[1] * m4 + matrix.m[5] * m5 + matrix.m[9] * m6; + target.m[6] = matrix.m[2] * m4 + matrix.m[6] * m5 + matrix.m[10] * m6; + target.m[7] = matrix.m[3] * m4 + matrix.m[7] * m5 + matrix.m[11] * m6; + target.m[8] = matrix.m[0] * sinY + matrix.m[4] * m9 + matrix.m[8] * m10; + target.m[9] = matrix.m[1] * sinY + matrix.m[5] * m9 + matrix.m[9] * m10; + target.m[10] = matrix.m[2] * sinY + matrix.m[6] * m9 + matrix.m[10] * m10; + target.m[11] = matrix.m[3] * sinY + matrix.m[7] * m9 + matrix.m[11] * m10; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> scaleX(const GenoMatrix<4, 4, T> & matrix, T scaleX) { + return new T[4 * 4] { + matrix.m[0] * scaleX, + matrix.m[1] * scaleX, + matrix.m[2] * scaleX, + matrix.m[3] * scaleX, + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleY(const GenoMatrix<4, 4, T> & matrix, T scaleY) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4] * scaleY, + matrix.m[5] * scaleY, + matrix.m[6] * scaleY, + matrix.m[7] * scaleY, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleZ(const GenoMatrix<4, 4, T> & matrix, T scaleZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8] * scaleZ, + matrix.m[9] * scaleZ, + matrix.m[10] * scaleZ, + matrix.m[11] * scaleZ, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXY(const GenoMatrix<4, 4, T> & matrix, T scale) { + return new T[4 * 4] { + matrix.m[0] * scale, + matrix.m[1] * scale, + matrix.m[2] * scale, + matrix.m[3] * scale, + matrix.m[4] * scale, + matrix.m[5] * scale, + matrix.m[6] * scale, + matrix.m[7] * scale, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXY(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY) { + return new T[4 * 4] { + matrix.m[0] * scaleX, + matrix.m[1] * scaleX, + matrix.m[2] * scaleX, + matrix.m[3] * scaleX, + matrix.m[4] * scaleY, + matrix.m[5] * scaleY, + matrix.m[6] * scaleY, + matrix.m[7] * scaleY, + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[0], + matrix.m[1] * scale.v[0], + matrix.m[2] * scale.v[0], + matrix.m[3] * scale.v[0], + matrix.m[4] * scale.v[1], + matrix.m[5] * scale.v[1], + matrix.m[6] * scale.v[1], + matrix.m[7] * scale.v[1], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXZ(const GenoMatrix<4, 4, T> & matrix, T scale) { + return new T[4 * 4] { + matrix.m[0] * scale, + matrix.m[1] * scale, + matrix.m[2] * scale, + matrix.m[3] * scale, + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8] * scale, + matrix.m[9] * scale, + matrix.m[10] * scale, + matrix.m[11] * scale, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXZ(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleZ) { + return new T[4 * 4] { + matrix.m[0] * scaleX, + matrix.m[1] * scaleX, + matrix.m[2] * scaleX, + matrix.m[3] * scaleX, + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8] * scaleZ, + matrix.m[9] * scaleZ, + matrix.m[10] * scaleZ, + matrix.m[11] * scaleZ, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[0], + matrix.m[1] * scale.v[0], + matrix.m[2] * scale.v[0], + matrix.m[3] * scale.v[0], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8] * scale.v[1], + matrix.m[9] * scale.v[1], + matrix.m[10] * scale.v[1], + matrix.m[11] * scale.v[1], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[1], + matrix.m[1] * scale.v[1], + matrix.m[2] * scale.v[1], + matrix.m[3] * scale.v[1], + matrix.m[4] * scale.v[0], + matrix.m[5] * scale.v[0], + matrix.m[6] * scale.v[0], + matrix.m[7] * scale.v[0], + matrix.m[8], + matrix.m[9], + matrix.m[10], + matrix.m[11], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleYZ(const GenoMatrix<4, 4, T> & matrix, T scale) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4] * scale, + matrix.m[5] * scale, + matrix.m[6] * scale, + matrix.m[7] * scale, + matrix.m[8] * scale, + matrix.m[9] * scale, + matrix.m[10] * scale, + matrix.m[11] * scale, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleYZ(const GenoMatrix<4, 4, T> & matrix, T scaleY, T scaleZ) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4] * scaleY, + matrix.m[5] * scaleY, + matrix.m[6] * scaleY, + matrix.m[7] * scaleY, + matrix.m[8] * scaleZ, + matrix.m[9] * scaleZ, + matrix.m[10] * scaleZ, + matrix.m[11] * scaleZ, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4] * scale.v[0], + matrix.m[5] * scale.v[0], + matrix.m[6] * scale.v[0], + matrix.m[7] * scale.v[0], + matrix.m[8] * scale.v[1], + matrix.m[9] * scale.v[1], + matrix.m[10] * scale.v[1], + matrix.m[11] * scale.v[1], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[1], + matrix.m[1] * scale.v[1], + matrix.m[2] * scale.v[1], + matrix.m[3] * scale.v[1], + matrix.m[4], + matrix.m[5], + matrix.m[6], + matrix.m[7], + matrix.m[8] * scale.v[0], + matrix.m[9] * scale.v[0], + matrix.m[10] * scale.v[0], + matrix.m[11] * scale.v[0], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale) { + return new T[4 * 4] { + matrix.m[0], + matrix.m[1], + matrix.m[2], + matrix.m[3], + matrix.m[4] * scale.v[1], + matrix.m[5] * scale.v[1], + matrix.m[6] * scale.v[1], + matrix.m[7] * scale.v[1], + matrix.m[8] * scale.v[0], + matrix.m[9] * scale.v[0], + matrix.m[10] * scale.v[0], + matrix.m[11] * scale.v[0], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXYZ(const GenoMatrix<4, 4, T> & matrix, T scale) { + return new T[4 * 4] { + matrix.m[0] * scale, + matrix.m[1] * scale, + matrix.m[2] * scale, + matrix.m[3] * scale, + matrix.m[4] * scale, + matrix.m[5] * scale, + matrix.m[6] * scale, + matrix.m[7] * scale, + matrix.m[8] * scale, + matrix.m[9] * scale, + matrix.m[10] * scale, + matrix.m[11] * scale, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXYZ(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY, T scaleZ) { + return new T[4 * 4] { + matrix.m[0] * scaleX, + matrix.m[1] * scaleX, + matrix.m[2] * scaleX, + matrix.m[3] * scaleX, + matrix.m[4] * scaleY, + matrix.m[5] * scaleY, + matrix.m[6] * scaleY, + matrix.m[7] * scaleY, + matrix.m[8] * scaleZ, + matrix.m[9] * scaleZ, + matrix.m[10] * scaleZ, + matrix.m[11] * scaleZ, + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[0], + matrix.m[1] * scale.v[0], + matrix.m[2] * scale.v[0], + matrix.m[3] * scale.v[0], + matrix.m[4] * scale.v[1], + matrix.m[5] * scale.v[1], + matrix.m[6] * scale.v[1], + matrix.m[7] * scale.v[1], + matrix.m[8] * scale.v[2], + matrix.m[9] * scale.v[2], + matrix.m[10] * scale.v[2], + matrix.m[11] * scale.v[2], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleXZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[0], + matrix.m[1] * scale.v[0], + matrix.m[2] * scale.v[0], + matrix.m[3] * scale.v[0], + matrix.m[4] * scale.v[2], + matrix.m[5] * scale.v[2], + matrix.m[6] * scale.v[2], + matrix.m[7] * scale.v[2], + matrix.m[8] * scale.v[1], + matrix.m[9] * scale.v[1], + matrix.m[10] * scale.v[1], + matrix.m[11] * scale.v[1], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleYXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[1], + matrix.m[1] * scale.v[1], + matrix.m[2] * scale.v[1], + matrix.m[3] * scale.v[1], + matrix.m[4] * scale.v[0], + matrix.m[5] * scale.v[0], + matrix.m[6] * scale.v[0], + matrix.m[7] * scale.v[0], + matrix.m[8] * scale.v[2], + matrix.m[9] * scale.v[2], + matrix.m[10] * scale.v[2], + matrix.m[11] * scale.v[2], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleYZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[2], + matrix.m[1] * scale.v[2], + matrix.m[2] * scale.v[2], + matrix.m[3] * scale.v[2], + matrix.m[4] * scale.v[0], + matrix.m[5] * scale.v[0], + matrix.m[6] * scale.v[0], + matrix.m[7] * scale.v[0], + matrix.m[8] * scale.v[1], + matrix.m[9] * scale.v[1], + matrix.m[10] * scale.v[1], + matrix.m[11] * scale.v[1], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleZXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[1], + matrix.m[1] * scale.v[1], + matrix.m[2] * scale.v[1], + matrix.m[3] * scale.v[1], + matrix.m[4] * scale.v[2], + matrix.m[5] * scale.v[2], + matrix.m[6] * scale.v[2], + matrix.m[7] * scale.v[2], + matrix.m[8] * scale.v[0], + matrix.m[9] * scale.v[0], + matrix.m[10] * scale.v[0], + matrix.m[11] * scale.v[0], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> scaleZYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale) { + return new T[4 * 4] { + matrix.m[0] * scale.v[2], + matrix.m[1] * scale.v[2], + matrix.m[2] * scale.v[2], + matrix.m[3] * scale.v[2], + matrix.m[4] * scale.v[1], + matrix.m[5] * scale.v[1], + matrix.m[6] * scale.v[1], + matrix.m[7] * scale.v[1], + matrix.m[8] * scale.v[0], + matrix.m[9] * scale.v[0], + matrix.m[10] * scale.v[0], + matrix.m[11] * scale.v[0], + matrix.m[12], + matrix.m[13], + matrix.m[14], + matrix.m[15] + }; +} + +template +GenoMatrix<4, 4, T> & scaleX(const GenoMatrix<4, 4, T> & matrix, T scaleX, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scaleX; + target.m[1] = matrix.m[1] * scaleX; + target.m[2] = matrix.m[2] * scaleX; + target.m[3] = matrix.m[3] * scaleX; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleY(const GenoMatrix<4, 4, T> & matrix, T scaleY, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4] * scaleY; + target.m[5] = matrix.m[5] * scaleY; + target.m[6] = matrix.m[6] * scaleY; + target.m[7] = matrix.m[7] * scaleY; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleZ(const GenoMatrix<4, 4, T> & matrix, T scaleZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8] * scaleZ; + target.m[9] = matrix.m[9] * scaleZ; + target.m[10] = matrix.m[10] * scaleZ; + target.m[11] = matrix.m[11] * scaleZ; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXY(const GenoMatrix<4, 4, T> & matrix, T scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale; + target.m[1] = matrix.m[1] * scale; + target.m[2] = matrix.m[2] * scale; + target.m[3] = matrix.m[3] * scale; + target.m[4] = matrix.m[4] * scale; + target.m[5] = matrix.m[5] * scale; + target.m[6] = matrix.m[6] * scale; + target.m[7] = matrix.m[7] * scale; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXY(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scaleX; + target.m[1] = matrix.m[1] * scaleX; + target.m[2] = matrix.m[2] * scaleX; + target.m[3] = matrix.m[3] * scaleX; + target.m[4] = matrix.m[4] * scaleY; + target.m[5] = matrix.m[5] * scaleY; + target.m[6] = matrix.m[6] * scaleY; + target.m[7] = matrix.m[7] * scaleY; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[0]; + target.m[1] = matrix.m[1] * scale.v[0]; + target.m[2] = matrix.m[2] * scale.v[0]; + target.m[3] = matrix.m[3] * scale.v[0]; + target.m[4] = matrix.m[4] * scale.v[1]; + target.m[5] = matrix.m[5] * scale.v[1]; + target.m[6] = matrix.m[6] * scale.v[1]; + target.m[7] = matrix.m[7] * scale.v[1]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXZ(const GenoMatrix<4, 4, T> & matrix, T scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale; + target.m[1] = matrix.m[1] * scale; + target.m[2] = matrix.m[2] * scale; + target.m[3] = matrix.m[3] * scale; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8] * scale; + target.m[9] = matrix.m[9] * scale; + target.m[10] = matrix.m[10] * scale; + target.m[11] = matrix.m[11] * scale; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXZ(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scaleX; + target.m[1] = matrix.m[1] * scaleX; + target.m[2] = matrix.m[2] * scaleX; + target.m[3] = matrix.m[3] * scaleX; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8] * scaleZ; + target.m[9] = matrix.m[9] * scaleZ; + target.m[10] = matrix.m[10] * scaleZ; + target.m[11] = matrix.m[11] * scaleZ; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[0]; + target.m[1] = matrix.m[1] * scale.v[0]; + target.m[2] = matrix.m[2] * scale.v[0]; + target.m[3] = matrix.m[3] * scale.v[0]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8] * scale.v[1]; + target.m[9] = matrix.m[9] * scale.v[1]; + target.m[10] = matrix.m[10] * scale.v[1]; + target.m[11] = matrix.m[11] * scale.v[1]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[1]; + target.m[1] = matrix.m[1] * scale.v[1]; + target.m[2] = matrix.m[2] * scale.v[1]; + target.m[3] = matrix.m[3] * scale.v[1]; + target.m[4] = matrix.m[4] * scale.v[0]; + target.m[5] = matrix.m[5] * scale.v[0]; + target.m[6] = matrix.m[6] * scale.v[0]; + target.m[7] = matrix.m[7] * scale.v[0]; + target.m[8] = matrix.m[8]; + target.m[9] = matrix.m[9]; + target.m[10] = matrix.m[10]; + target.m[11] = matrix.m[11]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleYZ(const GenoMatrix<4, 4, T> & matrix, T scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4] * scale; + target.m[5] = matrix.m[5] * scale; + target.m[6] = matrix.m[6] * scale; + target.m[7] = matrix.m[7] * scale; + target.m[8] = matrix.m[8] * scale; + target.m[9] = matrix.m[9] * scale; + target.m[10] = matrix.m[10] * scale; + target.m[11] = matrix.m[11] * scale; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleYZ(const GenoMatrix<4, 4, T> & matrix, T scaleY, T scaleZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4] * scaleY; + target.m[5] = matrix.m[5] * scaleY; + target.m[6] = matrix.m[6] * scaleY; + target.m[7] = matrix.m[7] * scaleY; + target.m[8] = matrix.m[8] * scaleZ; + target.m[9] = matrix.m[9] * scaleZ; + target.m[10] = matrix.m[10] * scaleZ; + target.m[11] = matrix.m[11] * scaleZ; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4] * scale.v[0]; + target.m[5] = matrix.m[5] * scale.v[0]; + target.m[6] = matrix.m[6] * scale.v[0]; + target.m[7] = matrix.m[7] * scale.v[0]; + target.m[8] = matrix.m[8] * scale.v[1]; + target.m[9] = matrix.m[9] * scale.v[1]; + target.m[10] = matrix.m[10] * scale.v[1]; + target.m[11] = matrix.m[11] * scale.v[1]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[1]; + target.m[1] = matrix.m[1] * scale.v[1]; + target.m[2] = matrix.m[2] * scale.v[1]; + target.m[3] = matrix.m[3] * scale.v[1]; + target.m[4] = matrix.m[4]; + target.m[5] = matrix.m[5]; + target.m[6] = matrix.m[6]; + target.m[7] = matrix.m[7]; + target.m[8] = matrix.m[8] * scale.v[0]; + target.m[9] = matrix.m[9] * scale.v[0]; + target.m[10] = matrix.m[10] * scale.v[0]; + target.m[11] = matrix.m[11] * scale.v[0]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<2, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0]; + target.m[1] = matrix.m[1]; + target.m[2] = matrix.m[2]; + target.m[3] = matrix.m[3]; + target.m[4] = matrix.m[4] * scale.v[1]; + target.m[5] = matrix.m[5] * scale.v[1]; + target.m[6] = matrix.m[6] * scale.v[1]; + target.m[7] = matrix.m[7] * scale.v[1]; + target.m[8] = matrix.m[8] * scale.v[0]; + target.m[9] = matrix.m[9] * scale.v[0]; + target.m[10] = matrix.m[10] * scale.v[0]; + target.m[11] = matrix.m[11] * scale.v[0]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXYZ(const GenoMatrix<4, 4, T> & matrix, T scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale; + target.m[1] = matrix.m[1] * scale; + target.m[2] = matrix.m[2] * scale; + target.m[3] = matrix.m[3] * scale; + target.m[4] = matrix.m[4] * scale; + target.m[5] = matrix.m[5] * scale; + target.m[6] = matrix.m[6] * scale; + target.m[7] = matrix.m[7] * scale; + target.m[8] = matrix.m[8] * scale; + target.m[9] = matrix.m[9] * scale; + target.m[10] = matrix.m[10] * scale; + target.m[11] = matrix.m[11] * scale; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXYZ(const GenoMatrix<4, 4, T> & matrix, T scaleX, T scaleY, T scaleZ, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scaleX; + target.m[1] = matrix.m[1] * scaleX; + target.m[2] = matrix.m[2] * scaleX; + target.m[3] = matrix.m[3] * scaleX; + target.m[4] = matrix.m[4] * scaleY; + target.m[5] = matrix.m[5] * scaleY; + target.m[6] = matrix.m[6] * scaleY; + target.m[7] = matrix.m[7] * scaleY; + target.m[8] = matrix.m[8] * scaleZ; + target.m[9] = matrix.m[9] * scaleZ; + target.m[10] = matrix.m[10] * scaleZ; + target.m[11] = matrix.m[11] * scaleZ; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXYZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[0]; + target.m[1] = matrix.m[1] * scale.v[0]; + target.m[2] = matrix.m[2] * scale.v[0]; + target.m[3] = matrix.m[3] * scale.v[0]; + target.m[4] = matrix.m[4] * scale.v[1]; + target.m[5] = matrix.m[5] * scale.v[1]; + target.m[6] = matrix.m[6] * scale.v[1]; + target.m[7] = matrix.m[7] * scale.v[1]; + target.m[8] = matrix.m[8] * scale.v[2]; + target.m[9] = matrix.m[9] * scale.v[2]; + target.m[10] = matrix.m[10] * scale.v[2]; + target.m[11] = matrix.m[11] * scale.v[2]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleXZY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[0]; + target.m[1] = matrix.m[1] * scale.v[0]; + target.m[2] = matrix.m[2] * scale.v[0]; + target.m[3] = matrix.m[3] * scale.v[0]; + target.m[4] = matrix.m[4] * scale.v[2]; + target.m[5] = matrix.m[5] * scale.v[2]; + target.m[6] = matrix.m[6] * scale.v[2]; + target.m[7] = matrix.m[7] * scale.v[2]; + target.m[8] = matrix.m[8] * scale.v[1]; + target.m[9] = matrix.m[9] * scale.v[1]; + target.m[10] = matrix.m[10] * scale.v[1]; + target.m[11] = matrix.m[11] * scale.v[1]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleYXZ(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[1]; + target.m[1] = matrix.m[1] * scale.v[1]; + target.m[2] = matrix.m[2] * scale.v[1]; + target.m[3] = matrix.m[3] * scale.v[1]; + target.m[4] = matrix.m[4] * scale.v[0]; + target.m[5] = matrix.m[5] * scale.v[0]; + target.m[6] = matrix.m[6] * scale.v[0]; + target.m[7] = matrix.m[7] * scale.v[0]; + target.m[8] = matrix.m[8] * scale.v[2]; + target.m[9] = matrix.m[9] * scale.v[2]; + target.m[10] = matrix.m[10] * scale.v[2]; + target.m[11] = matrix.m[11] * scale.v[2]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleYZX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[2]; + target.m[1] = matrix.m[1] * scale.v[2]; + target.m[2] = matrix.m[2] * scale.v[2]; + target.m[3] = matrix.m[3] * scale.v[2]; + target.m[4] = matrix.m[4] * scale.v[0]; + target.m[5] = matrix.m[5] * scale.v[0]; + target.m[6] = matrix.m[6] * scale.v[0]; + target.m[7] = matrix.m[7] * scale.v[0]; + target.m[8] = matrix.m[8] * scale.v[1]; + target.m[9] = matrix.m[9] * scale.v[1]; + target.m[10] = matrix.m[10] * scale.v[1]; + target.m[11] = matrix.m[11] * scale.v[1]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleZXY(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[1]; + target.m[1] = matrix.m[1] * scale.v[1]; + target.m[2] = matrix.m[2] * scale.v[1]; + target.m[3] = matrix.m[3] * scale.v[1]; + target.m[4] = matrix.m[4] * scale.v[2]; + target.m[5] = matrix.m[5] * scale.v[2]; + target.m[6] = matrix.m[6] * scale.v[2]; + target.m[7] = matrix.m[7] * scale.v[2]; + target.m[8] = matrix.m[8] * scale.v[0]; + target.m[9] = matrix.m[9] * scale.v[0]; + target.m[10] = matrix.m[10] * scale.v[0]; + target.m[11] = matrix.m[11] * scale.v[0]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoMatrix<4, 4, T> & scaleZYX(const GenoMatrix<4, 4, T> & matrix, const GenoVector<3, T> & scale, GenoMatrix<4, 4, T> & target) { + target.m[0] = matrix.m[0] * scale.v[2]; + target.m[1] = matrix.m[1] * scale.v[2]; + target.m[2] = matrix.m[2] * scale.v[2]; + target.m[3] = matrix.m[3] * scale.v[2]; + target.m[4] = matrix.m[4] * scale.v[1]; + target.m[5] = matrix.m[5] * scale.v[1]; + target.m[6] = matrix.m[6] * scale.v[1]; + target.m[7] = matrix.m[7] * scale.v[1]; + target.m[8] = matrix.m[8] * scale.v[0]; + target.m[9] = matrix.m[9] * scale.v[0]; + target.m[10] = matrix.m[10] * scale.v[0]; + target.m[11] = matrix.m[11] * scale.v[0]; + target.m[12] = matrix.m[12]; + target.m[13] = matrix.m[13]; + target.m[14] = matrix.m[14]; + target.m[15] = matrix.m[15]; + return target; +} + +template +GenoVector<4, T> operator*(const GenoMatrix<4, 4, T> & left, const GenoVector<4, T> & right) { + return new T[4] { + left.m[0] * right.v[0] + left.m[4] * right.v[1] + left.m[8 ] * right.v[2] + left.m[12] * right.v[3], + left.m[1] * right.v[0] + left.m[5] * right.v[1] + left.m[9 ] * right.v[2] + left.m[13] * right.v[3], + left.m[2] * right.v[0] + left.m[6] * right.v[1] + left.m[10] * right.v[2] + left.m[14] * right.v[3], + left.m[3] * right.v[0] + left.m[7] * right.v[1] + left.m[11] * right.v[2] + left.m[15] * right.v[3] + }; +} + +template +std::ostream & operator<<(std::ostream & stream, const GenoMatrix<4, 4, T> & matrix) { + return stream << '[' << matrix.m[0] << ", " << matrix.m[4] << ", " << matrix.m[8 ] << ", " << matrix.m[12] << "]\n" + "[" << matrix.m[1] << ", " << matrix.m[5] << ", " << matrix.m[9 ] << ", " << matrix.m[13] << "]\n" + "[" << matrix.m[2] << ", " << matrix.m[6] << ", " << matrix.m[10] << ", " << matrix.m[14] << "]\n" + "[" << matrix.m[3] << ", " << matrix.m[7] << ", " << matrix.m[11] << ", " << matrix.m[15] << "]\n"; +} + +using GenoMatrix4b = GenoMatrix<4, 4, int8 >; +using GenoMatrix4ub = GenoMatrix<4, 4, uint8 >; +using GenoMatrix4s = GenoMatrix<4, 4, int16>; +using GenoMatrix4us = GenoMatrix<4, 4, uint16>; +using GenoMatrix4i = GenoMatrix<4, 4, int32>; +using GenoMatrix4ui = GenoMatrix<4, 4, uint32>; +using GenoMatrix4l = GenoMatrix<4, 4, int8 >; +using GenoMatrix4ul = GenoMatrix<4, 4, uint64>; +using GenoMatrix4f = GenoMatrix<4, 4, float >; +using GenoMatrix4d = GenoMatrix<4, 4, double>; + +#define GNARLY_GENOME_MATRIX4_FORWARD +#endif // GNARLY_GENOME_MATRIX4 \ No newline at end of file diff --git a/src/geno/math/linear/GenoMatrixN.h b/src/geno/math/linear/GenoMatrixN.h new file mode 100644 index 0000000..78dcc09 --- /dev/null +++ b/src/geno/math/linear/GenoMatrixN.h @@ -0,0 +1,200 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * INPLIED, INCLUDING BUT NOT LINITED TO THE WARRANTIES OF NERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGENENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIN, DANAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FRON, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_MATRIX_FORWARD +#define GNARLY_GENOME_MATRIX_FORWARD + +template +class GenoMatrix; + +#endif // GNARLY_GENOME_MATRIX_FORWARD + +#ifndef GNARLY_GENOME_MATRIXN +#define GNARLY_GENOME_MATRIXN + +#include + +#include "GenoVector.h" +#include "GenoMatrix.h" + +template +class GenoMatrix { + + static_assert(N > 0 && N > 0, "Matrix dimensions must be greater than 0!"); + + private: + bool owner = true; + + void clean() { + if (owner) + delete [] m; + } + public: + T * m; + + static GenoMatrix makeIdentity() { + auto identity = new T[N * N]; + for (uint32 i = 0; i < N * N; ++i) { + if (i % N == i / N) + identity[i] = 1; + else + identity[i] = 0; + } + return identity; + } + + GenoMatrix() : + m(new T[N * N]()) {} + + GenoMatrix(T * m, bool owner = true) noexcept : + owner(owner), + m(m) {} + + GenoMatrix(std::initializer_list list) : + m(new T[N * N]) { + auto min = list.size() < N * N ? list.size() : N * N; + auto init = list.begin(); + for (uint32 i = 0; i < min; ++i) + m[(i % N) * N + (i / N)] = init[i]; + } + + template + GenoMatrix(const GenoMatrix & matrix) : + m(new T[N * N]) { + for (uint32 i = 0; i < N * N; ++i) + m[i] = (T) matrix.m[i]; + } + + GenoMatrix(const GenoMatrix & matrix) : + m(new T[N * N]) { + for (uint32 i = 0; i < N * N; ++i) + m[i] = matrix.m[i]; + } + + GenoMatrix(GenoMatrix && matrix) noexcept : + owner(matrix.owner), + m(matrix.m) { + matrix.owner = false; + } + + GenoMatrix & operator=(const GenoMatrix & matrix) { + for (uint32 i = 0; i < N * N; ++i) + m[i] = matrix.m[i]; + return *this; + } + + GenoMatrix & operator=(GenoMatrix && matrix) noexcept { + clean(); + owner = matrix.owner; + m = matrix.m; + matrix.owner = false; + return *this; + } + + GenoMatrix & operator+=(const GenoMatrix & matrix) { + for (uint32 i = 0; i < N * N; ++i) + m[i] += matrix.m[i]; + return *this; + } + + GenoMatrix & operator-=(const GenoMatrix & matrix) { + for (uint32 i = 0; i < N * N; ++i) + m[i] -= matrix.m[i]; + return *this; + } + + GenoMatrix & operator*=(const GenoMatrix & matrix) { + return *this = *this * matrix; + } + + GenoVector operator[](uint32 index) const noexcept { + return GenoVector(index * N, false); + } + + GenoMatrix & setIdentity() { + for (uint32 i = 0; i < N * N; ++i) { + if (i % N == i / N) + m[i] = 1; + else + m[i] = 0; + } + return *this; + } + + ~GenoMatrix() { + clean(); + } +}; + +template +T det(const GenoMatrix & matrix) { + auto ret = T{ 0 }; + auto sign = T{ 1 }; + GenoMatrix storage; + for (uint32 i = 0; i < N; ++i) { + auto offset = uint32( -1 ); + for (uint32 j = 0; j < N * N; ++j) + if (j % N != 0 && j / N != i) + storage.m[++offset] = matrix.m[j]; + ret += sign * matrix.m[i * N] * det(storage); + sign *= -1; + } + return ret; +} + +template +T det(const GenoMatrix<2, 2, T> & matrix) { + return matrix.m[0] * matrix.m[3] - matrix.m[2] * matrix.m[1]; +} + +template +T det(const GenoMatrix<1, 1, T> & matrix) { + return matrix.m[0]; +} + +template using GenoMatrixNb = GenoMatrix; +template using GenoMatrixNub = GenoMatrix; +template using GenoMatrixNs = GenoMatrix; +template using GenoMatrixNus = GenoMatrix; +template using GenoMatrixNi = GenoMatrix; +template using GenoMatrixNui = GenoMatrix; +template using GenoMatrixNl = GenoMatrix; +template using GenoMatrixNul = GenoMatrix; +template using GenoMatrixNf = GenoMatrix; +template using GenoMatrixNd = GenoMatrix; + +#define GNARLY_GENOME_MATRIXN_FORWARD +#endif // GNARLY_GENOME_MATRIXN \ No newline at end of file diff --git a/src/geno/math/linear/GenoVector.h b/src/geno/math/linear/GenoVector.h new file mode 100644 index 0000000..b6b9ba2 --- /dev/null +++ b/src/geno/math/linear/GenoVector.h @@ -0,0 +1,476 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_VECTOR +#define GNARLY_GENOME_VECTOR + +#include +#include +#include + +#include "../../GenoInts.h" + +template +class GenoVector { + + static_assert(N > 0, "Vector dimensions must be greater than 0!"); + + private: + bool owner = true; + + void clean() { + if (owner) + delete [] v; + } + + public: + static GenoVector * newArray(uint32 length) { + T * v = new T[N * length]; + GenoVector * ret = new GenoVector[length]; + ret[0] = GenoVector(v); + for (uint32 i = 1; i < length; ++i) + ret[i] = GenoVector(v + i * N, false); + return ret; + } + + T * v; + + GenoVector() : + v(new T[N]()) {} + + GenoVector(T * v, bool owner = true) noexcept : + owner(owner), + v(v) {} + + explicit GenoVector(T value) : + v(new T[N]) { + for (uint32 i = 0; i < N; ++i) + v[i] = value; + } + + GenoVector(std::initializer_list list) : + v(new T[N]) { + auto min = list.size() < N ? list.size() : N; + auto init = list.begin(); + for (uint32 i = 0; i < min; ++i) + v[i] = init[i]; + } + + template + GenoVector(const GenoVector & vector) : + v(new T[N]) { + for (uint32 i = 0; i < N; ++i) + v[i] = (T) vector.v[i]; + } + + GenoVector(const GenoVector & vector) : + v(new T[N]) { + for (uint32 i = 0; i < N; ++i) + v[i] = vector.v[i]; + } + + GenoVector(GenoVector && vector) noexcept : + owner(vector.owner), + v(vector.v) { + vector.owner = false; + } + + GenoVector & operator=(const GenoVector & vector) { + for (uint32 i = 0; i < N; ++i) + v[i] = vector.v[i]; + return *this; + } + + GenoVector & operator=(GenoVector && vector) noexcept { + if (owner) { + clean(); + owner = vector.owner; + v = vector.v; + vector.owner = false; + } + else for (uint32 i = 0; i < N; ++i) + v[i] = vector.v[i]; + return *this; + } + + GenoVector & operator+=(const GenoVector & vector) { + for (uint32 i = 0; i < N; ++i) + v[i] += vector.v[i]; + return *this; + } + + GenoVector & operator-=(const GenoVector & vector) { + for (uint32 i = 0; i < N; ++i) + v[i] -= vector.v[i]; + return *this; + } + + GenoVector & operator*=(T scalar) { + for (uint32 i = 0; i < N; ++i) + v[i] *= scalar; + return *this; + } + + GenoVector & operator*=(const GenoVector & vector) { + for (uint32 i = 0; i < N; ++i) + v[i] *= vector.v[i]; + return *this; + } + + GenoVector & operator/=(T scalar) { + for (uint32 i = 0; i < N; ++i) + v[i] /= scalar; + return *this; + } + + GenoVector & operator/=(const GenoVector & vector) { + for (uint32 i = 0; i < N; ++i) + v[i] /= vector.v[i]; + return *this; + } + + T & operator[](uint32 index) noexcept { + return v[index]; + } + + const T & operator[](uint32 index) const noexcept { + return v[index]; + } + + T getLength() const { + auto lengthSquared = 0; + for (uint32 i = 0; i < N; ++i) + lengthSquared += v[i] * v[i]; + return sqrt(lengthSquared); + } + + T getLengthSquared() const { + auto lengthSquared = 0; + for (uint32 i = 0; i < N; ++i) + lengthSquared += v[i] * v[i]; + return lengthSquared; + } + + GenoVector & setLength(T length) { + auto scalar = length / getLength(); + for (uint32 i = 0; i < N; ++i) + v[i] *= scalar; + return *this; + } + + GenoVector & normalize() { + auto scalar = 1 / getLength(); + for (uint32 i = 0; i < N; ++i) + v[i] *= scalar; + return *this; + } + + GenoVector & negate() { + for (uint32 i = 0; i < N; ++i) + v[i] = -v[i]; + return *this; + } + + GenoVector & project(const GenoVector & projection) { + auto scalar = dot(*this, projection) / projection.getLengthSquared(); + for (uint32 i = 0; i < N; ++i) + v[i] = scalar * projection.v[i]; + return *this; + } + + GenoVector & set(const GenoVector & set) { + for (uint32 i = 0; i < N; ++i) + v[i] = set.v[i]; + return *this; + } + + GenoVector & translate(const GenoVector & translate) { + for (uint32 i = 0; i < N; ++i) + v[i] += translate.v[i]; + return *this; + } + + GenoVector & scale(T scale) { + for (uint32 i = 0; i < N; ++i) + v[i] *= scale; + return *this; + } + + GenoVector & scale(const GenoVector & scale) { + for (uint32 i = 0; i < N; ++i) + v[i] *= scale.v[i]; + return *this; + } + + virtual ~GenoVector() noexcept { + clean(); + } +}; + +template +GenoVector operator-(const GenoVector & vector) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = -vector.v[i]; + return newV; +} + +template +GenoVector operator+(const GenoVector & left, const GenoVector & right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i] + right.v[i]; + return newV; +} + +template +GenoVector operator-(const GenoVector & left, const GenoVector & right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i] - right.v[i]; + return newV; +} + +template +GenoVector operator*(const GenoVector & left, T right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i] * right; + return newV; +} + +template +GenoVector operator*(T left, const GenoVector & right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left * right.v[i]; + return newV; +} + +template +GenoVector operator*(const GenoVector & left, const GenoVector & right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i] * right.v[i]; + return newV; +} + +template +GenoVector operator/(const GenoVector & left, T right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i] / right; + return newV; +} + +template +GenoVector operator/(const GenoVector & left, const GenoVector & right) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i] / right.v[i]; + return newV; +} + +template +GenoVector operator|(const GenoVector & left, T right) { + auto newV = new T[N + 1]; + for (uint32 i = 0; i < N + 1; ++i) + newV[i] = left.v[i]; + newV[N] = right; + return newV; +} + +template +GenoVector operator|(T left, const GenoVector & right) { + auto newV = new T[N + 1]; + newV[0] = left; + for (uint32 i = 0; i < N + 1; ++i) + newV[i + 1] = right.v[i]; + return newV; +} + +template +GenoVector operator|(const GenoVector & left, const GenoVector & right) { + auto newV = new T[N + N2]; + auto vRight = newV + N; + for (uint32 i = 0; i < N; ++i) + newV[i] = left.v[i]; + for (uint32 i = 0; i < N2; ++i) + vRight[i] = right.v[i]; + return newV; +} + +template +GenoVector setLength(const GenoVector & vector, T length) { + auto scalar = length / vector.getLength(); + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = vector.v[i] * scalar; + return newV; +} + +template +GenoVector & setLength(const GenoVector & vector, T length, const GenoVector & target) { + auto scalar = length / vector.getLength(); + for (uint32 i = 0; i < N; ++i) + target.v[i] = vector.v[i] * scalar; + return target; +} + +template +GenoVector normalize(const GenoVector & vector) { + auto scalar = 1 / vector.getLength(); + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = vector.v[i] * scalar; + return newV; +} + +template +GenoVector & normalize(const GenoVector & vector, const GenoVector & target) { + auto scalar = 1 / vector.getLength(); + for (uint32 i = 0; i < N; ++i) + target.v[i] = vector.v[i] * scalar; + return target; +} + +template +GenoVector negate(const GenoVector & vector) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = -vector.v[i]; + return newV; +} + +template +GenoVector & negate(const GenoVector & vector, GenoVector & target) { + for (uint32 i = 0; i < N; ++i) + target.v[i] = -vector.v[i]; + return target; +} + +template +T dot(const GenoVector & left, const GenoVector & right) { + auto product = T(); + for (uint32 i = 0; i < N; ++i) + product += left.v[i] * right.v[i]; + return product; +} + +template +GenoVector project(const GenoVector & vector, const GenoVector & projection) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = scalar * projection.v[i]; + return newV; +} + +template +GenoVector & project(const GenoVector & vector, const GenoVector & projection, GenoVector & target) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + for (uint32 i = 0; i < N; ++i) + target.v[i] = scalar * projection.v[i]; + return target; +} + +template +T angleBetween(const GenoVector & vector1, const GenoVector & vector2) { + return acos(dot(vector1, vector2) / (vector1.getLength() * vector2.getLength())); +} + +template +GenoVector & translate(const GenoVector & vector, const GenoVector & translate) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = vector.v[i] + translate.v[i]; + return newV; +} + + +template +GenoVector & translate(const GenoVector & vector, const GenoVector & translate, GenoVector & target) { + for (uint32 i = 0; i < N; ++i) + target.v[i] = vector.v[i] + translate.v[i]; + return target; +} + +template +GenoVector & scale(const GenoVector & vector, T scale) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = vector.v[i] * scale; + return newV; +} + + +template +GenoVector & scale(const GenoVector & vector, T scale, GenoVector & target) { + for (uint32 i = 0; i < N; ++i) + target.v[i] = vector.v[i] * scale; + return target; +} + +template +GenoVector & scale(const GenoVector & vector, const GenoVector & scale) { + auto newV = new T[N]; + for (uint32 i = 0; i < N; ++i) + newV[i] = vector.v[i] * scale.v[i]; + return newV; +} + + +template +GenoVector & scale(const GenoVector & vector, const GenoVector & scale, GenoVector & target) { + for (uint32 i = 0; i < N; ++i) + target.v[i] = vector.v[i] * scale.v[i]; + return target; +} + +template +std::ostream & operator<<(std::ostream & stream, const GenoVector & vector) { + stream << '<'; + for (uint32 i = 0; i < N; ++i) { + stream << vector.v[i]; + if (i < N - 1) + stream << ", "; + } + return stream << '>'; +} + +template using GenoVectorNb = GenoVector; +template using GenoVectorNub = GenoVector; +template using GenoVectorNs = GenoVector; +template using GenoVectorNus = GenoVector; +template using GenoVectorNi = GenoVector; +template using GenoVectorNui = GenoVector; +template using GenoVectorNl = GenoVector; +template using GenoVectorNul = GenoVector; +template using GenoVectorNf = GenoVector; +template using GenoVectorNd = GenoVector; + +#define GNARLY_GENOME_VECTOR_FORWARD +#endif // GNARLY_GENOME_VECTOR diff --git a/src/geno/math/linear/GenoVector1.h b/src/geno/math/linear/GenoVector1.h new file mode 100644 index 0000000..156f94f --- /dev/null +++ b/src/geno/math/linear/GenoVector1.h @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_VECTOR1 +#define GNARLY_GENOME_VECTOR1 + +#include "GenoVector.h" + +template using GenoVector1 = GenoVector<1, T>; + +using GenoVector1b = GenoVector1< int8 >; +using GenoVector1ub = GenoVector1; +using GenoVector1s = GenoVector1< int16>; +using GenoVector1us = GenoVector1; +using GenoVector1i = GenoVector1< int32>; +using GenoVector1ui = GenoVector1; +using GenoVector1l = GenoVector1< int64>; +using GenoVector1ul = GenoVector1; +using GenoVector1f = GenoVector1; +using GenoVector1d = GenoVector1; + +#define GNARLY_GENOME_VECTOR1_FORWARD +#endif // GNARLY_GENOME_VECTOR1 \ No newline at end of file diff --git a/src/geno/math/linear/GenoVector2.h b/src/geno/math/linear/GenoVector2.h new file mode 100644 index 0000000..82f821f --- /dev/null +++ b/src/geno/math/linear/GenoVector2.h @@ -0,0 +1,1080 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_VECTOR3_FORWARD +#define GNARLY_GENOME_VECTOR3_FORWARD + +template +class GenoVector<3, T>; + +#endif // GNARLY_GENOME_VECTOR3_FORWARD + +#ifndef GNARLY_GENOME_VECTOR4_FORWARD +#define GNARLY_GENOME_VECTOR4_FORWARD + +template +class GenoVector<4, T>; + +#endif // GNARLY_GENOME_VECTOR4_FORWARD + +#ifndef GNARLY_GENOME_VECTOR2 +#define GNARLY_GENOME_VECTOR2 + +#include +#include + +#include "GenoVector.h" +#include "GenoVector3.h" +#include "GenoVector4.h" +#include "GenoVectorDimensions.h" + +namespace GenoVectorDimensions { + extern GenoVectorDimension<0> x; + extern GenoVectorDimension<1> y; +} + +template +class GenoVector<2, T> { + private: + bool owner = true; + + void clean() { + if (owner) + delete [] v; + } + + public: + static GenoVector<2, T> * newArray(uint32 length) { + T * v = new T[2 * length]; + GenoVector<2, T> * ret = new GenoVector<2, T>[length]; + ret[0] = GenoVector<2, T>(v); + for (uint32 i = 1; i < length; ++i) + ret[i] = GenoVector<2, T>(v + i * 2, false); + return ret; + } + + T * v; + + GenoVector() : + v(new T[2]()) {} + + GenoVector(T * v, bool owner = true) noexcept : + owner(owner), + v(v) {} + + explicit GenoVector(T value) : + v(new T[2] { value, value }) {} + + GenoVector(T x, T y) : + v(new T[2] { x, y }) {} + + template + GenoVector(const GenoVector<2, T2> & vector) : + v(new T[2] { + (T) vector.v[0], + (T) vector.v[1] + }) {} + + GenoVector(const GenoVector<2, T> & vector) : + v(new T[2] { + vector.v[0], + vector.v[1] + }) {} + + GenoVector(GenoVector<2, T> && vector) noexcept : + owner(vector.owner), + v(vector.v) { + vector.owner = false; + } + + GenoVector<2, T> & operator=(const GenoVector<2, T> & vector) { + v[0] = vector.v[0]; + v[1] = vector.v[1]; + return *this; + } + + GenoVector<2, T> & operator=(GenoVector<2, T> && vector) noexcept { + if (owner) { + clean(); + owner = vector.owner; + v = vector.v; + vector.owner = false; + } + else { + v[0] = vector.v[0]; + v[1] = vector.v[1]; + } + return *this; + } + + GenoVector<2, T> & operator+=(const GenoVector<2, T> & vector) { + v[0] += vector.v[0]; + v[1] += vector.v[1]; + return *this; + } + + GenoVector<2, T> & operator-=(const GenoVector<2, T> & vector) { + v[0] -= vector.v[0]; + v[1] -= vector.v[1]; + return *this; + } + + GenoVector<2, T> & operator*=(T scalar) { + v[0] *= scalar; + v[1] *= scalar; + return *this; + } + + GenoVector<2, T> & operator*=(const GenoVector<2, T> & vector) { + v[0] *= vector.v[0]; + v[1] *= vector.v[1]; + return *this; + } + + GenoVector<2, T> & operator/=(T scalar) { + v[0] /= scalar; + v[1] /= scalar; + return *this; + } + + GenoVector<2, T> & operator/=(const GenoVector<2, T> & vector) { + v[0] /= vector.v[0]; + v[1] /= vector.v[1]; + return *this; + } + + T & operator[](uint32 index) noexcept { + return v[index]; + } + + const T & operator[](uint32 index) const noexcept { + return v[index]; + } + + template + T & operator[](const GenoVectorDimensions::GenoVectorDimension & dimension) noexcept { + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension != 2, "GenoVector<2, T> has no dimension z!"); + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension != 3, "GenoVector<2, T> has no dimension w!"); + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension < 4, "GenoVector<2, T> has no dimension beyond y!"); + return v[GenoVectorDimensions::GenoVectorDimension::dimension]; + } + + template + const T & operator[](const GenoVectorDimensions::GenoVectorDimension & dimension) const noexcept { + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension != 2, "GenoVector<2, T> has no dimension z!"); + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension != 3, "GenoVector<2, T> has no dimension w!"); + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension < 4, "GenoVector<2, T> has no dimension beyond y!"); + return v[GenoVectorDimensions::GenoVectorDimension::dimension]; + } + + T & x() noexcept { + return v[0]; + } + + const T & x() const noexcept { + return v[0]; + } + + T & y() noexcept { + return v[1]; + } + + const T & y() const noexcept { + return v[1]; + } + + T getLength() const { + return sqrt( + v[0] * v[0] + + v[1] * v[1] + ); + } + + T getLengthSquared() const { + return ( + v[0] * v[0] + + v[1] * v[1] + ); + } + + GenoVector<2, T> & setLength(T length) { + auto scalar = length / getLength(); + v[0] *= scalar; + v[1] *= scalar; + return *this; + } + + GenoVector<2, T> & normalize() { + auto scalar = 1 / getLength(); + v[0] *= scalar; + v[1] *= scalar; + return *this; + } + + T getAngle() const { + return atan2(v[1], v[0]); + } + + GenoVector<2, T> & setAngle(T angle) { + auto length = getLength(); + v[0] = cos(angle) * length; + v[1] = sin(angle) * length; + return *this; + } + + GenoVector<2, T> & rotate(T angle) { + auto sine = sin(angle); + auto cosine = cos(angle); + auto x = v[0]; + v[0] = v[0] * cosine - v[1] * sine; + v[1] = x * sine - v[1] * cosine; + return *this; + } + + GenoVector<2, T> & negate() { + v[0] = -v[0]; + v[1] = -v[1]; + return *this; + } + + GenoVector<2, T> & project(const GenoVector<2, T> & projection) { + auto scalar = dot(*this, projection) / projection.getLengthSquared(); + v[0] /= scalar; + v[1] /= scalar; + return *this; + } + + GenoVector<2, T> & shear(T axisAngle, T shearAngle) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto scalar = v[0] * sinAxis - v[1] * cosAxis; + scalar *= tan(shearAngle); + v[0] += scalar * cosAxis; + v[1] += scalar * sinAxis; + return *this; + } + + GenoVector<2, T> & shear(const GenoVector<2, T> & axis, T shearAngle) { + auto unitAxis = normalize(axis); + auto scalar = v[0] * unitAxis.v[1] - v[1] * unitAxis.v[0]; + scalar *= tan(shearAngle); + v[0] += scalar * unitAxis.v[0]; + v[1] += scalar * unitAxis.v[1]; + return *this; + } + + GenoVector<2, T> & shear(T axisAngle, const GenoVector<2, T> & shear) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto scalar = v[0] * sinAxis - v[1] * cosAxis; + scalar *= shear.v[1] / shear.v[0]; + v[0] += scalar * cosAxis; + v[1] += scalar * sinAxis; + return *this; + } + + GenoVector<2, T> & shear(const GenoVector<2, T> & axis, const GenoVector<2, T> & shear) { + auto unitAxis = normalize(axis); + auto scalar = v[0] * unitAxis.v[1] - v[1] * unitAxis.v[0]; + scalar *= shear.v[1] / shear.v[0]; + v[0] += scalar * unitAxis.v[0]; + v[1] += scalar * unitAxis.v[1]; + return *this; + } + + GenoVector<2, T> & shearX(T angle) { + v[0] -= v[1] * tan(angle); + return *this; + } + + GenoVector<2, T> & shearX(const GenoVector<2, T> & shear) { + v[0] -= v[1] * shear.v[1] / shear.v[0]; + return *this; + } + + GenoVector<2, T> & shearY(T angle) { + v[1] += v[0] * tan(angle); + return *this; + } + + GenoVector<2, T> & shearY(const GenoVector<2, T> & shear) { + v[1] += v[0] * shear.v[1] / shear.v[0]; + return *this; + } + + GenoVector<2, T> & set(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<2, T> & translate(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + return *this; + } + + GenoVector<2, T> & scale(T scale) { + v[0] *= scale; + v[1] *= scale; + return *this; + } + + GenoVector<2, T> & scale(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + return *this; + } + + GenoVector<2, T> & setX(T x) { + v[0] = x; + return *this; + } + + GenoVector<2, T> & setY(T y) { + v[1] = y; + return *this; + } + + GenoVector<2, T> & setXY(T x, T y) { + v[0] = x; + v[1] = y; + return *this; + } + + GenoVector<2, T> & setXY(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<2, T> & setYX(const GenoVector<2, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + return *this; + } + + GenoVector<2, T> & translateX(T translateX) { + v[0] += translateX; + } + + GenoVector<2, T> & translateY(T translateY) { + v[1] += translateY; + } + + GenoVector<2, T> & translateXY(T translateX, T translateY) { + v[0] += translateX; + v[1] += translateY; + } + + GenoVector<2, T> & translateXY(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + } + + GenoVector<2, T> & translateYX(const GenoVector<2, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + } + + GenoVector<2, T> & scaleX(T scaleX) { + v[0] *= scaleX; + } + + GenoVector<2, T> & scaleY(T scaleY) { + v[1] *= scaleY; + } + + GenoVector<2, T> & scaleXY(T scale) { + v[0] *= scale; + v[1] *= scale; + } + + GenoVector<2, T> & scaleXY(T scaleX, T scaleY) { + v[0] *= scaleX; + v[1] *= scaleY; + } + + GenoVector<2, T> & scaleXY(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + } + + GenoVector<2, T> & scaleYX(const GenoVector<2, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + } + + T getX() const { + return v[0]; + } + + T getY() const { + return v[1]; + } + + GenoVector<2, T> getXX() const { + return { v[0], v[0] }; + } + + GenoVector<2, T> getXY() const { + return { v[0], v[1] }; + } + + GenoVector<2, T> getYX() const { + return { v[1], v[0] }; + } + + GenoVector<2, T> getYY() const { + return { v[1], v[1] }; + } + + GenoVector<3, T> getXXX() const { + return { v[0], v[0], v[0] }; + } + + GenoVector<3, T> getXXY() const { + return { v[0], v[0], v[1] }; + } + + GenoVector<3, T> getXYX() const { + return { v[0], v[1], v[0] }; + } + + GenoVector<3, T> getXYY() const { + return { v[0], v[1], v[1] }; + } + + GenoVector<3, T> getYXX() const { + return { v[1], v[0], v[0] }; + } + + GenoVector<3, T> getYXY() const { + return { v[1], v[0], v[1] }; + } + + GenoVector<3, T> getYYX() const { + return { v[1], v[1], v[0] }; + } + + GenoVector<3, T> getYYY() const { + return { v[1], v[1], v[1] }; + } + + GenoVector<4, T> getXXXX() const { + return { v[0], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getXXXY() const { + return { v[0], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getXXYX() const { + return { v[0], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getXXYY() const { + return { v[0], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getXYXX() const { + return { v[0], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getXYXY() const { + return { v[0], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getXYYX() const { + return { v[0], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getXYYY() const { + return { v[0], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getYXXX() const { + return { v[1], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getYXXY() const { + return { v[1], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getYXYX() const { + return { v[1], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getYXYY() const { + return { v[1], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getYYXX() const { + return { v[1], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getYYXY() const { + return { v[1], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getYYYX() const { + return { v[1], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getYYYY() const { + return { v[1], v[1], v[1], v[1] }; + } + + virtual ~GenoVector() noexcept { + clean(); + } +}; + +template +GenoVector<2, T> operator-(const GenoVector<2, T> & vector) { + return { + -vector.v[0], + -vector.v[1] + }; +} + +template +GenoVector<2, T> operator+(const GenoVector<2, T> & left, const GenoVector<2, T> & right) { + return { + left.v[0] + right.v[0], + left.v[1] + right.v[1] + }; +} + +template +GenoVector<2, T> operator-(const GenoVector<2, T> & left, const GenoVector<2, T> & right) { + return { + left.v[0] - right.v[0], + left.v[1] - right.v[1] + }; +} + +template +GenoVector<2, T> operator*(T left, const GenoVector<2, T> & right) { + return { + left * right.v[0], + left * right.v[1] + }; +} + +template +GenoVector<2, T> operator*(const GenoVector<2, T> & left, T right) { + return { + left.v[0] * right, + left.v[1] * right + }; +} + +template +GenoVector<2, T> operator*(const GenoVector<2, T> & left, const GenoVector<2, T> & right) { + return { + left.v[0] * right.v[0], + left.v[1] * right.v[1] + }; +} + +template +GenoVector<2, T> operator/(const GenoVector<2, T> & left, T right) { + return { + left.v[0] / right, + left.v[1] / right + }; +} + +template +GenoVector<2, T> operator/(const GenoVector<2, T> & left, const GenoVector<2, T> & right) { + return { + left.v[0] / right.v[0], + left.v[1] / right.v[1] + }; +} + +template +GenoVector<3, T> operator|(T left, const GenoVector<2, T> & right) { + return { + left, + right.v[0], + right.v[1] + }; +} + +template +GenoVector<3, T> operator|(const GenoVector<2, T> & left, T right) { + return { + left.v[0], + left.v[1], + right + }; +} + +template +GenoVector<4, T> operator|(const GenoVector<2, T> & left, const GenoVector<2, T> & right) { + return { + left.v[0], + left.v[1], + right.v[0], + right.v[1] + }; +} + +template +GenoVector<2, T> setLength(const GenoVector<2, T> & vector, T length) { + auto scalar = length / vector.getLength(); + return { + vector.v[0] * scalar, + vector.v[1] * scalar + }; +} + +template +GenoVector<2, T> & setLength(const GenoVector<2, T> & vector, T length, GenoVector<2, T> & target) { + auto scalar = length / vector.getLength(); + target.v[0] = vector.v[0] * scalar; + target.v[1] = vector.v[1] * scalar; + return target; +} + +template +GenoVector<2, T> normalize(const GenoVector<2, T> & vector) { + auto scalar = 1 / vector.getLength(); + return { + vector.v[0] * scalar, + vector.v[1] * scalar + }; +} + +template +GenoVector<2, T> & normalize(const GenoVector<2, T> & vector, GenoVector<2, T> & target) { + auto scalar = 1 / vector.getLength(); + target.v[0] = vector.v[0] * scalar; + target.v[1] = vector.v[1] * scalar; + return target; +} + +template +GenoVector<2, T> setAngle(const GenoVector<2, T> & vector, T angle) { + auto length = vector.getLength(); + return { + cos(angle) * length, + sin(angle) * length + }; +} + +template +GenoVector<2, T> & setAngle(const GenoVector<2, T> & vector, T angle, GenoVector<2, T> & target) { + auto length = vector.getLength(); + target.v[0] = cos(angle) * length; + target.v[1] = sin(angle) * length; + return target; +} + +template +GenoVector<2, T> & rotate(const GenoVector<2, T> & vector, T angle) { + auto sine = sin(angle); + auto cosine = cos(angle); + return { + vector.v[0] * cosine - vector.v[1] * sine, + vector.v[0] * sine + vector.v[1] * cosine + }; +} + +template +GenoVector<2, T> & rotate(const GenoVector<2, T> & vector, T angle, GenoVector<2, T> & target) { + auto sine = sin(angle); + auto cosine = cos(angle); + target.v[0] = vector.v[0] * cosine - vector.v[1] * sine; + target.v[1] = vector.v[0] * sine + vector.v[1] * cosine; + return target; +} + +template +GenoVector<2, T> negate(const GenoVector<2, T> & vector) { + return { + -vector.v[0], + -vector.v[1] + }; +} + +template +GenoVector<2, T> & negate(const GenoVector<2, T> & vector, GenoVector<2, T> & target) { + target.v[0] = -vector.v[0]; + target.v[1] = -vector.v[1]; + return target; +} + +template +T dot(const GenoVector<2, T> & left, const GenoVector<2, T> & right) { + return ( + left.v[0] * right.v[0] + + left.v[1] * right.v[1] + ); +} + +template +GenoVector<2, T> project(const GenoVector<2, T> & vector, const GenoVector<2, T> & projection) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + return { + scalar * projection.v[0], + scalar * projection.v[1] + }; +} + +template +GenoVector<2, T> & project(const GenoVector<2, T> & vector, const GenoVector<2, T> & projection, GenoVector<2, T> & target) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + target.v[0] = scalar * projection.v[0]; + target.v[1] = scalar * projection.v[1]; + return target; +} + +template +GenoVector<2, T> shear(const GenoVector<2, T> & vector, T axisAngle, T shearAngle) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto scalar = vector.v[0] * sinAxis - vector.v[1] * cosAxis; + scalar *= tan(shearAngle); + return { + vector.v[0] + scalar * cosAxis, + vector.v[1] + scalar * sinAxis, + }; +} + +template +GenoVector<2, T> & shear(const GenoVector<2, T> & vector, T axisAngle, T shearAngle, GenoVector<2, T> & target) { + auto sinAxis = sin(axisAngle); + auto cosAxis = cos(axisAngle); + auto scalar = vector.v[0] * sinAxis - vector.v[1] * cosAxis; + scalar *= tan(shearAngle); + target.v[0] = vector.v[0] + scalar * cosAxis; + target.v[1] = vector.v[1] + scalar * sinAxis; + return target; +} + +template +GenoVector<2, T> shearX(const GenoVector<2, T> & vector, T angle) { + return { + vector.v[0] - vector.v[1] * tan(angle), + vector.v[1] + }; +} + +template +GenoVector<2, T> & shearX(const GenoVector<2, T> & vector, T angle, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] - vector.v[1] * tan(angle); + target.v[1] = vector.v[1]; + return target; +} + +template +GenoVector<2, T> shearY(const GenoVector<2, T> & vector, T angle) { + return { + vector.v[0], + vector.v[1] + vector.v[0] * tan(angle) + }; +} + +template +GenoVector<2, T> & shearY(const GenoVector<2, T> & vector, T angle, GenoVector<2, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + vector.v[0] * tan(angle); + return target; +} + +template +GenoVector<2, T> translate(const GenoVector<2, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1] + }; +} + +template +GenoVector<2, T> & translate(const GenoVector<2, T> & vector, const GenoVector<2, T> & translate, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + return target; +} + +template +GenoVector<2, T> scale(const GenoVector<2, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale + }; +} + +template +GenoVector<2, T> & scale(const GenoVector<2, T> & vector, T scale, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + return target; +} + +template +GenoVector<2, T> scale(const GenoVector<2, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1] + }; +} + +template +GenoVector<2, T> & scale(const GenoVector<2, T> & vector, const GenoVector<2, T> & scale, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + return target; +} + +template +GenoVector<2, T> setX(const GenoVector<2, T> & vector, T x) { + return { + x, + vector.v[1] + }; +} + +template +GenoVector<2, T> setY(const GenoVector<2, T> & vector, T y) { + return { + vector.v[0], + y + }; +} + +template +GenoVector<2, T> setX(const GenoVector<2, T> & vector, T x, GenoVector<2, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + return target; +} + +template +GenoVector<2, T> setY(const GenoVector<2, T> & vector, T y, GenoVector<2, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + return target; +} + +template +GenoVector<2, T> translateX(const GenoVector<2, T> & vector, T translateX) { + return { + vector.v[0] + translateX, + vector.v[1] + }; +} + +template +GenoVector<2, T> translateY(const GenoVector<2, T> & vector, T translateY) { + return { + vector.v[0], + vector.v[1] + translateY + }; +} + +template +GenoVector<2, T> translateXY(const GenoVector<2, T> & vector, T translateX, T translateY) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY + }; +} + +template +GenoVector<2, T> translateXY(const GenoVector<2, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1] + }; +} + +template +GenoVector<2, T> translateYX(const GenoVector<2, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0] + }; +} + +template +GenoVector<2, T> translateX(const GenoVector<2, T> & vector, T translateX, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + return target; +} + +template +GenoVector<2, T> translateY(const GenoVector<2, T> & vector, T translateY, GenoVector<2, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + return target; +} + +template +GenoVector<2, T> translateXY(const GenoVector<2, T> & vector, T translateX, T translateY, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + return target; +} + +template +GenoVector<2, T> translateXY(const GenoVector<2, T> & vector, const GenoVector<2, T> & translate, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + return target; +} + +template +GenoVector<2, T> translateYX(const GenoVector<2, T> & vector, const GenoVector<2, T> & translate, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + return target; +} + +template +GenoVector<2, T> scaleX(const GenoVector<2, T> & vector, T scaleX) { + return { + vector.v[0] * scaleX, + vector.v[1] + }; +} + +template +GenoVector<2, T> scaleY(const GenoVector<2, T> & vector, T scaleY) { + return { + vector.v[0], + vector.v[1] * scaleY + }; +} + +template +GenoVector<2, T> scaleXY(const GenoVector<2, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale + }; +} + +template +GenoVector<2, T> scaleXY(const GenoVector<2, T> & vector, T scaleX, T scaleY) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY + }; +} + +template +GenoVector<2, T> scaleXY(const GenoVector<2, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1] + }; +} + +template +GenoVector<2, T> scaleYX(const GenoVector<2, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0] + }; +} + +template +GenoVector<2, T> scaleX(const GenoVector<2, T> & vector, T scaleX, const GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + return target; +} + +template +GenoVector<2, T> scaleY(const GenoVector<2, T> & vector, T scaleY, const GenoVector<2, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + return target; +} + +template +GenoVector<2, T> scaleXY(const GenoVector<2, T> & vector, T scale, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + return target; +} + +template +GenoVector<2, T> scaleXY(const GenoVector<2, T> & vector, T scaleX, T scaleY, const GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + return target; +} + +template +GenoVector<2, T> scaleXY(const GenoVector<2, T> & vector, const GenoVector<2, T> & scale, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + return target; +} + +template +GenoVector<2, T> scaleYX(const GenoVector<2, T> & vector, const GenoVector<2, T> & scale, GenoVector<2, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + return target; +} + +template +std::ostream & operator<<(std::ostream & stream, const GenoVector<2, T> & vector) { + return stream << '<' << vector.v[0] << ", " << vector.v[1] << '>'; +} + +template using GenoVector2 = GenoVector<2, T>; + +using GenoVector2b = GenoVector2< int8 >; +using GenoVector2ub = GenoVector2; +using GenoVector2s = GenoVector2< int16>; +using GenoVector2us = GenoVector2; +using GenoVector2i = GenoVector2< int32>; +using GenoVector2ui = GenoVector2; +using GenoVector2l = GenoVector2< int64>; +using GenoVector2ul = GenoVector2; +using GenoVector2f = GenoVector2; +using GenoVector2d = GenoVector2; + +#define GNARLY_GENOME_VECTOR2_FORWARD +#endif // GNARLY_GENOME_VECTOR2 \ No newline at end of file diff --git a/src/geno/math/linear/GenoVector3.h b/src/geno/math/linear/GenoVector3.h new file mode 100644 index 0000000..017d40f --- /dev/null +++ b/src/geno/math/linear/GenoVector3.h @@ -0,0 +1,3080 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_VECTOR2_FORWARD +#define GNARLY_GENOME_VECTOR2_FORWARD + +template +class GenoVector<2, T>; + +#endif // GNARLY_GENOME_VECTOR2_FORWARD + +#ifndef GNARLY_GENOME_VECTOR4_FORWARD +#define GNARLY_GENOME_VECTOR4_FORWARD + +template +class GenoVector<4, T>; + +#endif // GNARLY_GENOME_VECTOR4_FORWARD + +#ifndef GNARLY_GENOME_VECTOR3 +#define GNARLY_GENOME_VECTOR3 + +#include +#include + +#include "GenoVector.h" +#include "GenoVector2.h" +#include "GenoVector4.h" +#include "GenoVectorDimensions.h" + +namespace GenoVectorDimensions { + extern GenoVectorDimension<2> z; +} + +template +class GenoVector<3, T> { + private: + bool owner = true; + + void clean() { + if (owner) + delete [] v; + } + + public: + static GenoVector<3, T> * newArray(uint32 length) { + T * v = new T[3 * length]; + GenoVector<3, T> * ret = new GenoVector<3, T>[length]; + ret[0] = GenoVector<3, T>(v); + for (uint32 i = 1; i < length; ++i) + ret[i] = GenoVector<3, T>(v + i * 3, false); + return ret; + } + + T * v; + + GenoVector() : + v(new T[3]()) {} + + GenoVector(T * v, bool owner = true) noexcept : + owner(owner), + v(v) {} + + explicit GenoVector(T value) : + v(new T[3] { value, value, value }) {} + + GenoVector(T x, T y, T z) : + v(new T[3] { x, y, z }) {} + + template + GenoVector(const GenoVector<3, T2> & vector) : + v(new T[3] { + (T) vector.v[0], + (T) vector.v[1], + (T) vector.v[2] + }) {} + + GenoVector(const GenoVector<3, T> & vector) : + v(new T[3] { + vector.v[0], + vector.v[1], + vector.v[2] + }) {} + + GenoVector(GenoVector<3, T> && vector) : + owner(vector.owner), + v(vector.v) { + vector.owner = false; + } + + GenoVector<3, T> & operator=(const GenoVector<3, T> & vector) { + v[0] = vector.v[0]; + v[1] = vector.v[1]; + v[2] = vector.v[2]; + return *this; + } + + GenoVector<3, T> & operator=(GenoVector<3, T> && vector) { + if (owner) { + clean(); + owner = vector.owner; + v = vector.v; + vector.owner = false; + } + else { + v[0] = vector.v[0]; + v[1] = vector.v[1]; + v[2] = vector.v[2]; + } + return *this; + } + + GenoVector<3, T> & operator+=(const GenoVector<3, T> & vector) { + v[0] += vector.v[0]; + v[1] += vector.v[1]; + v[2] += vector.v[2]; + return *this; + } + + GenoVector<3, T> & operator-=(const GenoVector<3, T> & vector) { + v[0] -= vector.v[0]; + v[1] -= vector.v[1]; + v[2] -= vector.v[2]; + return *this; + } + + GenoVector<3, T> & operator*=(T scalar) { + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + return *this; + } + + GenoVector<3, T> & operator*=(const GenoVector<3, T> & vector) { + v[0] *= vector.v[0]; + v[1] *= vector.v[1]; + v[2] *= vector.v[2]; + return *this; + } + + GenoVector<3, T> & operator/=(T scalar) { + v[0] /= scalar; + v[1] /= scalar; + v[2] /= scalar; + return *this; + } + + GenoVector<3, T> & operator/=(const GenoVector<3, T> & vector) { + v[0] /= vector.v[0]; + v[1] /= vector.v[1]; + v[2] /= vector.v[2]; + return *this; + } + + T & operator[](uint32 index) noexcept { + return v[index]; + } + + const T & operator[](uint32 index) const noexcept { + return v[index]; + } + + template + T & operator[](const GenoVectorDimensions::GenoVectorDimension & dimension) noexcept { + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension != 3, "GenoVector<3, T> has no dimension w!"); + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension < 4, "GenoVector<3, T> has no dimension beyond z!"); + return v[GenoVectorDimensions::GenoVectorDimension::dimension]; + } + + template + const T & operator[](const GenoVectorDimensions::GenoVectorDimension & dimension) const noexcept { + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension != 3, "GenoVector<3, T> has no dimension w!"); + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension < 4, "GenoVector<3, T> has no dimension beyond z!"); + return v[GenoVectorDimensions::GenoVectorDimension::dimension]; + } + + T & x() noexcept { + return v[0]; + } + + const T & x() const noexcept { + return v[0]; + } + + T & y() noexcept { + return v[1]; + } + + const T & y() const noexcept { + return v[1]; + } + + T & z() noexcept { + return v[2]; + } + + const T & z() const noexcept { + return v[2]; + } + + T getLength() const { + return sqrt( + v[0] * v[0] + + v[1] * v[1] + + v[2] * v[2] + ); + } + + T getLengthSquared() const { + return ( + v[0] * v[0] + + v[1] * v[1] + + v[2] * v[2] + ); + } + + GenoVector<3, T> & setLength(T length) { + auto scalar = length / getLength(); + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + return *this; + } + + GenoVector<3, T> & normalize() { + auto scalar = 1 / getLength(); + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + return *this; + } + + GenoVector<3, T> & negate() { + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; + return *this; + } + + GenoVector<3, T> & project(const GenoVector<3, T> & projection) { + auto scalar = dot(*this, projection) / projection.getLengthSquared(); + v[0] /= scalar; + v[1] /= scalar; + v[2] /= scalar; + return *this; + } + + GenoVector<3, T> & cross(const GenoVector<3, T> & cross) { + T v0 = v[1] * cross.v[2] - v[2] * cross.v[1]; + T v1 = v[2] * cross.v[0] - v[0] * cross.v[2]; + v[2] = v[0] * cross.v[1] - v[1] * cross.v[0]; + v[0] = v0; + v[1] = v1; + return *this; + } + + GenoVector<3, T> & set(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<3, T> & translate(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + return *this; + } + + GenoVector<3, T> & scale(T scale) { + v[0] *= scale; + v[1] *= scale; + v[2] *= scale; + return *this; + } + + GenoVector<3, T> & scale(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + return *this; + } + + GenoVector<3, T> & setX(T x) { + v[0] = x; + return *this; + } + + GenoVector<3, T> & setY(T y) { + v[1] = y; + return *this; + } + + GenoVector<3, T> & setZ(T z) { + v[2] = z; + return *this; + } + + GenoVector<3, T> & setXY(T x, T y) { + v[0] = x; + v[1] = y; + return *this; + } + + GenoVector<3, T> & setXY(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<3, T> & setXZ(T x, T z) { + v[0] = x; + v[2] = z; + return *this; + } + + GenoVector<3, T> & setXZ(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + return *this; + } + + GenoVector<3, T> & setYX(const GenoVector<2, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + return *this; + } + + GenoVector<3, T> & setYZ(T y, T z) { + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & setYZ(const GenoVector<2, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + return *this; + } + + GenoVector<3, T> & setZX(const GenoVector<2, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + return *this; + } + + GenoVector<3, T> & setZY(const GenoVector<2, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<3, T> & setXYZ(T x, T y, T z) { + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & setXYZ(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<3, T> & setXZY(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<3, T> & setYXZ(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<3, T> & setYZX(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<3, T> & setZXY(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<3, T> & setZYX(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<3, T> & translateX(T translateX) { + v[0] += translateX; + } + + GenoVector<3, T> & translateY(T translateY) { + v[1] += translateY; + } + + GenoVector<3, T> & translateZ(T translateZ) { + v[2] += translateZ; + } + + GenoVector<3, T> & translateXY(T translateX, T translateY) { + v[0] += translateX; + v[1] += translateY; + } + + GenoVector<3, T> & translateXY(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + } + + GenoVector<3, T> & translateXZ(T translateX, T translateZ) { + v[0] += translateX; + v[2] += translateZ; + } + + GenoVector<3, T> & translateXZ(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + } + + GenoVector<3, T> & translateYX(const GenoVector<2, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + } + + GenoVector<3, T> & translateYZ(T translateY, T translateZ) { + v[1] += translateY; + v[2] += translateZ; + } + + GenoVector<3, T> & translateYZ(const GenoVector<2, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + } + + GenoVector<3, T> & translateZX(const GenoVector<2, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + } + + GenoVector<3, T> & translateZY(const GenoVector<2, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + } + + GenoVector<3, T> & translateXYZ(T translateX, T translateY, T translateZ) { + v[0] += translateX; + v[1] += translateY; + v[2] += translateZ; + } + + GenoVector<3, T> & translateXYZ(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<3, T> & translateXZY(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<3, T> & translateYXZ(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<3, T> & translateYZX(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<3, T> & translateZXY(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<3, T> & translateZYX(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<3, T> & rotateX(T rotateX) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto y = v[1] * ( cosX ) + v[2] * (-sinX ); + auto z = v[1] * ( sinX ) + v[2] * ( cosX ); + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateY(T rotateY) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto x = v[0] * ( cosY ) + v[2] * ( sinY ); + auto z = v[0] * (-sinY ) + v[2] * ( cosY ); + v[0] = x; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateZ(T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto x = v[0] * ( cosZ ) + v[1] * (-sinZ ); + auto y = v[0] * ( sinZ ) + v[1] * ( cosZ ); + v[0] = x; + v[1] = y; + return *this; + } + + GenoVector<3, T> & rotateXY(T rotateX, T rotateY) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto x = v[0] * ( cosY ) + v[1] * ( sinY * sinX ) + v[2] * ( sinY * cosX ); + auto y = v[1] * ( cosX ) + v[2] * (-sinX ); + auto z = v[0] * (-sinY ) + v[1] * ( cosY * sinX ) + v[2] * ( cosY * cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateXY(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto x = v[0] * ( cosY ) + v[1] * ( sinY * sinX ) + v[2] * ( sinY * cosX ); + auto y = v[1] * ( cosX ) + v[2] * (-sinX ); + auto z = v[0] * (-sinY ) + v[1] * ( cosY * sinX ) + v[2] * ( cosY * cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateXZ(T rotateX, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto x = v[0] * ( cosZ ) + v[1] * (-sinZ * cosX ) + v[2] * ( sinZ * sinX ); + auto y = v[0] * ( sinZ ) + v[1] * ( cosZ * cosX ) + v[2] * (-cosZ * sinX ); + auto z = v[1] * ( sinX ) + v[2] * ( cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateXZ(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto x = v[0] * ( cosZ ) + v[1] * (-sinZ * cosX ) + v[2] * ( sinZ * sinX ); + auto y = v[0] * ( sinZ ) + v[1] * ( cosZ * cosX ) + v[2] * (-cosZ * sinX ); + auto z = v[1] * ( sinX ) + v[2] * ( cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateYX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto x = v[0] * ( cosY ) + v[2] * ( sinY ); + auto y = v[0] * ( sinX * sinY ) + v[1] * ( cosX ) + v[2] * (-sinX * cosY ); + auto z = v[0] * (-cosX * sinY ) + v[1] * ( sinX ) + v[2] * ( cosX * cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateYZ(T rotateY, T rotateZ) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto x = v[0] * ( cosZ * cosY ) + v[1] * (-sinZ ) + v[2] * ( cosZ * sinY ); + auto y = v[0] * ( sinZ * cosY ) + v[1] * ( cosZ ) + v[2] * ( sinZ * sinY ); + auto z = v[0] * (-sinY ) + v[2] * ( cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateYZ(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto x = v[0] * ( cosZ * cosY ) + v[1] * (-sinZ ) + v[2] * ( cosZ * sinY ); + auto y = v[0] * ( sinZ * cosY ) + v[1] * ( cosZ ) + v[2] * ( sinZ * sinY ); + auto z = v[0] * (-sinY ) + v[2] * ( cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateZX(const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto x = v[0] * ( cosZ ) + v[1] * (-sinZ ); + auto y = v[0] * ( cosX * sinZ ) + v[1] * ( cosX * cosZ ) + v[2] * (-sinX ); + auto z = v[0] * ( sinX * sinZ ) + v[1] * ( sinX * cosZ ) + v[2] * ( cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateZY(const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto x = v[0] * ( cosY * cosZ ) + v[1] * (-cosY * sinZ ) + v[2] * ( sinY ); + auto y = v[0] * ( sinZ ) + v[1] * ( cosZ ); + auto z = v[0] * (-sinY * cosZ ) + v[1] * ( sinY * sinZ ) + v[2] * ( cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateXYZ(T rotateX, T rotateY, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + auto x = v[0] * ( cosZ * cosY ) + v[1] * (-sinZ * cosX + cosZ * sinY * sinX ) + v[2] * ( sinZ * sinX + cosZ * sinY * cosX ); + auto y = v[0] * ( sinZ * cosY ) + v[1] * ( cosZ * cosX + sinZ * sinY * sinX ) + v[2] * (-cosZ * sinX + sinZ * sinY * cosX ); + auto z = v[0] * (-sinY ) + v[1] * ( cosY * sinX ) + v[2] * ( cosY * cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateXYZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto x = v[0] * ( cosZ * cosY ) + v[1] * (-sinZ * cosX + cosZ * sinY * sinX ) + v[2] * ( sinZ * sinX + cosZ * sinY * cosX ); + auto y = v[0] * ( sinZ * cosY ) + v[1] * ( cosZ * cosX + sinZ * sinY * sinX ) + v[2] * (-cosZ * sinX + sinZ * sinY * cosX ); + auto z = v[0] * (-sinY ) + v[1] * ( cosY * sinX ) + v[2] * ( cosY * cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateXZY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto x = v[0] * ( cosY * cosZ ) + v[1] * (-cosY * sinZ * cosX + sinY * sinX ) + v[2] * ( cosY * sinZ * sinX + sinY * cosX ); + auto y = v[0] * ( sinZ ) + v[1] * ( cosZ * cosX ) + v[2] * (-cosZ * sinX ); + auto z = v[0] * (-sinY * cosZ ) + v[1] * ( sinY * sinZ * cosX + cosY * sinX ) + v[2] * (-sinY * sinZ * sinX + cosY * cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateYXZ(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + auto x = v[0] * ( cosZ * cosY - sinZ * sinX * sinY ) + v[1] * (-sinZ * cosX ) + v[2] * ( cosZ * sinY + sinZ * sinX * cosY ); + auto y = v[0] * ( sinZ * cosY + cosZ * sinX * sinY ) + v[1] * ( cosZ * cosX ) + v[2] * ( sinZ * sinY - cosZ * sinX * cosY ); + auto z = v[0] * (-cosX * sinY ) + v[1] * ( sinX ) + v[2] * ( cosX * cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateYZX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + auto x = v[0] * ( cosZ * cosY ) + v[1] * (-sinZ ) + v[2] * ( cosZ * sinY ); + auto y = v[0] * ( cosX * sinZ * cosY + sinX * sinY ) + v[1] * ( cosX * cosZ ) + v[2] * ( cosX * sinZ * sinY - sinX * cosY ); + auto z = v[0] * ( sinX * sinZ * cosY - cosX * sinY ) + v[1] * ( sinX * cosZ ) + v[2] * ( sinX * sinZ * sinY + cosX * cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateZXY(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto x = v[0] * ( cosY * cosZ + sinY * sinX * sinZ ) + v[1] * (-cosY * sinZ + sinY * sinX * cosZ ) + v[2] * ( sinY * cosX ); + auto y = v[0] * ( cosX * sinZ ) + v[1] * ( cosX * cosZ ) + v[2] * (-sinX ); + auto z = v[0] * (-sinY * cosZ + cosY * sinX * sinZ ) + v[1] * ( sinY * sinZ + cosY * sinX * cosZ ) + v[2] * ( cosY * cosX ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & rotateZYX(const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + auto x = v[0] * ( cosY * cosZ ) + v[1] * (-cosY * sinZ ) + v[2] * ( sinY ); + auto y = v[0] * ( sinX * sinY * cosZ + cosX * sinZ ) + v[1] * (-sinX * sinY * sinZ + cosX * cosZ ) + v[2] * (-sinX * cosY ); + auto z = v[0] * (-cosX * sinY * cosZ + sinX * sinZ ) + v[1] * ( cosX * sinY * sinZ + sinX * cosZ ) + v[2] * ( cosX * cosY ); + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<3, T> & scaleX(T scaleX) { + v[0] *= scaleX; + } + + GenoVector<3, T> & scaleY(T scaleY) { + v[1] *= scaleY; + } + + GenoVector<3, T> & scaleZ(T scaleZ) { + v[2] *= scaleZ; + } + + GenoVector<3, T> & scaleXY(T scale) { + v[0] *= scale; + v[1] *= scale; + } + + GenoVector<3, T> & scaleXY(T scaleX, T scaleY) { + v[0] *= scaleX; + v[1] *= scaleY; + } + + GenoVector<3, T> & scaleXY(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + } + + GenoVector<3, T> & scaleXZ(T scale) { + v[0] *= scale; + v[2] *= scale; + } + + GenoVector<3, T> & scaleXZ(T scaleX, T scaleZ) { + v[0] *= scaleX; + v[2] *= scaleZ; + } + + GenoVector<3, T> & scaleXZ(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + } + + GenoVector<3, T> & scaleYX(const GenoVector<2, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + } + + GenoVector<3, T> & scaleYZ(T scale) { + v[1] *= scale; + v[2] *= scale; + } + + GenoVector<3, T> & scaleYZ(T scaleY, T scaleZ) { + v[1] *= scaleY; + v[2] *= scaleZ; + } + + GenoVector<3, T> & scaleYZ(const GenoVector<2, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + } + + GenoVector<3, T> & scaleZX(const GenoVector<2, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + } + + GenoVector<3, T> & scaleZY(const GenoVector<2, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + } + + GenoVector<3, T> & scaleXYZ(T scale) { + v[0] *= scale; + v[1] *= scale; + v[2] *= scale; + } + + GenoVector<3, T> & scaleXYZ(T scaleX, T scaleY, T scaleZ) { + v[0] *= scaleX; + v[1] *= scaleY; + v[2] *= scaleZ; + } + + GenoVector<3, T> & scaleXYZ(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<3, T> & scaleXZY(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<3, T> & scaleYXZ(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<3, T> & scaleYZX(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<3, T> & scaleZXY(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<3, T> & scaleZYX(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + T getX() const { + return v[0]; + } + + T getY() const { + return v[1]; + } + + T getZ() const { + return v[2]; + } + + GenoVector<2, T> getXX() const { + return { v[0], v[0] }; + } + + GenoVector<2, T> getXY() const { + return { v[0], v[1] }; + } + + GenoVector<2, T> getXZ() const { + return { v[0], v[2] }; + } + + GenoVector<2, T> getYX() const { + return { v[1], v[0] }; + } + + GenoVector<2, T> getYY() const { + return { v[1], v[1] }; + } + + GenoVector<2, T> getYZ() const { + return { v[1], v[2] }; + } + + GenoVector<2, T> getZX() const { + return { v[2], v[0] }; + } + + GenoVector<2, T> getZY() const { + return { v[2], v[1] }; + } + + GenoVector<2, T> getZZ() const { + return { v[2], v[2] }; + } + + GenoVector<3, T> getXXX() const { + return { v[0], v[0], v[0] }; + } + + GenoVector<3, T> getXXY() const { + return { v[0], v[0], v[1] }; + } + + GenoVector<3, T> getXXZ() const { + return { v[0], v[0], v[2] }; + } + + GenoVector<3, T> getXYX() const { + return { v[0], v[1], v[0] }; + } + + GenoVector<3, T> getXYY() const { + return { v[0], v[1], v[1] }; + } + + GenoVector<3, T> getXYZ() const { + return { v[0], v[1], v[2] }; + } + + GenoVector<3, T> getXZX() const { + return { v[0], v[2], v[0] }; + } + + GenoVector<3, T> getXZY() const { + return { v[0], v[2], v[1] }; + } + + GenoVector<3, T> getXZZ() const { + return { v[0], v[2], v[2] }; + } + + GenoVector<3, T> getYXX() const { + return { v[1], v[0], v[0] }; + } + + GenoVector<3, T> getYXY() const { + return { v[1], v[0], v[1] }; + } + + GenoVector<3, T> getYXZ() const { + return { v[1], v[0], v[2] }; + } + + GenoVector<3, T> getYYX() const { + return { v[1], v[1], v[0] }; + } + + GenoVector<3, T> getYYY() const { + return { v[1], v[1], v[1] }; + } + + GenoVector<3, T> getYYZ() const { + return { v[1], v[1], v[2] }; + } + + GenoVector<3, T> getYZX() const { + return { v[1], v[2], v[0] }; + } + + GenoVector<3, T> getYZY() const { + return { v[1], v[2], v[1] }; + } + + GenoVector<3, T> getYZZ() const { + return { v[1], v[2], v[2] }; + } + + GenoVector<3, T> getZXX() const { + return { v[2], v[0], v[0] }; + } + + GenoVector<3, T> getZXY() const { + return { v[2], v[0], v[1] }; + } + + GenoVector<3, T> getZXZ() const { + return { v[2], v[0], v[2] }; + } + + GenoVector<3, T> getZYX() const { + return { v[2], v[1], v[0] }; + } + + GenoVector<3, T> getZYY() const { + return { v[2], v[1], v[1] }; + } + + GenoVector<3, T> getZYZ() const { + return { v[2], v[1], v[2] }; + } + + GenoVector<3, T> getZZX() const { + return { v[2], v[2], v[0] }; + } + + GenoVector<3, T> getZZY() const { + return { v[2], v[2], v[1] }; + } + + GenoVector<3, T> getZZZ() const { + return { v[2], v[2], v[2] }; + } + + GenoVector<4, T> getXXXX() const { + return { v[0], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getXXXY() const { + return { v[0], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getXXXZ() const { + return { v[0], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getXXYX() const { + return { v[0], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getXXYY() const { + return { v[0], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getXXYZ() const { + return { v[0], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getXXZX() const { + return { v[0], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getXXZY() const { + return { v[0], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getXXZZ() const { + return { v[0], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getXYXX() const { + return { v[0], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getXYXY() const { + return { v[0], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getXYXZ() const { + return { v[0], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getXYYX() const { + return { v[0], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getXYYY() const { + return { v[0], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getXYYZ() const { + return { v[0], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getXYZX() const { + return { v[0], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getXYZY() const { + return { v[0], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getXYZZ() const { + return { v[0], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getXZXX() const { + return { v[0], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getXZXY() const { + return { v[0], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getXZXZ() const { + return { v[0], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getXZYX() const { + return { v[0], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getXZYY() const { + return { v[0], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getXZYZ() const { + return { v[0], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getXZZX() const { + return { v[0], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getXZZY() const { + return { v[0], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getXZZZ() const { + return { v[0], v[2], v[2], v[2] }; + } + + GenoVector<4, T> getYXXX() const { + return { v[1], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getYXXY() const { + return { v[1], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getYXXZ() const { + return { v[1], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getYXYX() const { + return { v[1], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getYXYY() const { + return { v[1], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getYXYZ() const { + return { v[1], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getYXZX() const { + return { v[1], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getYXZY() const { + return { v[1], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getYXZZ() const { + return { v[1], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getYYXX() const { + return { v[1], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getYYXY() const { + return { v[1], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getYYXZ() const { + return { v[1], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getYYYX() const { + return { v[1], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getYYYY() const { + return { v[1], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getYYYZ() const { + return { v[1], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getYYZX() const { + return { v[1], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getYYZY() const { + return { v[1], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getYYZZ() const { + return { v[1], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getYZXX() const { + return { v[1], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getYZXY() const { + return { v[1], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getYZXZ() const { + return { v[1], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getYZYX() const { + return { v[1], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getYZYY() const { + return { v[1], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getYZYZ() const { + return { v[1], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getYZZX() const { + return { v[1], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getYZZY() const { + return { v[1], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getYZZZ() const { + return { v[1], v[2], v[2], v[2] }; + } + + GenoVector<4, T> getZXXX() const { + return { v[2], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getZXXY() const { + return { v[2], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getZXXZ() const { + return { v[2], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getZXYX() const { + return { v[2], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getZXYY() const { + return { v[2], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getZXYZ() const { + return { v[2], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getZXZX() const { + return { v[2], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getZXZY() const { + return { v[2], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getZXZZ() const { + return { v[2], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getZYXX() const { + return { v[2], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getZYXY() const { + return { v[2], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getZYXZ() const { + return { v[2], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getZYYX() const { + return { v[2], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getZYYY() const { + return { v[2], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getZYYZ() const { + return { v[2], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getZYZX() const { + return { v[2], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getZYZY() const { + return { v[2], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getZYZZ() const { + return { v[2], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getZZXX() const { + return { v[2], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getZZXY() const { + return { v[2], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getZZXZ() const { + return { v[2], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getZZYX() const { + return { v[2], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getZZYY() const { + return { v[2], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getZZYZ() const { + return { v[2], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getZZZX() const { + return { v[2], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getZZZY() const { + return { v[2], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getZZZZ() const { + return { v[2], v[2], v[2], v[2] }; + } + + virtual ~GenoVector() noexcept { + clean(); + } +}; + +template +GenoVector<3, T> operator-(const GenoVector<3, T> & vector) { + return { + -vector.v[0], + -vector.v[1], + -vector.v[2] + }; +} + +template +GenoVector<3, T> operator+(const GenoVector<3, T> & left, const GenoVector<3, T> & right) { + return { + left.v[0] + right.v[0], + left.v[1] + right.v[1], + left.v[2] + right.v[2] + }; +} + +template +GenoVector<3, T> operator-(const GenoVector<3, T> & left, const GenoVector<3, T> & right) { + return { + left.v[0] - right.v[0], + left.v[1] - right.v[1], + left.v[2] - right.v[2] + }; +} + +template +GenoVector<3, T> operator*(T left, const GenoVector<3, T> & right) { + return { + left * right.v[0], + left * right.v[1], + left * right.v[2] + }; +} + +template +GenoVector<3, T> operator*(const GenoVector<3, T> & left, T right) { + return { + left.v[0] * right, + left.v[1] * right, + left.v[2] * right + }; +} + +template +GenoVector<3, T> operator*(const GenoVector<3, T> & left, const GenoVector<3, T> & right) { + return { + left.v[0] * right.v[0], + left.v[1] * right.v[1], + left.v[2] * right.v[2] + }; +} + +template +GenoVector<3, T> operator/(const GenoVector<3, T> & left, T right) { + return { + left.v[0] / right, + left.v[1] / right, + left.v[2] / right + }; +} + +template +GenoVector<3, T> operator/(const GenoVector<3, T> & left, const GenoVector<3, T> & right) { + return { + left.v[0] / right.v[0], + left.v[1] / right.v[1], + left.v[2] / right.v[2] + }; +} + +template +GenoVector<4, T> operator|(T left, const GenoVector<3, T> & right) { + return { + left, + right.v[0], + right.v[1], + right.v[2] + }; +} + +template +GenoVector<4, T> operator|(const GenoVector<3, T> & left, T right) { + return { + left.v[0], + left.v[1], + left.v[2], + right + }; +} + +template +GenoVector<3, T> setLength(const GenoVector<3, T> & vector, T length) { + auto scalar = length / vector.getLength(); + return { + vector.v[0] * scalar, + vector.v[1] * scalar, + vector.v[2] * scalar + }; +} + +template +GenoVector<3, T> & setLength(const GenoVector<3, T> & vector, T length, GenoVector<3, T> & target) { + auto scalar = length / vector.getLength(); + target.v[0] = vector.v[0] * scalar; + target.v[1] = vector.v[1] * scalar; + target.v[2] = vector.v[2] * scalar; + return target; +} + +template +GenoVector<3, T> normalize(const GenoVector<3, T> & vector) { + auto scalar = 1 / vector.getLength(); + return { + vector.v[0] * scalar, + vector.v[1] * scalar, + vector.v[2] * scalar + }; +} + +template +GenoVector<3, T> & normalize(const GenoVector<3, T> & vector, GenoVector<3, T> & target) { + auto scalar = 1 / vector.getLength(); + target.v[0] = vector.v[0] * scalar; + target.v[1] = vector.v[1] * scalar; + target.v[2] = vector.v[2] * scalar; + return target; +} + +template +GenoVector<3, T> negate(const GenoVector<3, T> & vector) { + return { + -vector.v[0], + -vector.v[1], + -vector.v[2] + }; +} + +template +GenoVector<3, T> & negate(const GenoVector<3, T> & vector, GenoVector<3, T> & target) { + target.v[0] = -vector.v[0]; + target.v[1] = -vector.v[1]; + target.v[2] = -vector.v[2]; + return target; +} + +template +T dot(const GenoVector<3, T> & left, const GenoVector<3, T> & right) { + return ( + left.v[0] * right.v[0] + + left.v[1] * right.v[1] + + left.v[2] * right.v[2] + ); +} + +template +GenoVector<3, T> project(const GenoVector<3, T> & vector, const GenoVector<3, T> & projection) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + return { + scalar * projection.v[0], + scalar * projection.v[1], + scalar * projection.v[2] + }; +} + +template +GenoVector<3, T> & project(const GenoVector<3, T> & vector, const GenoVector<3, T> & projection, GenoVector<3, T> & target) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + target.v[0] = scalar * projection.v[0]; + target.v[1] = scalar * projection.v[1]; + target.v[2] = scalar * projection.v[2]; + return target; +} + +template +GenoVector<3, T> cross(const GenoVector<3, T> & vector, const GenoVector<3, T> & cross) { + return { + vector.v[1] * cross.v[2] - vector.v[2] * cross.v[1], + vector.v[2] * cross.v[0] - vector.v[0] * cross.v[2], + vector.v[0] * cross.v[1] - vector.v[1] * cross.v[0] + }; +} + +template +GenoVector<3, T> & cross(const GenoVector<3, T> & vector, const GenoVector<3, T> & cross, GenoVector<3, T> & target) { + target.v[0] = vector.v[1] * cross.v[2] - vector.v[2] * cross.v[1]; + target.v[1] = vector.v[2] * cross.v[0] - vector.v[0] * cross.v[2]; + target.v[2] = vector.v[0] * cross.v[1] - vector.v[1] * cross.v[0]; + return target; +} + +template +GenoVector<3, T> translate(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2] + }; +} + +template +GenoVector<3, T> & translate(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + return target; +} + +template +GenoVector<3, T> scale(const GenoVector<3, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2] * scale + }; +} + +template +GenoVector<3, T> & scale(const GenoVector<3, T> & vector, T scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + return target; +} + +template +GenoVector<3, T> scale(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2] + }; +} + +template +GenoVector<3, T> & scale(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + return target; +} + +template +GenoVector<3, T> setX(const GenoVector<3, T> & vector, T x) { + return { + x, + vector.v[1], + vector.v[2] + }; +} + +template +GenoVector<3, T> setY(const GenoVector<3, T> & vector, T y) { + return { + vector.v[0], + y, + vector.v[2] + }; +} + +template +GenoVector<3, T> setZ(const GenoVector<3, T> & vector, T z) { + return { + vector.v[0], + vector.v[1], + z + }; +} + +template +GenoVector<3, T> setXY(const GenoVector<3, T> & vector, T x, T y) { + return { + x, + y, + vector.v[2] + }; +} + +template +GenoVector<3, T> setXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[0], + set.v[1], + vector.v[2] + }; +} + +template +GenoVector<3, T> setXZ(const GenoVector<3, T> & vector, T x, T z) { + return { + x, + vector.v[1], + z + }; +} + +template +GenoVector<3, T> setXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[0], + vector.v[1], + set.v[1] + }; +} + +template +GenoVector<3, T> setYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[1], + set.v[0], + vector.v[2] + }; +} + +template +GenoVector<3, T> setYZ(const GenoVector<3, T> & vector, T y, T z) { + return { + vector.v[0], + y, + z + }; +} + +template +GenoVector<3, T> setYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + set.v[0], + set.v[1] + }; +} + +template +GenoVector<3, T> setZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[1], + vector.v[1], + set.v[0] + }; +} + +template +GenoVector<3, T> setZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + set.v[1], + set.v[0] + }; +} + +template +GenoVector<3, T> setX(const GenoVector<3, T> & vector, T x, GenoVector<3, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> setY(const GenoVector<3, T> & vector, T y, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> setZ(const GenoVector<3, T> & vector, T z, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = z; + return target; +} + +template +GenoVector<3, T> setXY(const GenoVector<3, T> & vector, T x, T y, GenoVector<3, T> & target) { + target.v[0] = x; + target.v[1] = y; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> setXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & set, GenoVector<3, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = set.v[1]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> setXZ(const GenoVector<3, T> & vector, T x, T z, GenoVector<3, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + target.v[2] = z; + return target; +} + +template +GenoVector<3, T> setXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & set, GenoVector<3, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[1]; + return target; +} + +template +GenoVector<3, T> setYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & set, GenoVector<3, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = set.v[0]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> setYZ(const GenoVector<3, T> & vector, T y, T z, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + target.v[2] = z; + return target; +} + +template +GenoVector<3, T> setYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & set, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[0]; + target.v[2] = set.v[1]; + return target; +} + +template +GenoVector<3, T> setZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & set, GenoVector<3, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[0]; + return target; +} + +template +GenoVector<3, T> setZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & set, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[1]; + target.v[2] = set.v[0]; + return target; +} + +template +GenoVector<3, T> translateX(const GenoVector<3, T> & vector, T translateX) { + return { + vector.v[0] + translateX, + vector.v[1], + vector.v[2] + }; +} + +template +GenoVector<3, T> translateY(const GenoVector<3, T> & vector, T translateY) { + return { + vector.v[0], + vector.v[1] + translateY, + vector.v[2] + }; +} + +template +GenoVector<3, T> translateZ(const GenoVector<3, T> & vector, T translateZ) { + return { + vector.v[0], + vector.v[1], + vector.v[2] + translateZ + }; +} + +template +GenoVector<3, T> translateXY(const GenoVector<3, T> & vector, T translateX, T translateY) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY, + vector.v[2] + }; +} + +template +GenoVector<3, T> translateXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + }; +} + +template +GenoVector<3, T> translateXZ(const GenoVector<3, T> & vector, T translateX, T translateZ) { + return { + vector.v[0] + translateX, + vector.v[1], + vector.v[2] + translateZ + }; +} + +template +GenoVector<3, T> translateXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1], + vector.v[2] + translate.v[1] + }; +} + +template +GenoVector<3, T> translateYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2] + }; +} + +template +GenoVector<3, T> translateYZ(const GenoVector<3, T> & vector, T translateY, T translateZ) { + return { + vector.v[0], + vector.v[1] + translateY, + vector.v[2] + translateZ + }; +} + +template +GenoVector<3, T> translateYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1] + }; +} + +template +GenoVector<3, T> translateZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1], + vector.v[2] + translate.v[0] + }; +} + +template +GenoVector<3, T> translateZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0] + }; +} + +template +GenoVector<3, T> translateXYZ(const GenoVector<3, T> & vector, T translateX, T translateY, T translateZ) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY, + vector.v[2] + translateZ + }; +} + +template +GenoVector<3, T> translateXYZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2] + }; +} + +template +GenoVector<3, T> translateXZY(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[1] + }; +} + +template +GenoVector<3, T> translateYXZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[2] + }; +} + +template +GenoVector<3, T> translateYZX(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1] + }; +} + +template +GenoVector<3, T> translateZXY(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[0] + }; +} + +template +GenoVector<3, T> translateZYX(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0] + }; +} + +template +GenoVector<3, T> translateX(const GenoVector<3, T> & vector, T translateX, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> translateY(const GenoVector<3, T> & vector, T translateY, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> translateZ(const GenoVector<3, T> & vector, T translateZ, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translateZ; + return target; +} + +template +GenoVector<3, T> translateXY(const GenoVector<3, T> & vector, T translateX, T translateY, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> translateXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> translateXZ(const GenoVector<3, T> & vector, T translateX, T translateZ, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translateZ; + return target; +} + +template +GenoVector<3, T> translateXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[1]; + return target; +} + +template +GenoVector<3, T> translateYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> translateYZ(const GenoVector<3, T> & vector, T translateY, T translateZ, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2] + translateZ; + return target; +} + +template +GenoVector<3, T> translateYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + return target; +} + +template +GenoVector<3, T> translateZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + return target; +} + +template +GenoVector<3, T> translateZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + return target; +} + +template +GenoVector<3, T> translateXYZ(const GenoVector<3, T> & vector, T translateX, T translateY, T translateZ, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2] + translateZ; + return target; +} + +template +GenoVector<3, T> translateXYZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + return target; +} + +template +GenoVector<3, T> translateXZY(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[1]; + return target; +} + +template +GenoVector<3, T> translateYXZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[2]; + return target; +} + +template +GenoVector<3, T> translateYZX(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + return target; +} + +template +GenoVector<3, T> translateZXY(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[0]; + return target; +} + +template +GenoVector<3, T> translateZYX(const GenoVector<3, T> & vector, const GenoVector<3, T> & translate, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + return target; +} + +template +GenoVector<3, T> & rotateX(const GenoVector<3, T> & vector, T rotateX) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + return { + vector.v[0], + vector.v[1] * ( cosX ) + vector.v[2] * (-sinX ), + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX ) + }; +} + +template +GenoVector<3, T> & rotateY(const GenoVector<3, T> & vector, T rotateY) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + return { + vector.v[0] * ( cosY ) + vector.v[2] * ( sinY ), + vector.v[1], + vector.v[0] * (-sinY ) + vector.v[2] * ( cosY ) + }; +} + +template +GenoVector<3, T> & rotateZ(const GenoVector<3, T> & vector, T rotateZ) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return { + vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ ), + vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ ), + vector.v[2] + }; +} + +template +GenoVector<3, T> & rotateXY(const GenoVector<3, T> & vector, T rotateX, T rotateY) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + return { + vector.v[0] * ( cosY ) + vector.v[1] * ( sinY * sinX ) + vector.v[2] * ( sinY * cosX ), + vector.v[1] * ( cosX ) + vector.v[2] * (-sinX ), + vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ) + }; +} + +template +GenoVector<3, T> & rotateXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + return { + vector.v[0] * ( cosY ) + vector.v[1] * ( sinY * sinX ) + vector.v[2] * ( sinY * cosX ), + vector.v[1] * ( cosX ) + vector.v[2] * (-sinX ), + vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ) + }; +} + +template +GenoVector<3, T> & rotateXZ(const GenoVector<3, T> & vector, T rotateX, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return { + vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ * cosX ) + vector.v[2] * ( sinZ * sinX ), + vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * (-cosZ * sinX ), + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX ) + }; +} + +template +GenoVector<3, T> & rotateXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return { + vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ * cosX ) + vector.v[2] * ( sinZ * sinX ), + vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * (-cosZ * sinX ), + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX ) + }; +} + +template +GenoVector<3, T> & rotateYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + return { + vector.v[0] * ( cosY ) + vector.v[2] * ( sinY ), + vector.v[0] * ( sinX * sinY ) + vector.v[1] * ( cosX ) + vector.v[2] * (-sinX * cosY ), + vector.v[0] * (-cosX * sinY ) + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX * cosY ) + }; +} + +template +GenoVector<3, T> & rotateYZ(const GenoVector<3, T> & vector, T rotateY, T rotateZ) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return { + vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ ) + vector.v[2] * ( cosZ * sinY ), + vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ ) + vector.v[2] * ( sinZ * sinY ), + vector.v[0] * (-sinY ) + vector.v[2] * ( cosY ) + }; +} + +template +GenoVector<3, T> & rotateYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return { + vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ ) + vector.v[2] * ( cosZ * sinY ), + vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ ) + vector.v[2] * ( sinZ * sinY ), + vector.v[0] * (-sinY ) + vector.v[2] * ( cosY ) + }; +} + +template +GenoVector<3, T> & rotateZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return { + vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ ), + vector.v[0] * ( cosX * sinZ ) + vector.v[1] * ( cosX * cosZ ) + vector.v[2] * (-sinX ), + vector.v[0] * ( sinX * sinZ ) + vector.v[1] * ( sinX * cosZ ) + vector.v[2] * ( cosX ) + }; +} + +template +GenoVector<3, T> & rotateZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return { + vector.v[0] * ( cosY * cosZ ) + vector.v[1] * (-cosY * sinZ ) + vector.v[2] * ( sinY ), + vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ ), + vector.v[0] * (-sinY * cosZ ) + vector.v[1] * ( sinY * sinZ ) + vector.v[2] * ( cosY ) + }; +} + +template +GenoVector<3, T> & rotateXYZ(const GenoVector<3, T> & vector, T rotateX, T rotateY, T rotateZ) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + return { + vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ * cosX + cosZ * sinY * sinX ) + vector.v[2] * ( sinZ * sinX + cosZ * sinY * cosX ), + vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ * cosX + sinZ * sinY * sinX ) + vector.v[2] * (-cosZ * sinX + sinZ * sinY * cosX ), + vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ) + }; +} + +template +GenoVector<3, T> & rotateXYZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + return { + vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ * cosX + cosZ * sinY * sinX ) + vector.v[2] * ( sinZ * sinX + cosZ * sinY * cosX ), + vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ * cosX + sinZ * sinY * sinX ) + vector.v[2] * (-cosZ * sinX + sinZ * sinY * cosX ), + vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ) + }; +} + +template +GenoVector<3, T> & rotateXZY(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return { + vector.v[0] * ( cosY * cosZ ) + vector.v[1] * (-cosY * sinZ * cosX + sinY * sinX ) + vector.v[2] * ( cosY * sinZ * sinX + sinY * cosX ), + vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * (-cosZ * sinX ), + vector.v[0] * (-sinY * cosZ ) + vector.v[1] * ( sinY * sinZ * cosX + cosY * sinX ) + vector.v[2] * (-sinY * sinZ * sinX + cosY * cosX ) + }; +} + +template +GenoVector<3, T> & rotateYXZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + return { + vector.v[0] * ( cosZ * cosY - sinZ * sinX * sinY ) + vector.v[1] * (-sinZ * cosX ) + vector.v[2] * ( cosZ * sinY + sinZ * sinX * cosY ), + vector.v[0] * ( sinZ * cosY + cosZ * sinX * sinY ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * ( sinZ * sinY - cosZ * sinX * cosY ), + vector.v[0] * (-cosX * sinY ) + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX * cosY ) + }; +} + +template +GenoVector<3, T> & rotateYZX(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + return { + vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ ) + vector.v[2] * ( cosZ * sinY ), + vector.v[0] * ( cosX * sinZ * cosY + sinX * sinY ) + vector.v[1] * ( cosX * cosZ ) + vector.v[2] * ( cosX * sinZ * sinY - sinX * cosY ), + vector.v[0] * ( sinX * sinZ * cosY - cosX * sinY ) + vector.v[1] * ( sinX * cosZ ) + vector.v[2] * ( sinX * sinZ * sinY + cosX * cosY ) + }; +} + +template +GenoVector<3, T> & rotateZXY(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return { + vector.v[0] * ( cosY * cosZ + sinY * sinX * sinZ ) + vector.v[1] * (-cosY * sinZ + sinY * sinX * cosZ ) + vector.v[2] * ( sinY * cosX ), + vector.v[0] * ( cosX * sinZ ) + vector.v[1] * ( cosX * cosZ ) + vector.v[2] * (-sinX ), + vector.v[0] * (-sinY * cosZ + cosY * sinX * sinZ ) + vector.v[1] * ( sinY * sinZ + cosY * sinX * cosZ ) + vector.v[2] * ( cosY * cosX ) + }; +} + +template +GenoVector<3, T> & rotateZYX(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + return { + vector.v[0] * ( cosY * cosZ ) + vector.v[1] * (-cosY * sinZ ) + vector.v[2] * ( sinY ), + vector.v[0] * ( sinX * sinY * cosZ + cosX * sinZ ) + vector.v[1] * (-sinX * sinY * sinZ + cosX * cosZ ) + vector.v[2] * (-sinX * cosY ), + vector.v[0] * (-cosX * sinY * cosZ + sinX * sinZ ) + vector.v[1] * ( cosX * sinY * sinZ + sinX * cosZ ) + vector.v[2] * ( cosX * cosY ) + }; +} + +template +GenoVector<3, T> & rotateX(const GenoVector<3, T> & vector, T rotateX, GenoVector<3, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * ( cosX ) + vector.v[2] * (-sinX ); + target.v[2] = vector.v[1] * ( sinX ) + vector.v[2] * ( cosX ); + return target; +} + +template +GenoVector<3, T> & rotateY(const GenoVector<3, T> & vector, T rotateY, GenoVector<3, T> & target) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + target.v[0] = vector.v[0] * ( cosY ) + vector.v[2] * ( sinY ); + target.v[1] = vector.v[1]; + target.v[2] = vector.v[0] * (-sinY ) + vector.v[2] * ( cosY ); + return target; +} + +template +GenoVector<3, T> & rotateZ(const GenoVector<3, T> & vector, T rotateZ, GenoVector<3, T> & target) { + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + target.v[0] = vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ ); + target.v[1] = vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ ); + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> & rotateXY(const GenoVector<3, T> & vector, T rotateX, T rotateY, GenoVector<3, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + target.v[0] = vector.v[0] * ( cosY ) + vector.v[1] * ( sinY * sinX ) + vector.v[2] * ( sinY * cosX ); + target.v[1] = vector.v[1] * ( cosX ) + vector.v[2] * (-sinX ); + target.v[2] = vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ); + return target; +} + +template +GenoVector<3, T> & rotateXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + target.v[0] = vector.v[0] * ( cosY ) + vector.v[1] * ( sinY * sinX ) + vector.v[2] * ( sinY * cosX ); + target.v[1] = vector.v[1] * ( cosX ) + vector.v[2] * (-sinX ); + target.v[2] = vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ); + return target; +} + +template +GenoVector<3, T> & rotateXZ(const GenoVector<3, T> & vector, T rotateX, T rotateZ, GenoVector<3, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + target.v[0] = vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ * cosX ) + vector.v[2] * ( sinZ * sinX ); + target.v[1] = vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * (-cosZ * sinX ); + target.v[2] = vector.v[1] * ( sinX ) + vector.v[2] * ( cosX ); + return target; +} + +template +GenoVector<3, T> & rotateXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + target.v[0] = vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ * cosX ) + vector.v[2] * ( sinZ * sinX ); + target.v[1] = vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * (-cosZ * sinX ); + target.v[2] = vector.v[1] * ( sinX ) + vector.v[2] * ( cosX ); + return target; +} + +template +GenoVector<3, T> & rotateYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + target.v[0] = vector.v[0] * ( cosY ) + vector.v[2] * ( sinY ); + target.v[1] = vector.v[0] * ( sinX * sinY ) + vector.v[1] * ( cosX ) + vector.v[2] * (-sinX * cosY ); + target.v[2] = vector.v[0] * (-cosX * sinY ) + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX * cosY ); + return target; +} + +template +GenoVector<3, T> & rotateYZ(const GenoVector<3, T> & vector, T rotateY, T rotateZ, GenoVector<3, T> & target) { + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + target.v[0] = vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ ) + vector.v[2] * ( cosZ * sinY ); + target.v[1] = vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ ) + vector.v[2] * ( sinZ * sinY ); + target.v[2] = vector.v[0] * (-sinY ) + vector.v[2] * ( cosY ); + return target; +} + +template +GenoVector<3, T> & rotateYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate, GenoVector<3, T> & target) { + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + target.v[0] = vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ ) + vector.v[2] * ( cosZ * sinY ); + target.v[1] = vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ ) + vector.v[2] * ( sinZ * sinY ); + target.v[2] = vector.v[0] * (-sinY ) + vector.v[2] * ( cosY ); + return target; +} + +template +GenoVector<3, T> & rotateZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + target.v[0] = vector.v[0] * ( cosZ ) + vector.v[1] * (-sinZ ); + target.v[1] = vector.v[0] * ( cosX * sinZ ) + vector.v[1] * ( cosX * cosZ ) + vector.v[2] * (-sinX ); + target.v[2] = vector.v[0] * ( sinX * sinZ ) + vector.v[1] * ( sinX * cosZ ) + vector.v[2] * ( cosX ); + return target; +} + +template +GenoVector<3, T> & rotateZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & rotate, GenoVector<3, T> & target) { + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + target.v[0] = vector.v[0] * ( cosY * cosZ ) + vector.v[1] * (-cosY * sinZ ) + vector.v[2] * ( sinY ); + target.v[1] = vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ ); + target.v[2] = vector.v[0] * (-sinY * cosZ ) + vector.v[1] * ( sinY * sinZ ) + vector.v[2] * ( cosY ); + return target; +} + +template +GenoVector<3, T> & rotateXYZ(const GenoVector<3, T> & vector, T rotateX, T rotateY, T rotateZ, GenoVector<3, T> & target) { + auto sinX = sin(rotateX); + auto cosX = cos(rotateX); + auto sinY = sin(rotateY); + auto cosY = cos(rotateY); + auto sinZ = sin(rotateZ); + auto cosZ = cos(rotateZ); + target.v[0] = vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ * cosX + cosZ * sinY * sinX ) + vector.v[2] * ( sinZ * sinX + cosZ * sinY * cosX ); + target.v[1] = vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ * cosX + sinZ * sinY * sinX ) + vector.v[2] * (-cosZ * sinX + sinZ * sinY * cosX ); + target.v[2] = vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ); + return target; +} + +template +GenoVector<3, T> & rotateXYZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + target.v[0] = vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ * cosX + cosZ * sinY * sinX ) + vector.v[2] * ( sinZ * sinX + cosZ * sinY * cosX ); + target.v[1] = vector.v[0] * ( sinZ * cosY ) + vector.v[1] * ( cosZ * cosX + sinZ * sinY * sinX ) + vector.v[2] * (-cosZ * sinX + sinZ * sinY * cosX ); + target.v[2] = vector.v[0] * (-sinY ) + vector.v[1] * ( cosY * sinX ) + vector.v[2] * ( cosY * cosX ); + return target; +} + +template +GenoVector<3, T> & rotateXZY(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[0]); + auto cosX = cos(rotate.v[0]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + target.v[0] = vector.v[0] * ( cosY * cosZ ) + vector.v[1] * (-cosY * sinZ * cosX + sinY * sinX ) + vector.v[2] * ( cosY * sinZ * sinX + sinY * cosX ); + target.v[1] = vector.v[0] * ( sinZ ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * (-cosZ * sinX ); + target.v[2] = vector.v[0] * (-sinY * cosZ ) + vector.v[1] * ( sinY * sinZ * cosX + cosY * sinX ) + vector.v[2] * (-sinY * sinZ * sinX + cosY * cosX ); + return target; +} + +template +GenoVector<3, T> & rotateYXZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[2]); + auto cosZ = cos(rotate.v[2]); + target.v[0] = vector.v[0] * ( cosZ * cosY - sinZ * sinX * sinY ) + vector.v[1] * (-sinZ * cosX ) + vector.v[2] * ( cosZ * sinY + sinZ * sinX * cosY ); + target.v[1] = vector.v[0] * ( sinZ * cosY + cosZ * sinX * sinY ) + vector.v[1] * ( cosZ * cosX ) + vector.v[2] * ( sinZ * sinY - cosZ * sinX * cosY ); + target.v[2] = vector.v[0] * (-cosX * sinY ) + vector.v[1] * ( sinX ) + vector.v[2] * ( cosX * cosY ); + return target; +} + +template +GenoVector<3, T> & rotateYZX(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[0]); + auto cosY = cos(rotate.v[0]); + auto sinZ = sin(rotate.v[1]); + auto cosZ = cos(rotate.v[1]); + target.v[0] = vector.v[0] * ( cosZ * cosY ) + vector.v[1] * (-sinZ ) + vector.v[2] * ( cosZ * sinY ); + target.v[1] = vector.v[0] * ( cosX * sinZ * cosY + sinX * sinY ) + vector.v[1] * ( cosX * cosZ ) + vector.v[2] * ( cosX * sinZ * sinY - sinX * cosY ); + target.v[2] = vector.v[0] * ( sinX * sinZ * cosY - cosX * sinY ) + vector.v[1] * ( sinX * cosZ ) + vector.v[2] * ( sinX * sinZ * sinY + cosX * cosY ); + return target; +} + +template +GenoVector<3, T> & rotateZXY(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[1]); + auto cosX = cos(rotate.v[1]); + auto sinY = sin(rotate.v[2]); + auto cosY = cos(rotate.v[2]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + target.v[0] = vector.v[0] * ( cosY * cosZ + sinY * sinX * sinZ ) + vector.v[1] * (-cosY * sinZ + sinY * sinX * cosZ ) + vector.v[2] * ( sinY * cosX ); + target.v[1] = vector.v[0] * ( cosX * sinZ ) + vector.v[1] * ( cosX * cosZ ) + vector.v[2] * (-sinX ); + target.v[2] = vector.v[0] * (-sinY * cosZ + cosY * sinX * sinZ ) + vector.v[1] * ( sinY * sinZ + cosY * sinX * cosZ ) + vector.v[2] * ( cosY * cosX ); + return target; +} + +template +GenoVector<3, T> & rotateZYX(const GenoVector<3, T> & vector, const GenoVector<3, T> & rotate, GenoVector<3, T> & target) { + auto sinX = sin(rotate.v[2]); + auto cosX = cos(rotate.v[2]); + auto sinY = sin(rotate.v[1]); + auto cosY = cos(rotate.v[1]); + auto sinZ = sin(rotate.v[0]); + auto cosZ = cos(rotate.v[0]); + target.v[0] = vector.v[0] * ( cosY * cosZ ) + vector.v[1] * (-cosY * sinZ ) + vector.v[2] * ( sinY ); + target.v[1] = vector.v[0] * ( sinX * sinY * cosZ + cosX * sinZ ) + vector.v[1] * (-sinX * sinY * sinZ + cosX * cosZ ) + vector.v[2] * (-sinX * cosY ); + target.v[2] = vector.v[0] * (-cosX * sinY * cosZ + sinX * sinZ ) + vector.v[1] * ( cosX * sinY * sinZ + sinX * cosZ ) + vector.v[2] * ( cosX * cosY ); + return target; +} + +template +GenoVector<3, T> scaleX(const GenoVector<3, T> & vector, T scaleX) { + return { + vector.v[0] * scaleX, + vector.v[1], + vector.v[2] + }; +} + +template +GenoVector<3, T> scaleY(const GenoVector<3, T> & vector, T scaleY) { + return { + vector.v[0], + vector.v[1] * scaleY, + vector.v[2] + }; +} + +template +GenoVector<3, T> scaleZ(const GenoVector<3, T> & vector, T scaleZ) { + return { + vector.v[0], + vector.v[1], + vector.v[2] * scaleZ + }; +} + +template +GenoVector<3, T> scaleXY(const GenoVector<3, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2] + }; +} + +template +GenoVector<3, T> scaleXY(const GenoVector<3, T> & vector, T scaleX, T scaleY) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY, + vector.v[2] + }; +} + +template +GenoVector<3, T> scaleXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] + }; +} + +template +GenoVector<3, T> scaleXZ(const GenoVector<3, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1], + vector.v[2] * scale + }; +} + +template +GenoVector<3, T> scaleXZ(const GenoVector<3, T> & vector, T scaleX, T scaleZ) { + return { + vector.v[0] * scaleX, + vector.v[1], + vector.v[2] * scaleZ + }; +} + +template +GenoVector<3, T> scaleXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1], + vector.v[2] * scale.v[1] + }; +} + +template +GenoVector<3, T> scaleYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2] + }; +} + +template +GenoVector<3, T> scaleYZ(const GenoVector<3, T> & vector, T scale) { + return { + vector.v[0], + vector.v[1] * scale, + vector.v[2] * scale + }; +} + +template +GenoVector<3, T> scaleYZ(const GenoVector<3, T> & vector, T scaleY, T scaleZ) { + return { + vector.v[0], + vector.v[1] * scaleY, + vector.v[2] * scaleZ + }; +} + +template +GenoVector<3, T> scaleYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1] + }; +} + +template +GenoVector<3, T> scaleZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1], + vector.v[2] * scale.v[0] + }; +} + +template +GenoVector<3, T> scaleZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0] + }; +} + +template +GenoVector<3, T> scaleXYZ(const GenoVector<3, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2] * scale + }; +} + +template +GenoVector<3, T> scaleXYZ(const GenoVector<3, T> & vector, T scaleX, T scaleY, T scaleZ) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY, + vector.v[2] * scaleZ + }; +} + +template +GenoVector<3, T> scaleXYZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2] + }; +} + +template +GenoVector<3, T> scaleXZY(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[1] + }; +} + +template +GenoVector<3, T> scaleYXZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[2] + }; +} + +template +GenoVector<3, T> scaleYZX(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1] + }; +} + +template +GenoVector<3, T> scaleZXY(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[0] + }; +} + +template +GenoVector<3, T> scaleZYX(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0] + }; +} + +template +GenoVector<3, T> scaleX(const GenoVector<3, T> & vector, T scaleX, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> scaleY(const GenoVector<3, T> & vector, T scaleY, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> scaleZ(const GenoVector<3, T> & vector, T scaleZ, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scaleZ; + return target; +} + +template +GenoVector<3, T> scaleXY(const GenoVector<3, T> & vector, T scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> scaleXY(const GenoVector<3, T> & vector, T scaleX, T scaleY, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> scaleXY(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> scaleXZ(const GenoVector<3, T> & vector, T scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale; + return target; +} + +template +GenoVector<3, T> scaleXZ(const GenoVector<3, T> & vector, T scaleX, T scaleZ, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scaleZ; + return target; +} + +template +GenoVector<3, T> scaleXZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[1]; + return target; +} + +template +GenoVector<3, T> scaleYX(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2]; + return target; +} + +template +GenoVector<3, T> scaleYZ(const GenoVector<3, T> & vector, T scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + return target; +} + +template +GenoVector<3, T> scaleYZ(const GenoVector<3, T> & vector, T scaleY, T scaleZ, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2] * scaleZ; + return target; +} + +template +GenoVector<3, T> scaleYZ(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + return target; +} + +template +GenoVector<3, T> scaleZX(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + return target; +} + +template +GenoVector<3, T> scaleZY(const GenoVector<3, T> & vector, const GenoVector<2, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + return target; +} + +template +GenoVector<3, T> scaleXYZ(const GenoVector<3, T> & vector, T scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + return target; +} + +template +GenoVector<3, T> scaleXYZ(const GenoVector<3, T> & vector, T scaleX, T scaleY, T scaleZ, const GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2] * scaleZ; + return target; +} + +template +GenoVector<3, T> scaleXYZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + return target; +} + +template +GenoVector<3, T> scaleXZY(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[1]; + return target; +} + +template +GenoVector<3, T> scaleYXZ(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[2]; + return target; +} + +template +GenoVector<3, T> scaleYZX(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + return target; +} + +template +GenoVector<3, T> scaleZXY(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[0]; + return target; +} + +template +GenoVector<3, T> scaleZYX(const GenoVector<3, T> & vector, const GenoVector<3, T> & scale, GenoVector<3, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + return target; +} + +template +std::ostream & operator<<(std::ostream & stream, const GenoVector<3, T> & vector) { + return stream << '<' << vector.v[0] << ", " << vector.v[1] << ", " << vector.v[2] << '>'; +} + + +template using GenoVector3 = GenoVector<3, T>; + +using GenoVector3b = GenoVector3< int8 >; +using GenoVector3ub = GenoVector3; +using GenoVector3s = GenoVector3< int16>; +using GenoVector3us = GenoVector3; +using GenoVector3i = GenoVector3< int32>; +using GenoVector3ui = GenoVector3; +using GenoVector3l = GenoVector3< int64>; +using GenoVector3ul = GenoVector3; +using GenoVector3f = GenoVector3; +using GenoVector3d = GenoVector3; + +#define GNARLY_GENOME_VECTOR3_FORWARD +#endif // GNARLY_GENOME_VECTOR3 \ No newline at end of file diff --git a/src/geno/math/linear/GenoVector4.h b/src/geno/math/linear/GenoVector4.h new file mode 100644 index 0000000..44bfcd3 --- /dev/null +++ b/src/geno/math/linear/GenoVector4.h @@ -0,0 +1,7440 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../../GenoInts.h" + +#ifndef GNARLY_GENOME_VECTOR_FORWARD +#define GNARLY_GENOME_VECTOR_FORWARD + +template +class GenoVector; + +#endif // GNARLY_GENOME_VECTOR_FORWARD + +#ifndef GNARLY_GENOME_VECTOR2_FORWARD +#define GNARLY_GENOME_VECTOR2_FORWARD + +template +class GenoVector<2, T>; + +#endif // GNARLY_GENOME_VECTOR2_FORWARD + +#ifndef GNARLY_GENOME_VECTOR3_FORWARD +#define GNARLY_GENOME_VECTOR3_FORWARD + +template +class GenoVector<3, T>; + +#endif // GNARLY_GENOME_VECTOR3_FORWARD + +#ifndef GNARLY_GENOME_VECTOR4 +#define GNARLY_GENOME_VECTOR4 + +#include +#include + +#include "GenoVector.h" +#include "GenoVector2.h" +#include "GenoVector3.h" +#include "GenoVectorDimensions.h" + +namespace GenoVectorDimensions { + extern GenoVectorDimension<3> w; +} + +template +class GenoVector<4, T> { + private: + bool owner = true; + + void clean() { + if (owner) + delete [] v; + } + + public: + static GenoVector<4, T> * newArray(uint32 length) { + T * v = new T[4 * length]; + GenoVector<4, T> * ret = new GenoVector<4, T>[length]; + ret[0] = GenoVector<4, T>(v); + for (uint32 i = 1; i < length; ++i) + ret[i] = GenoVector<4, T>(v + i * 4, false); + return ret; + } + + T * v; + + GenoVector() : + v(new T[4]()) {} + + GenoVector(T * v, bool owner = true) noexcept : + owner(owner), + v(v) {} + + explicit GenoVector(T value) : + v(new T[4] { value, value, value, value }) {} + + GenoVector(T x, T y, T z, T w) : + v(new T[4] { x, y, z, w }) {} + + template + GenoVector(const GenoVector<4, T2> & vector) : + v(new T[4] { + (T) vector.v[0], + (T) vector.v[1], + (T) vector.v[2], + (T) vector.v[3] + }) {} + + GenoVector(const GenoVector<4, T> & vector) : + v(new T[4] { + vector.v[0], + vector.v[1], + vector.v[2], + vector.v[3] + }) {} + + GenoVector(GenoVector<4, T> && vector) : + owner(vector.owner), + v(vector.v) { + vector.owner = false; + } + + GenoVector<4, T> & operator=(const GenoVector<4, T> & vector) { + v[0] = vector.v[0]; + v[1] = vector.v[1]; + v[2] = vector.v[2]; + v[3] = vector.v[3]; + return *this; + } + + GenoVector<4, T> & operator=(GenoVector<4, T> && vector) { + if (owner) { + clean(); + owner = vector.owner; + v = vector.v; + vector.owner = false; + } + else { + v[0] = vector.v[0]; + v[1] = vector.v[1]; + v[2] = vector.v[2]; + v[3] = vector.v[3]; + } + return *this; + } + + GenoVector<4, T> & operator+=(const GenoVector<4, T> & vector) { + v[0] += vector.v[0]; + v[1] += vector.v[1]; + v[2] += vector.v[2]; + v[3] += vector.v[3]; + return *this; + } + + GenoVector<4, T> & operator-=(const GenoVector<4, T> & vector) { + v[0] -= vector.v[0]; + v[1] -= vector.v[1]; + v[2] -= vector.v[2]; + v[3] -= vector.v[3]; + return *this; + } + + GenoVector<4, T> & operator*=(T scalar) { + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + v[3] *= scalar; + return *this; + } + + GenoVector<4, T> & operator*=(const GenoVector<4, T> & vector) { + v[0] *= vector.v[0]; + v[1] *= vector.v[1]; + v[2] *= vector.v[2]; + v[3] *= vector.v[3]; + return *this; + } + + GenoVector<4, T> & operator/=(T scalar) { + v[0] /= scalar; + v[1] /= scalar; + v[2] /= scalar; + v[3] /= scalar; + return *this; + } + + GenoVector<4, T> & operator/=(const GenoVector<4, T> & vector) { + v[0] /= vector.v[0]; + v[1] /= vector.v[1]; + v[2] /= vector.v[2]; + v[3] /= vector.v[3]; + return *this; + } + + T & operator[](uint32 index) noexcept { + return v[index]; + } + + const T & operator[](uint32 index) const noexcept { + return v[index]; + } + + template + T & operator[](const GenoVectorDimensions::GenoVectorDimension & dimension) noexcept { + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension < 4, "GenoVector<4, T> has no dimension beyond w!"); + return v[GenoVectorDimensions::GenoVectorDimension::dimension]; + } + + template + const T & operator[](const GenoVectorDimensions::GenoVectorDimension & dimension) const noexcept { + static_assert(GenoVectorDimensions::GenoVectorDimension::dimension < 4, "GenoVector<4, T> has no dimension beyond w!"); + return v[GenoVectorDimensions::GenoVectorDimension::dimension]; + } + + T & x() noexcept { + return v[0]; + } + + const T & x() const noexcept { + return v[0]; + } + + T & y() noexcept { + return v[1]; + } + + const T & y() const noexcept { + return v[1]; + } + + T & z() noexcept { + return v[2]; + } + + const T & z() const noexcept { + return v[2]; + } + + T & w() noexcept { + return v[3]; + } + + const T & w() const noexcept { + return v[3]; + } + + T getLength() const { + return sqrt( + v[0] * v[0] + + v[1] * v[1] + + v[2] * v[2] + + v[3] * v[3] + ); + } + + T getLengthSquared() const { + return ( + v[0] * v[0] + + v[1] * v[1] + + v[2] * v[2] + + v[3] * v[3] + ); + } + + GenoVector<4, T> & setLength(T length) { + auto scalar = length / getLength(); + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + v[3] *= scalar; + return *this; + } + + GenoVector<4, T> & normalize() { + auto scalar = 1 / getLength(); + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + v[3] *= scalar; + return *this; + } + + GenoVector<2, T> & negate() { + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; + v[3] = -v[3]; + return *this; + } + + GenoVector<4, T> & project(const GenoVector<4, T> & projection) { + auto scalar = dot(*this, projection) / projection.getLengthSquared(); + v[0] /= scalar; + v[1] /= scalar; + v[2] /= scalar; + v[3] /= scalar; + return *this; + } + + GenoVector<4, T> & set(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & translate(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + v[3] += translate.v[3]; + return *this; + } + + GenoVector<4, T> & scale(T scale) { + v[0] *= scale; + v[1] *= scale; + v[2] *= scale; + v[3] *= scale; + return *this; + } + + GenoVector<4, T> & scale(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + v[3] *= scale.v[3]; + return *this; + } + + GenoVector<4, T> & setX(T x) { + v[0] = x; + return *this; + } + + GenoVector<4, T> & setY(T y) { + v[1] = y; + return *this; + } + + GenoVector<4, T> & setZ(T z) { + v[2] = z; + return *this; + } + + GenoVector<4, T> & setW(T w) { + v[3] = w; + return *this; + } + + GenoVector<4, T> & setXY(T x, T y) { + v[0] = x; + v[1] = y; + return *this; + } + + GenoVector<4, T> & setXY(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setXZ(T x, T z) { + v[0] = x; + v[2] = z; + return *this; + } + + GenoVector<4, T> & setXZ(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setXW(T x, T w) { + v[0] = x; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setXW(const GenoVector<2, T> & set) { + v[0] = set.v[0]; + v[3] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setYX(const GenoVector<2, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setYZ(T y, T z) { + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<4, T> & setYZ(const GenoVector<2, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setYW(T y, T w) { + v[1] = y; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setYW(const GenoVector<2, T> & set) { + v[1] = set.v[0]; + v[3] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setZX(const GenoVector<2, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setZY(const GenoVector<2, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setZW(T z, T w) { + v[2] = z; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setZW(const GenoVector<2, T> & set) { + v[2] = set.v[0]; + v[3] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setWX(const GenoVector<2, T> & set) { + v[3] = set.v[0]; + v[0] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setWY(const GenoVector<2, T> & set) { + v[3] = set.v[0]; + v[1] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setWZ(const GenoVector<2, T> & set) { + v[3] = set.v[0]; + v[2] = set.v[1]; + return *this; + } + + GenoVector<4, T> & setXYZ(T x, T y, T z) { + v[0] = x; + v[1] = y; + v[2] = z; + return *this; + } + + GenoVector<4, T> & setXYZ(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setXYW(T x, T y, T w) { + v[0] = x; + v[1] = y; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setXYW(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[3] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setXZY(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setXZW(T x, T z, T w) { + v[0] = x; + v[2] = z; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setXZW(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + v[3] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setXWY(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[3] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setXWZ(const GenoVector<3, T> & set) { + v[0] = set.v[0]; + v[3] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setYXZ(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setYXW(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + v[3] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setYZX(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setYZW(T y, T z, T w) { + v[1] = y; + v[2] = z; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setYZW(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + v[3] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setYWX(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[3] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setYWZ(const GenoVector<3, T> & set) { + v[1] = set.v[0]; + v[3] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setZXY(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setZXW(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + v[3] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setZYX(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setZYW(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + v[3] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setZWX(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[3] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setZWY(const GenoVector<3, T> & set) { + v[2] = set.v[0]; + v[3] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setWXY(const GenoVector<3, T> & set) { + v[3] = set.v[0]; + v[0] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setWXZ(const GenoVector<3, T> & set) { + v[3] = set.v[0]; + v[0] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setWYX(const GenoVector<3, T> & set) { + v[3] = set.v[0]; + v[1] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setWYZ(const GenoVector<3, T> & set) { + v[3] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setWZX(const GenoVector<3, T> & set) { + v[3] = set.v[0]; + v[2] = set.v[1]; + v[0] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setWZY(const GenoVector<3, T> & set) { + v[3] = set.v[0]; + v[2] = set.v[1]; + v[1] = set.v[2]; + return *this; + } + + GenoVector<4, T> & setXYZW(T x, T y, T z, T w) { + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = w; + return *this; + } + + GenoVector<4, T> & setXYZW(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setXYWZ(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[1] = set.v[1]; + v[3] = set.v[2]; + v[2] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setXZYW(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + v[1] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setXZWY(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[2] = set.v[1]; + v[3] = set.v[2]; + v[1] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setXWYZ(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[3] = set.v[1]; + v[1] = set.v[2]; + v[2] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setXWZY(const GenoVector<4, T> & set) { + v[0] = set.v[0]; + v[3] = set.v[1]; + v[2] = set.v[2]; + v[1] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setYXZW(const GenoVector<4, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + v[2] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setYXWZ(const GenoVector<4, T> & set) { + v[1] = set.v[0]; + v[0] = set.v[1]; + v[3] = set.v[2]; + v[2] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setYZXW(const GenoVector<4, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + v[0] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setYZWX(const GenoVector<4, T> & set) { + v[1] = set.v[0]; + v[2] = set.v[1]; + v[3] = set.v[2]; + v[0] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setYWXZ(const GenoVector<4, T> & set) { + v[1] = set.v[0]; + v[3] = set.v[1]; + v[0] = set.v[2]; + v[2] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setYWZX(const GenoVector<4, T> & set) { + v[1] = set.v[0]; + v[3] = set.v[1]; + v[2] = set.v[2]; + v[0] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setZXYW(const GenoVector<4, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + v[1] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setZXWY(const GenoVector<4, T> & set) { + v[2] = set.v[0]; + v[0] = set.v[1]; + v[3] = set.v[2]; + v[1] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setZYXW(const GenoVector<4, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + v[0] = set.v[2]; + v[3] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setZYWX(const GenoVector<4, T> & set) { + v[2] = set.v[0]; + v[1] = set.v[1]; + v[3] = set.v[2]; + v[0] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setZWXY(const GenoVector<4, T> & set) { + v[2] = set.v[0]; + v[3] = set.v[1]; + v[0] = set.v[2]; + v[1] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setZWYX(const GenoVector<4, T> & set) { + v[2] = set.v[0]; + v[3] = set.v[1]; + v[1] = set.v[2]; + v[0] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setWXYZ(const GenoVector<4, T> & set) { + v[3] = set.v[0]; + v[0] = set.v[1]; + v[1] = set.v[2]; + v[2] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setWXZY(const GenoVector<4, T> & set) { + v[3] = set.v[0]; + v[0] = set.v[1]; + v[2] = set.v[2]; + v[1] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setWYXZ(const GenoVector<4, T> & set) { + v[3] = set.v[0]; + v[1] = set.v[1]; + v[0] = set.v[2]; + v[2] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setWYZX(const GenoVector<4, T> & set) { + v[3] = set.v[0]; + v[1] = set.v[1]; + v[2] = set.v[2]; + v[0] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setWZXY(const GenoVector<4, T> & set) { + v[3] = set.v[0]; + v[2] = set.v[1]; + v[0] = set.v[2]; + v[1] = set.v[3]; + return *this; + } + + GenoVector<4, T> & setWZYX(const GenoVector<4, T> & set) { + v[3] = set.v[0]; + v[2] = set.v[1]; + v[1] = set.v[2]; + v[0] = set.v[3]; + return *this; + } + + GenoVector<4, T> & translateX(T translateX) { + v[0] += translateX; + } + + GenoVector<4, T> & translateY(T translateY) { + v[1] += translateY; + } + + GenoVector<4, T> & translateZ(T translateZ) { + v[2] += translateZ; + } + + GenoVector<4, T> & translateW(T translateW) { + v[3] += translateW; + } + + GenoVector<4, T> & translateXY(T translateX, T translateY) { + v[0] += translateX; + v[1] += translateY; + } + + GenoVector<4, T> & translateXY(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + } + + GenoVector<4, T> & translateXZ(T translateX, T translateZ) { + v[0] += translateX; + v[2] += translateZ; + } + + GenoVector<4, T> & translateXZ(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + } + + GenoVector<4, T> & translateXW(T translateX, T translateW) { + v[0] += translateX; + v[3] += translateW; + } + + GenoVector<4, T> & translateXW(const GenoVector<2, T> & translate) { + v[0] += translate.v[0]; + v[3] += translate.v[1]; + } + + GenoVector<4, T> & translateYX(const GenoVector<2, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + } + + GenoVector<4, T> & translateYZ(T translateY, T translateZ) { + v[1] += translateY; + v[2] += translateZ; + } + + GenoVector<4, T> & translateYZ(const GenoVector<2, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + } + + GenoVector<4, T> & translateYW(T translateY, T translateW) { + v[1] += translateY; + v[3] += translateW; + } + + GenoVector<4, T> & translateYW(const GenoVector<2, T> & translate) { + v[1] += translate.v[0]; + v[3] += translate.v[1]; + } + + GenoVector<4, T> & translateZX(const GenoVector<2, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + } + + GenoVector<4, T> & translateZY(const GenoVector<2, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + } + + GenoVector<4, T> & translateZW(T translateZ, T translateW) { + v[2] += translateZ; + v[3] += translateW; + } + + GenoVector<4, T> & translateZW(const GenoVector<2, T> & translate) { + v[2] += translate.v[0]; + v[3] += translate.v[1]; + } + + GenoVector<4, T> & translateWX(const GenoVector<2, T> & translate) { + v[3] += translate.v[0]; + v[0] += translate.v[1]; + } + + GenoVector<4, T> & translateWY(const GenoVector<2, T> & translate) { + v[3] += translate.v[0]; + v[1] += translate.v[1]; + } + + GenoVector<4, T> & translateWZ(const GenoVector<2, T> & translate) { + v[3] += translate.v[0]; + v[2] += translate.v[1]; + } + + GenoVector<4, T> & translateXYZ(T translateX, T translateY, T translateZ) { + v[0] += translateX; + v[1] += translateY; + v[2] += translateZ; + } + + GenoVector<4, T> & translateXYZ(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<4, T> & translateXYW(T translateX, T translateY, T translateW) { + v[0] += translateX; + v[1] += translateY; + v[3] += translateW; + } + + GenoVector<4, T> & translateXYW(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[3] += translate.v[2]; + } + + GenoVector<4, T> & translateXZY(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<4, T> & translateXZW(T translateX, T translateZ, T translateW) { + v[0] += translateX; + v[2] += translateZ; + v[3] += translateW; + } + + GenoVector<4, T> & translateXZW(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + v[3] += translate.v[2]; + } + + GenoVector<4, T> & translateXWY(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[3] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<4, T> & translateXWZ(const GenoVector<3, T> & translate) { + v[0] += translate.v[0]; + v[3] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<4, T> & translateYXZ(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<4, T> & translateYXW(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + v[3] += translate.v[2]; + } + + GenoVector<4, T> & translateYZX(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<4, T> & translateYZW(T translateY, T translateZ, T translateW) { + v[1] += translateY; + v[2] += translateZ; + v[3] += translateW; + } + + GenoVector<4, T> & translateYZW(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + v[3] += translate.v[2]; + } + + GenoVector<4, T> & translateYWX(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[3] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<4, T> & translateYWZ(const GenoVector<3, T> & translate) { + v[1] += translate.v[0]; + v[3] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<4, T> & translateZXY(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<4, T> & translateZXW(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + v[3] += translate.v[2]; + } + + GenoVector<4, T> & translateZYX(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<4, T> & translateZYW(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + v[3] += translate.v[2]; + } + + GenoVector<4, T> & translateZWX(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[3] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<4, T> & translateZWY(const GenoVector<3, T> & translate) { + v[2] += translate.v[0]; + v[3] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<4, T> & translateWXY(const GenoVector<3, T> & translate) { + v[3] += translate.v[0]; + v[0] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<4, T> & translateWXZ(const GenoVector<3, T> & translate) { + v[3] += translate.v[0]; + v[0] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<4, T> & translateWYX(const GenoVector<3, T> & translate) { + v[3] += translate.v[0]; + v[1] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<4, T> & translateWYZ(const GenoVector<3, T> & translate) { + v[3] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + } + + GenoVector<4, T> & translateWZX(const GenoVector<3, T> & translate) { + v[3] += translate.v[0]; + v[2] += translate.v[1]; + v[0] += translate.v[2]; + } + + GenoVector<4, T> & translateWZY(const GenoVector<3, T> & translate) { + v[3] += translate.v[0]; + v[2] += translate.v[1]; + v[1] += translate.v[2]; + } + + GenoVector<4, T> & translateXYZW(T translateX, T translateY, T translateZ, T translateW) { + v[0] += translateX; + v[1] += translateY; + v[2] += translateZ; + v[3] += translateW; + } + + GenoVector<4, T> & translateXYZW(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + v[3] += translate.v[3]; + } + + GenoVector<4, T> & translateXYWZ(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[1] += translate.v[1]; + v[3] += translate.v[2]; + v[2] += translate.v[3]; + } + + GenoVector<4, T> & translateXZYW(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + v[1] += translate.v[2]; + v[3] += translate.v[3]; + } + + GenoVector<4, T> & translateXZWY(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[2] += translate.v[1]; + v[3] += translate.v[2]; + v[1] += translate.v[3]; + } + + GenoVector<4, T> & translateXWYZ(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[3] += translate.v[1]; + v[1] += translate.v[2]; + v[2] += translate.v[3]; + } + + GenoVector<4, T> & translateXWZY(const GenoVector<4, T> & translate) { + v[0] += translate.v[0]; + v[3] += translate.v[1]; + v[2] += translate.v[2]; + v[1] += translate.v[3]; + } + + GenoVector<4, T> & translateYXZW(const GenoVector<4, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + v[2] += translate.v[2]; + v[3] += translate.v[3]; + } + + GenoVector<4, T> & translateYXWZ(const GenoVector<4, T> & translate) { + v[1] += translate.v[0]; + v[0] += translate.v[1]; + v[3] += translate.v[2]; + v[2] += translate.v[3]; + } + + GenoVector<4, T> & translateYZXW(const GenoVector<4, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + v[0] += translate.v[2]; + v[3] += translate.v[3]; + } + + GenoVector<4, T> & translateYZWX(const GenoVector<4, T> & translate) { + v[1] += translate.v[0]; + v[2] += translate.v[1]; + v[3] += translate.v[2]; + v[0] += translate.v[3]; + } + + GenoVector<4, T> & translateYWXZ(const GenoVector<4, T> & translate) { + v[1] += translate.v[0]; + v[3] += translate.v[1]; + v[0] += translate.v[2]; + v[2] += translate.v[3]; + } + + GenoVector<4, T> & translateYWZX(const GenoVector<4, T> & translate) { + v[1] += translate.v[0]; + v[3] += translate.v[1]; + v[2] += translate.v[2]; + v[0] += translate.v[3]; + } + + GenoVector<4, T> & translateZXYW(const GenoVector<4, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + v[1] += translate.v[2]; + v[3] += translate.v[3]; + } + + GenoVector<4, T> & translateZXWY(const GenoVector<4, T> & translate) { + v[2] += translate.v[0]; + v[0] += translate.v[1]; + v[3] += translate.v[2]; + v[1] += translate.v[3]; + } + + GenoVector<4, T> & translateZYXW(const GenoVector<4, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + v[0] += translate.v[2]; + v[3] += translate.v[3]; + } + + GenoVector<4, T> & translateZYWX(const GenoVector<4, T> & translate) { + v[2] += translate.v[0]; + v[1] += translate.v[1]; + v[3] += translate.v[2]; + v[0] += translate.v[3]; + } + + GenoVector<4, T> & translateZWXY(const GenoVector<4, T> & translate) { + v[2] += translate.v[0]; + v[3] += translate.v[1]; + v[0] += translate.v[2]; + v[1] += translate.v[3]; + } + + GenoVector<4, T> & translateZWYX(const GenoVector<4, T> & translate) { + v[2] += translate.v[0]; + v[3] += translate.v[1]; + v[1] += translate.v[2]; + v[0] += translate.v[3]; + } + + GenoVector<4, T> & translateWXYZ(const GenoVector<4, T> & translate) { + v[3] += translate.v[0]; + v[0] += translate.v[1]; + v[1] += translate.v[2]; + v[2] += translate.v[3]; + } + + GenoVector<4, T> & translateWXZY(const GenoVector<4, T> & translate) { + v[3] += translate.v[0]; + v[0] += translate.v[1]; + v[2] += translate.v[2]; + v[1] += translate.v[3]; + } + + GenoVector<4, T> & translateWYXZ(const GenoVector<4, T> & translate) { + v[3] += translate.v[0]; + v[1] += translate.v[1]; + v[0] += translate.v[2]; + v[2] += translate.v[3]; + } + + GenoVector<4, T> & translateWYZX(const GenoVector<4, T> & translate) { + v[3] += translate.v[0]; + v[1] += translate.v[1]; + v[2] += translate.v[2]; + v[0] += translate.v[3]; + } + + GenoVector<4, T> & translateWZXY(const GenoVector<4, T> & translate) { + v[3] += translate.v[0]; + v[2] += translate.v[1]; + v[0] += translate.v[2]; + v[1] += translate.v[3]; + } + + GenoVector<4, T> & translateWZYX(const GenoVector<4, T> & translate) { + v[3] += translate.v[0]; + v[2] += translate.v[1]; + v[1] += translate.v[2]; + v[0] += translate.v[3]; + } + + GenoVector<4, T> & scaleX(T scaleX) { + v[0] *= scaleX; + } + + GenoVector<4, T> & scaleY(T scaleY) { + v[1] *= scaleY; + } + + GenoVector<4, T> & scaleZ(T scaleZ) { + v[2] *= scaleZ; + } + + GenoVector<4, T> & scaleW(T scaleW) { + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleXY(T scale) { + v[0] *= scale; + v[1] *= scale; + } + + GenoVector<4, T> & scaleXY(T scaleX, T scaleY) { + v[0] *= scaleX; + v[1] *= scaleY; + } + + GenoVector<4, T> & scaleXY(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + } + + GenoVector<4, T> & scaleXZ(T scale) { + v[0] *= scale; + v[2] *= scale; + } + + GenoVector<4, T> & scaleXZ(T scaleX, T scaleZ) { + v[0] *= scaleX; + v[2] *= scaleZ; + } + + GenoVector<4, T> & scaleXZ(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + } + + GenoVector<4, T> & scaleXW(T scale) { + v[0] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleXW(T scaleX, T scaleW) { + v[0] *= scaleX; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleXW(const GenoVector<2, T> & scale) { + v[0] *= scale.v[0]; + v[3] *= scale.v[1]; + } + + GenoVector<4, T> & scaleYX(const GenoVector<2, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + } + + GenoVector<4, T> & scaleYZ(T scale) { + v[1] *= scale; + v[2] *= scale; + } + + GenoVector<4, T> & scaleYZ(T scaleY, T scaleZ) { + v[1] *= scaleY; + v[2] *= scaleZ; + } + + GenoVector<4, T> & scaleYZ(const GenoVector<2, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + } + + GenoVector<4, T> & scaleYW(T scale) { + v[1] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleYW(T scaleY, T scaleW) { + v[1] *= scaleY; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleYW(const GenoVector<2, T> & scale) { + v[1] *= scale.v[0]; + v[3] *= scale.v[1]; + } + + GenoVector<4, T> & scaleZX(const GenoVector<2, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + } + + GenoVector<4, T> & scaleZY(const GenoVector<2, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + } + + GenoVector<4, T> & scaleZW(T scale) { + v[2] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleZW(T scaleZ, T scaleW) { + v[2] *= scaleZ; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleZW(const GenoVector<2, T> & scale) { + v[2] *= scale.v[0]; + v[3] *= scale.v[1]; + } + + GenoVector<4, T> & scaleWX(const GenoVector<2, T> & scale) { + v[3] *= scale.v[0]; + v[0] *= scale.v[1]; + } + + GenoVector<4, T> & scaleWY(const GenoVector<2, T> & scale) { + v[3] *= scale.v[0]; + v[1] *= scale.v[1]; + } + + GenoVector<4, T> & scaleWZ(const GenoVector<2, T> & scale) { + v[3] *= scale.v[0]; + v[2] *= scale.v[1]; + } + + GenoVector<4, T> & scaleXYZ(T scale) { + v[0] *= scale; + v[1] *= scale; + v[2] *= scale; + } + + GenoVector<4, T> & scaleXYZ(T scaleX, T scaleY, T scaleZ) { + v[0] *= scaleX; + v[1] *= scaleY; + v[2] *= scaleZ; + } + + GenoVector<4, T> & scaleXYZ(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<4, T> & scaleXYW(T scale) { + v[0] *= scale; + v[1] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleXYW(T scaleX, T scaleY, T scaleW) { + v[0] *= scaleX; + v[1] *= scaleY; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleXYW(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[3] *= scale.v[2]; + } + + GenoVector<4, T> & scaleXZY(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<4, T> & scaleXZW(T scale) { + v[0] *= scale; + v[2] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleXZW(T scaleX, T scaleZ, T scaleW) { + v[0] *= scaleX; + v[2] *= scaleZ; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleXZW(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + v[3] *= scale.v[2]; + } + + GenoVector<4, T> & scaleXWY(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[3] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<4, T> & scaleXWZ(const GenoVector<3, T> & scale) { + v[0] *= scale.v[0]; + v[3] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<4, T> & scaleYXZ(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<4, T> & scaleYXW(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + v[3] *= scale.v[2]; + } + + GenoVector<4, T> & scaleYZX(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<4, T> & scaleYZW(T scale) { + v[1] *= scale; + v[2] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleYZW(T scaleY, T scaleZ, T scaleW) { + v[1] *= scaleY; + v[2] *= scaleZ; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleYZW(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + v[3] *= scale.v[2]; + } + + GenoVector<4, T> & scaleYWX(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[3] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<4, T> & scaleYWZ(const GenoVector<3, T> & scale) { + v[1] *= scale.v[0]; + v[3] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<4, T> & scaleZXY(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<4, T> & scaleZXW(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + v[3] *= scale.v[2]; + } + + GenoVector<4, T> & scaleZYX(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<4, T> & scaleZYW(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + v[3] *= scale.v[2]; + } + + GenoVector<4, T> & scaleZWX(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[3] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<4, T> & scaleZWY(const GenoVector<3, T> & scale) { + v[2] *= scale.v[0]; + v[3] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<4, T> & scaleWXY(const GenoVector<3, T> & scale) { + v[3] *= scale.v[0]; + v[0] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<4, T> & scaleWXZ(const GenoVector<3, T> & scale) { + v[3] *= scale.v[0]; + v[0] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<4, T> & scaleWYX(const GenoVector<3, T> & scale) { + v[3] *= scale.v[0]; + v[1] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<4, T> & scaleWYZ(const GenoVector<3, T> & scale) { + v[3] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + } + + GenoVector<4, T> & scaleWZX(const GenoVector<3, T> & scale) { + v[3] *= scale.v[0]; + v[2] *= scale.v[1]; + v[0] *= scale.v[2]; + } + + GenoVector<4, T> & scaleWZY(const GenoVector<3, T> & scale) { + v[3] *= scale.v[0]; + v[2] *= scale.v[1]; + v[1] *= scale.v[2]; + } + + GenoVector<4, T> & scaleXYZW(T scale) { + v[0] *= scale; + v[1] *= scale; + v[2] *= scale; + v[3] *= scale; + } + + GenoVector<4, T> & scaleXYZW(T scaleX, T scaleY, T scaleZ, T scaleW) { + v[0] *= scaleX; + v[1] *= scaleY; + v[2] *= scaleZ; + v[3] *= scaleW; + } + + GenoVector<4, T> & scaleXYZW(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + v[3] *= scale.v[3]; + } + + GenoVector<4, T> & scaleXYWZ(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[1] *= scale.v[1]; + v[3] *= scale.v[2]; + v[2] *= scale.v[3]; + } + + GenoVector<4, T> & scaleXZYW(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + v[1] *= scale.v[2]; + v[3] *= scale.v[3]; + } + + GenoVector<4, T> & scaleXZWY(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[2] *= scale.v[1]; + v[3] *= scale.v[2]; + v[1] *= scale.v[3]; + } + + GenoVector<4, T> & scaleXWYZ(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[3] *= scale.v[1]; + v[1] *= scale.v[2]; + v[2] *= scale.v[3]; + } + + GenoVector<4, T> & scaleXWZY(const GenoVector<4, T> & scale) { + v[0] *= scale.v[0]; + v[3] *= scale.v[1]; + v[2] *= scale.v[2]; + v[1] *= scale.v[3]; + } + + GenoVector<4, T> & scaleYXZW(const GenoVector<4, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + v[2] *= scale.v[2]; + v[3] *= scale.v[3]; + } + + GenoVector<4, T> & scaleYXWZ(const GenoVector<4, T> & scale) { + v[1] *= scale.v[0]; + v[0] *= scale.v[1]; + v[3] *= scale.v[2]; + v[2] *= scale.v[3]; + } + + GenoVector<4, T> & scaleYZXW(const GenoVector<4, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + v[0] *= scale.v[2]; + v[3] *= scale.v[3]; + } + + GenoVector<4, T> & scaleYZWX(const GenoVector<4, T> & scale) { + v[1] *= scale.v[0]; + v[2] *= scale.v[1]; + v[3] *= scale.v[2]; + v[0] *= scale.v[3]; + } + + GenoVector<4, T> & scaleYWXZ(const GenoVector<4, T> & scale) { + v[1] *= scale.v[0]; + v[3] *= scale.v[1]; + v[0] *= scale.v[2]; + v[2] *= scale.v[3]; + } + + GenoVector<4, T> & scaleYWZX(const GenoVector<4, T> & scale) { + v[1] *= scale.v[0]; + v[3] *= scale.v[1]; + v[2] *= scale.v[2]; + v[0] *= scale.v[3]; + } + + GenoVector<4, T> & scaleZXYW(const GenoVector<4, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + v[1] *= scale.v[2]; + v[3] *= scale.v[3]; + } + + GenoVector<4, T> & scaleZXWY(const GenoVector<4, T> & scale) { + v[2] *= scale.v[0]; + v[0] *= scale.v[1]; + v[3] *= scale.v[2]; + v[1] *= scale.v[3]; + } + + GenoVector<4, T> & scaleZYXW(const GenoVector<4, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + v[0] *= scale.v[2]; + v[3] *= scale.v[3]; + } + + GenoVector<4, T> & scaleZYWX(const GenoVector<4, T> & scale) { + v[2] *= scale.v[0]; + v[1] *= scale.v[1]; + v[3] *= scale.v[2]; + v[0] *= scale.v[3]; + } + + GenoVector<4, T> & scaleZWXY(const GenoVector<4, T> & scale) { + v[2] *= scale.v[0]; + v[3] *= scale.v[1]; + v[0] *= scale.v[2]; + v[1] *= scale.v[3]; + } + + GenoVector<4, T> & scaleZWYX(const GenoVector<4, T> & scale) { + v[2] *= scale.v[0]; + v[3] *= scale.v[1]; + v[1] *= scale.v[2]; + v[0] *= scale.v[3]; + } + + GenoVector<4, T> & scaleWXYZ(const GenoVector<4, T> & scale) { + v[3] *= scale.v[0]; + v[0] *= scale.v[1]; + v[1] *= scale.v[2]; + v[2] *= scale.v[3]; + } + + GenoVector<4, T> & scaleWXZY(const GenoVector<4, T> & scale) { + v[3] *= scale.v[0]; + v[0] *= scale.v[1]; + v[2] *= scale.v[2]; + v[1] *= scale.v[3]; + } + + GenoVector<4, T> & scaleWYXZ(const GenoVector<4, T> & scale) { + v[3] *= scale.v[0]; + v[1] *= scale.v[1]; + v[0] *= scale.v[2]; + v[2] *= scale.v[3]; + } + + GenoVector<4, T> & scaleWYZX(const GenoVector<4, T> & scale) { + v[3] *= scale.v[0]; + v[1] *= scale.v[1]; + v[2] *= scale.v[2]; + v[0] *= scale.v[3]; + } + + GenoVector<4, T> & scaleWZXY(const GenoVector<4, T> & scale) { + v[3] *= scale.v[0]; + v[2] *= scale.v[1]; + v[0] *= scale.v[2]; + v[1] *= scale.v[3]; + } + + GenoVector<4, T> & scaleWZYX(const GenoVector<4, T> & scale) { + v[3] *= scale.v[0]; + v[2] *= scale.v[1]; + v[1] *= scale.v[2]; + v[0] *= scale.v[3]; + } + + T getX() const { + return v[0]; + } + + T getY() const { + return v[1]; + } + + T getZ() const { + return v[2]; + } + + T getW() const { + return v[3]; + } + + GenoVector<2, T> getXX() const { + return { v[0], v[0] }; + } + + GenoVector<2, T> getXY() const { + return { v[0], v[1] }; + } + + GenoVector<2, T> getXZ() const { + return { v[0], v[2] }; + } + + GenoVector<2, T> getXW() const { + return { v[0], v[3] }; + } + + GenoVector<2, T> getYX() const { + return { v[1], v[0] }; + } + + GenoVector<2, T> getYY() const { + return { v[1], v[1] }; + } + + GenoVector<2, T> getYZ() const { + return { v[1], v[2] }; + } + + GenoVector<2, T> getYW() const { + return { v[1], v[3] }; + } + + GenoVector<2, T> getZX() const { + return { v[2], v[0] }; + } + + GenoVector<2, T> getZY() const { + return { v[2], v[1] }; + } + + GenoVector<2, T> getZZ() const { + return { v[2], v[2] }; + } + + GenoVector<2, T> getZW() const { + return { v[2], v[3] }; + } + + GenoVector<2, T> getWX() const { + return { v[3], v[0] }; + } + + GenoVector<2, T> getWY() const { + return { v[3], v[1] }; + } + + GenoVector<2, T> getWZ() const { + return { v[3], v[2] }; + } + + GenoVector<2, T> getWW() const { + return { v[3], v[3] }; + } + + GenoVector<3, T> getXXX() const { + return { v[0], v[0], v[0] }; + } + + GenoVector<3, T> getXXY() const { + return { v[0], v[0], v[1] }; + } + + GenoVector<3, T> getXXZ() const { + return { v[0], v[0], v[2] }; + } + + GenoVector<3, T> getXXW() const { + return { v[0], v[0], v[3] }; + } + + GenoVector<3, T> getXYX() const { + return { v[0], v[1], v[0] }; + } + + GenoVector<3, T> getXYY() const { + return { v[0], v[1], v[1] }; + } + + GenoVector<3, T> getXYZ() const { + return { v[0], v[1], v[2] }; + } + + GenoVector<3, T> getXYW() const { + return { v[0], v[1], v[3] }; + } + + GenoVector<3, T> getXZX() const { + return { v[0], v[2], v[0] }; + } + + GenoVector<3, T> getXZY() const { + return { v[0], v[2], v[1] }; + } + + GenoVector<3, T> getXZZ() const { + return { v[0], v[2], v[2] }; + } + + GenoVector<3, T> getXZW() const { + return { v[0], v[2], v[3] }; + } + + GenoVector<3, T> getXWX() const { + return { v[0], v[3], v[0] }; + } + + GenoVector<3, T> getXWY() const { + return { v[0], v[3], v[1] }; + } + + GenoVector<3, T> getXWZ() const { + return { v[0], v[3], v[2] }; + } + + GenoVector<3, T> getXWW() const { + return { v[0], v[3], v[3] }; + } + + GenoVector<3, T> getYXX() const { + return { v[1], v[0], v[0] }; + } + + GenoVector<3, T> getYXY() const { + return { v[1], v[0], v[1] }; + } + + GenoVector<3, T> getYXZ() const { + return { v[1], v[0], v[2] }; + } + + GenoVector<3, T> getYXW() const { + return { v[1], v[0], v[3] }; + } + + GenoVector<3, T> getYYX() const { + return { v[1], v[1], v[0] }; + } + + GenoVector<3, T> getYYY() const { + return { v[1], v[1], v[1] }; + } + + GenoVector<3, T> getYYZ() const { + return { v[1], v[1], v[2] }; + } + + GenoVector<3, T> getYYW() const { + return { v[1], v[1], v[3] }; + } + + GenoVector<3, T> getYZX() const { + return { v[1], v[2], v[0] }; + } + + GenoVector<3, T> getYZY() const { + return { v[1], v[2], v[1] }; + } + + GenoVector<3, T> getYZZ() const { + return { v[1], v[2], v[2] }; + } + + GenoVector<3, T> getYZW() const { + return { v[1], v[2], v[3] }; + } + + GenoVector<3, T> getYWX() const { + return { v[1], v[3], v[0] }; + } + + GenoVector<3, T> getYWY() const { + return { v[1], v[3], v[1] }; + } + + GenoVector<3, T> getYWZ() const { + return { v[1], v[3], v[2] }; + } + + GenoVector<3, T> getYWW() const { + return { v[1], v[3], v[3] }; + } + + GenoVector<3, T> getZXX() const { + return { v[2], v[0], v[0] }; + } + + GenoVector<3, T> getZXY() const { + return { v[2], v[0], v[1] }; + } + + GenoVector<3, T> getZXZ() const { + return { v[2], v[0], v[2] }; + } + + GenoVector<3, T> getZXW() const { + return { v[2], v[0], v[3] }; + } + + GenoVector<3, T> getZYX() const { + return { v[2], v[1], v[0] }; + } + + GenoVector<3, T> getZYY() const { + return { v[2], v[1], v[1] }; + } + + GenoVector<3, T> getZYZ() const { + return { v[2], v[1], v[2] }; + } + + GenoVector<3, T> getZYW() const { + return { v[2], v[1], v[3] }; + } + + GenoVector<3, T> getZZX() const { + return { v[2], v[2], v[0] }; + } + + GenoVector<3, T> getZZY() const { + return { v[2], v[2], v[1] }; + } + + GenoVector<3, T> getZZZ() const { + return { v[2], v[2], v[2] }; + } + + GenoVector<3, T> getZZW() const { + return { v[2], v[2], v[3] }; + } + + GenoVector<3, T> getZWX() const { + return { v[2], v[3], v[0] }; + } + + GenoVector<3, T> getZWY() const { + return { v[2], v[3], v[1] }; + } + + GenoVector<3, T> getZWZ() const { + return { v[2], v[3], v[2] }; + } + + GenoVector<3, T> getZWW() const { + return { v[2], v[3], v[3] }; + } + + GenoVector<3, T> getWXX() const { + return { v[3], v[0], v[0] }; + } + + GenoVector<3, T> getWXY() const { + return { v[3], v[0], v[1] }; + } + + GenoVector<3, T> getWXZ() const { + return { v[3], v[0], v[2] }; + } + + GenoVector<3, T> getWXW() const { + return { v[3], v[0], v[3] }; + } + + GenoVector<3, T> getWYX() const { + return { v[3], v[1], v[0] }; + } + + GenoVector<3, T> getWYY() const { + return { v[3], v[1], v[1] }; + } + + GenoVector<3, T> getWYZ() const { + return { v[3], v[1], v[2] }; + } + + GenoVector<3, T> getWYW() const { + return { v[3], v[1], v[3] }; + } + + GenoVector<3, T> getWZX() const { + return { v[3], v[2], v[0] }; + } + + GenoVector<3, T> getWZY() const { + return { v[3], v[2], v[1] }; + } + + GenoVector<3, T> getWZZ() const { + return { v[3], v[2], v[2] }; + } + + GenoVector<3, T> getWZW() const { + return { v[3], v[2], v[3] }; + } + + GenoVector<3, T> getWWX() const { + return { v[3], v[3], v[0] }; + } + + GenoVector<3, T> getWWY() const { + return { v[3], v[3], v[1] }; + } + + GenoVector<3, T> getWWZ() const { + return { v[3], v[3], v[2] }; + } + + GenoVector<3, T> getWWW() const { + return { v[3], v[3], v[3] }; + } + + GenoVector<4, T> getXXXX() const { + return { v[0], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getXXXY() const { + return { v[0], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getXXXZ() const { + return { v[0], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getXXXW() const { + return { v[0], v[0], v[0], v[3] }; + } + + GenoVector<4, T> getXXYX() const { + return { v[0], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getXXYY() const { + return { v[0], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getXXYZ() const { + return { v[0], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getXXYW() const { + return { v[0], v[0], v[1], v[3] }; + } + + GenoVector<4, T> getXXZX() const { + return { v[0], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getXXZY() const { + return { v[0], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getXXZZ() const { + return { v[0], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getXXZW() const { + return { v[0], v[0], v[2], v[3] }; + } + + GenoVector<4, T> getXXWX() const { + return { v[0], v[0], v[3], v[0] }; + } + + GenoVector<4, T> getXXWY() const { + return { v[0], v[0], v[3], v[1] }; + } + + GenoVector<4, T> getXXWZ() const { + return { v[0], v[0], v[3], v[2] }; + } + + GenoVector<4, T> getXXWW() const { + return { v[0], v[0], v[3], v[3] }; + } + + GenoVector<4, T> getXYXX() const { + return { v[0], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getXYXY() const { + return { v[0], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getXYXZ() const { + return { v[0], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getXYXW() const { + return { v[0], v[1], v[0], v[3] }; + } + + GenoVector<4, T> getXYYX() const { + return { v[0], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getXYYY() const { + return { v[0], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getXYYZ() const { + return { v[0], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getXYYW() const { + return { v[0], v[1], v[1], v[3] }; + } + + GenoVector<4, T> getXYZX() const { + return { v[0], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getXYZY() const { + return { v[0], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getXYZZ() const { + return { v[0], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getXYZW() const { + return { v[0], v[1], v[2], v[3] }; + } + + GenoVector<4, T> getXYWX() const { + return { v[0], v[1], v[3], v[0] }; + } + + GenoVector<4, T> getXYWY() const { + return { v[0], v[1], v[3], v[1] }; + } + + GenoVector<4, T> getXYWZ() const { + return { v[0], v[1], v[3], v[2] }; + } + + GenoVector<4, T> getXYWW() const { + return { v[0], v[1], v[3], v[3] }; + } + + GenoVector<4, T> getXZXX() const { + return { v[0], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getXZXY() const { + return { v[0], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getXZXZ() const { + return { v[0], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getXZXW() const { + return { v[0], v[2], v[0], v[3] }; + } + + GenoVector<4, T> getXZYX() const { + return { v[0], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getXZYY() const { + return { v[0], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getXZYZ() const { + return { v[0], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getXZYW() const { + return { v[0], v[2], v[1], v[3] }; + } + + GenoVector<4, T> getXZZX() const { + return { v[0], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getXZZY() const { + return { v[0], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getXZZZ() const { + return { v[0], v[2], v[2], v[2] }; + } + + GenoVector<4, T> getXZZW() const { + return { v[0], v[2], v[2], v[3] }; + } + + GenoVector<4, T> getXZWX() const { + return { v[0], v[2], v[3], v[0] }; + } + + GenoVector<4, T> getXZWY() const { + return { v[0], v[2], v[3], v[1] }; + } + + GenoVector<4, T> getXZWZ() const { + return { v[0], v[2], v[3], v[2] }; + } + + GenoVector<4, T> getXZWW() const { + return { v[0], v[2], v[3], v[3] }; + } + + GenoVector<4, T> getXWXX() const { + return { v[0], v[3], v[0], v[0] }; + } + + GenoVector<4, T> getXWXY() const { + return { v[0], v[3], v[0], v[1] }; + } + + GenoVector<4, T> getXWXZ() const { + return { v[0], v[3], v[0], v[2] }; + } + + GenoVector<4, T> getXWXW() const { + return { v[0], v[3], v[0], v[3] }; + } + + GenoVector<4, T> getXWYX() const { + return { v[0], v[3], v[1], v[0] }; + } + + GenoVector<4, T> getXWYY() const { + return { v[0], v[3], v[1], v[1] }; + } + + GenoVector<4, T> getXWYZ() const { + return { v[0], v[3], v[1], v[2] }; + } + + GenoVector<4, T> getXWYW() const { + return { v[0], v[3], v[1], v[3] }; + } + + GenoVector<4, T> getXWZX() const { + return { v[0], v[3], v[2], v[0] }; + } + + GenoVector<4, T> getXWZY() const { + return { v[0], v[3], v[2], v[1] }; + } + + GenoVector<4, T> getXWZZ() const { + return { v[0], v[3], v[2], v[2] }; + } + + GenoVector<4, T> getXWZW() const { + return { v[0], v[3], v[2], v[3] }; + } + + GenoVector<4, T> getXWWX() const { + return { v[0], v[3], v[3], v[0] }; + } + + GenoVector<4, T> getXWWY() const { + return { v[0], v[3], v[3], v[1] }; + } + + GenoVector<4, T> getXWWZ() const { + return { v[0], v[3], v[3], v[2] }; + } + + GenoVector<4, T> getXWWW() const { + return { v[0], v[3], v[3], v[3] }; + } + + GenoVector<4, T> getYXXX() const { + return { v[1], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getYXXY() const { + return { v[1], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getYXXZ() const { + return { v[1], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getYXXW() const { + return { v[1], v[0], v[0], v[3] }; + } + + GenoVector<4, T> getYXYX() const { + return { v[1], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getYXYY() const { + return { v[1], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getYXYZ() const { + return { v[1], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getYXYW() const { + return { v[1], v[0], v[1], v[3] }; + } + + GenoVector<4, T> getYXZX() const { + return { v[1], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getYXZY() const { + return { v[1], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getYXZZ() const { + return { v[1], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getYXZW() const { + return { v[1], v[0], v[2], v[3] }; + } + + GenoVector<4, T> getYXWX() const { + return { v[1], v[0], v[3], v[0] }; + } + + GenoVector<4, T> getYXWY() const { + return { v[1], v[0], v[3], v[1] }; + } + + GenoVector<4, T> getYXWZ() const { + return { v[1], v[0], v[3], v[2] }; + } + + GenoVector<4, T> getYXWW() const { + return { v[1], v[0], v[3], v[3] }; + } + + GenoVector<4, T> getYYXX() const { + return { v[1], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getYYXY() const { + return { v[1], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getYYXZ() const { + return { v[1], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getYYXW() const { + return { v[1], v[1], v[0], v[3] }; + } + + GenoVector<4, T> getYYYX() const { + return { v[1], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getYYYY() const { + return { v[1], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getYYYZ() const { + return { v[1], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getYYYW() const { + return { v[1], v[1], v[1], v[3] }; + } + + GenoVector<4, T> getYYZX() const { + return { v[1], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getYYZY() const { + return { v[1], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getYYZZ() const { + return { v[1], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getYYZW() const { + return { v[1], v[1], v[2], v[3] }; + } + + GenoVector<4, T> getYYWX() const { + return { v[1], v[1], v[3], v[0] }; + } + + GenoVector<4, T> getYYWY() const { + return { v[1], v[1], v[3], v[1] }; + } + + GenoVector<4, T> getYYWZ() const { + return { v[1], v[1], v[3], v[2] }; + } + + GenoVector<4, T> getYYWW() const { + return { v[1], v[1], v[3], v[3] }; + } + + GenoVector<4, T> getYZXX() const { + return { v[1], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getYZXY() const { + return { v[1], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getYZXZ() const { + return { v[1], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getYZXW() const { + return { v[1], v[2], v[0], v[3] }; + } + + GenoVector<4, T> getYZYX() const { + return { v[1], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getYZYY() const { + return { v[1], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getYZYZ() const { + return { v[1], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getYZYW() const { + return { v[1], v[2], v[1], v[3] }; + } + + GenoVector<4, T> getYZZX() const { + return { v[1], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getYZZY() const { + return { v[1], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getYZZZ() const { + return { v[1], v[2], v[2], v[2] }; + } + + GenoVector<4, T> getYZZW() const { + return { v[1], v[2], v[2], v[3] }; + } + + GenoVector<4, T> getYZWX() const { + return { v[1], v[2], v[3], v[0] }; + } + + GenoVector<4, T> getYZWY() const { + return { v[1], v[2], v[3], v[1] }; + } + + GenoVector<4, T> getYZWZ() const { + return { v[1], v[2], v[3], v[2] }; + } + + GenoVector<4, T> getYZWW() const { + return { v[1], v[2], v[3], v[3] }; + } + + GenoVector<4, T> getYWXX() const { + return { v[1], v[3], v[0], v[0] }; + } + + GenoVector<4, T> getYWXY() const { + return { v[1], v[3], v[0], v[1] }; + } + + GenoVector<4, T> getYWXZ() const { + return { v[1], v[3], v[0], v[2] }; + } + + GenoVector<4, T> getYWXW() const { + return { v[1], v[3], v[0], v[3] }; + } + + GenoVector<4, T> getYWYX() const { + return { v[1], v[3], v[1], v[0] }; + } + + GenoVector<4, T> getYWYY() const { + return { v[1], v[3], v[1], v[1] }; + } + + GenoVector<4, T> getYWYZ() const { + return { v[1], v[3], v[1], v[2] }; + } + + GenoVector<4, T> getYWYW() const { + return { v[1], v[3], v[1], v[3] }; + } + + GenoVector<4, T> getYWZX() const { + return { v[1], v[3], v[2], v[0] }; + } + + GenoVector<4, T> getYWZY() const { + return { v[1], v[3], v[2], v[1] }; + } + + GenoVector<4, T> getYWZZ() const { + return { v[1], v[3], v[2], v[2] }; + } + + GenoVector<4, T> getYWZW() const { + return { v[1], v[3], v[2], v[3] }; + } + + GenoVector<4, T> getYWWX() const { + return { v[1], v[3], v[3], v[0] }; + } + + GenoVector<4, T> getYWWY() const { + return { v[1], v[3], v[3], v[1] }; + } + + GenoVector<4, T> getYWWZ() const { + return { v[1], v[3], v[3], v[2] }; + } + + GenoVector<4, T> getYWWW() const { + return { v[1], v[3], v[3], v[3] }; + } + + GenoVector<4, T> getZXXX() const { + return { v[2], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getZXXY() const { + return { v[2], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getZXXZ() const { + return { v[2], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getZXXW() const { + return { v[2], v[0], v[0], v[3] }; + } + + GenoVector<4, T> getZXYX() const { + return { v[2], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getZXYY() const { + return { v[2], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getZXYZ() const { + return { v[2], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getZXYW() const { + return { v[2], v[0], v[1], v[3] }; + } + + GenoVector<4, T> getZXZX() const { + return { v[2], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getZXZY() const { + return { v[2], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getZXZZ() const { + return { v[2], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getZXZW() const { + return { v[2], v[0], v[2], v[3] }; + } + + GenoVector<4, T> getZXWX() const { + return { v[2], v[0], v[3], v[0] }; + } + + GenoVector<4, T> getZXWY() const { + return { v[2], v[0], v[3], v[1] }; + } + + GenoVector<4, T> getZXWZ() const { + return { v[2], v[0], v[3], v[2] }; + } + + GenoVector<4, T> getZXWW() const { + return { v[2], v[0], v[3], v[3] }; + } + + GenoVector<4, T> getZYXX() const { + return { v[2], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getZYXY() const { + return { v[2], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getZYXZ() const { + return { v[2], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getZYXW() const { + return { v[2], v[1], v[0], v[3] }; + } + + GenoVector<4, T> getZYYX() const { + return { v[2], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getZYYY() const { + return { v[2], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getZYYZ() const { + return { v[2], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getZYYW() const { + return { v[2], v[1], v[1], v[3] }; + } + + GenoVector<4, T> getZYZX() const { + return { v[2], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getZYZY() const { + return { v[2], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getZYZZ() const { + return { v[2], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getZYZW() const { + return { v[2], v[1], v[2], v[3] }; + } + + GenoVector<4, T> getZYWX() const { + return { v[2], v[1], v[3], v[0] }; + } + + GenoVector<4, T> getZYWY() const { + return { v[2], v[1], v[3], v[1] }; + } + + GenoVector<4, T> getZYWZ() const { + return { v[2], v[1], v[3], v[2] }; + } + + GenoVector<4, T> getZYWW() const { + return { v[2], v[1], v[3], v[3] }; + } + + GenoVector<4, T> getZZXX() const { + return { v[2], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getZZXY() const { + return { v[2], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getZZXZ() const { + return { v[2], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getZZXW() const { + return { v[2], v[2], v[0], v[3] }; + } + + GenoVector<4, T> getZZYX() const { + return { v[2], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getZZYY() const { + return { v[2], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getZZYZ() const { + return { v[2], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getZZYW() const { + return { v[2], v[2], v[1], v[3] }; + } + + GenoVector<4, T> getZZZX() const { + return { v[2], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getZZZY() const { + return { v[2], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getZZZZ() const { + return { v[2], v[2], v[2], v[2] }; + } + + GenoVector<4, T> getZZZW() const { + return { v[2], v[2], v[2], v[3] }; + } + + GenoVector<4, T> getZZWX() const { + return { v[2], v[2], v[3], v[0] }; + } + + GenoVector<4, T> getZZWY() const { + return { v[2], v[2], v[3], v[1] }; + } + + GenoVector<4, T> getZZWZ() const { + return { v[2], v[2], v[3], v[2] }; + } + + GenoVector<4, T> getZZWW() const { + return { v[2], v[2], v[3], v[3] }; + } + + GenoVector<4, T> getZWXX() const { + return { v[2], v[3], v[0], v[0] }; + } + + GenoVector<4, T> getZWXY() const { + return { v[2], v[3], v[0], v[1] }; + } + + GenoVector<4, T> getZWXZ() const { + return { v[2], v[3], v[0], v[2] }; + } + + GenoVector<4, T> getZWXW() const { + return { v[2], v[3], v[0], v[3] }; + } + + GenoVector<4, T> getZWYX() const { + return { v[2], v[3], v[1], v[0] }; + } + + GenoVector<4, T> getZWYY() const { + return { v[2], v[3], v[1], v[1] }; + } + + GenoVector<4, T> getZWYZ() const { + return { v[2], v[3], v[1], v[2] }; + } + + GenoVector<4, T> getZWYW() const { + return { v[2], v[3], v[1], v[3] }; + } + + GenoVector<4, T> getZWZX() const { + return { v[2], v[3], v[2], v[0] }; + } + + GenoVector<4, T> getZWZY() const { + return { v[2], v[3], v[2], v[1] }; + } + + GenoVector<4, T> getZWZZ() const { + return { v[2], v[3], v[2], v[2] }; + } + + GenoVector<4, T> getZWZW() const { + return { v[2], v[3], v[2], v[3] }; + } + + GenoVector<4, T> getZWWX() const { + return { v[2], v[3], v[3], v[0] }; + } + + GenoVector<4, T> getZWWY() const { + return { v[2], v[3], v[3], v[1] }; + } + + GenoVector<4, T> getZWWZ() const { + return { v[2], v[3], v[3], v[2] }; + } + + GenoVector<4, T> getZWWW() const { + return { v[2], v[3], v[3], v[3] }; + } + + GenoVector<4, T> getWXXX() const { + return { v[3], v[0], v[0], v[0] }; + } + + GenoVector<4, T> getWXXY() const { + return { v[3], v[0], v[0], v[1] }; + } + + GenoVector<4, T> getWXXZ() const { + return { v[3], v[0], v[0], v[2] }; + } + + GenoVector<4, T> getWXXW() const { + return { v[3], v[0], v[0], v[3] }; + } + + GenoVector<4, T> getWXYX() const { + return { v[3], v[0], v[1], v[0] }; + } + + GenoVector<4, T> getWXYY() const { + return { v[3], v[0], v[1], v[1] }; + } + + GenoVector<4, T> getWXYZ() const { + return { v[3], v[0], v[1], v[2] }; + } + + GenoVector<4, T> getWXYW() const { + return { v[3], v[0], v[1], v[3] }; + } + + GenoVector<4, T> getWXZX() const { + return { v[3], v[0], v[2], v[0] }; + } + + GenoVector<4, T> getWXZY() const { + return { v[3], v[0], v[2], v[1] }; + } + + GenoVector<4, T> getWXZZ() const { + return { v[3], v[0], v[2], v[2] }; + } + + GenoVector<4, T> getWXZW() const { + return { v[3], v[0], v[2], v[3] }; + } + + GenoVector<4, T> getWXWX() const { + return { v[3], v[0], v[3], v[0] }; + } + + GenoVector<4, T> getWXWY() const { + return { v[3], v[0], v[3], v[1] }; + } + + GenoVector<4, T> getWXWZ() const { + return { v[3], v[0], v[3], v[2] }; + } + + GenoVector<4, T> getWXWW() const { + return { v[3], v[0], v[3], v[3] }; + } + + GenoVector<4, T> getWYXX() const { + return { v[3], v[1], v[0], v[0] }; + } + + GenoVector<4, T> getWYXY() const { + return { v[3], v[1], v[0], v[1] }; + } + + GenoVector<4, T> getWYXZ() const { + return { v[3], v[1], v[0], v[2] }; + } + + GenoVector<4, T> getWYXW() const { + return { v[3], v[1], v[0], v[3] }; + } + + GenoVector<4, T> getWYYX() const { + return { v[3], v[1], v[1], v[0] }; + } + + GenoVector<4, T> getWYYY() const { + return { v[3], v[1], v[1], v[1] }; + } + + GenoVector<4, T> getWYYZ() const { + return { v[3], v[1], v[1], v[2] }; + } + + GenoVector<4, T> getWYYW() const { + return { v[3], v[1], v[1], v[3] }; + } + + GenoVector<4, T> getWYZX() const { + return { v[3], v[1], v[2], v[0] }; + } + + GenoVector<4, T> getWYZY() const { + return { v[3], v[1], v[2], v[1] }; + } + + GenoVector<4, T> getWYZZ() const { + return { v[3], v[1], v[2], v[2] }; + } + + GenoVector<4, T> getWYZW() const { + return { v[3], v[1], v[2], v[3] }; + } + + GenoVector<4, T> getWYWX() const { + return { v[3], v[1], v[3], v[0] }; + } + + GenoVector<4, T> getWYWY() const { + return { v[3], v[1], v[3], v[1] }; + } + + GenoVector<4, T> getWYWZ() const { + return { v[3], v[1], v[3], v[2] }; + } + + GenoVector<4, T> getWYWW() const { + return { v[3], v[1], v[3], v[3] }; + } + + GenoVector<4, T> getWZXX() const { + return { v[3], v[2], v[0], v[0] }; + } + + GenoVector<4, T> getWZXY() const { + return { v[3], v[2], v[0], v[1] }; + } + + GenoVector<4, T> getWZXZ() const { + return { v[3], v[2], v[0], v[2] }; + } + + GenoVector<4, T> getWZXW() const { + return { v[3], v[2], v[0], v[3] }; + } + + GenoVector<4, T> getWZYX() const { + return { v[3], v[2], v[1], v[0] }; + } + + GenoVector<4, T> getWZYY() const { + return { v[3], v[2], v[1], v[1] }; + } + + GenoVector<4, T> getWZYZ() const { + return { v[3], v[2], v[1], v[2] }; + } + + GenoVector<4, T> getWZYW() const { + return { v[3], v[2], v[1], v[3] }; + } + + GenoVector<4, T> getWZZX() const { + return { v[3], v[2], v[2], v[0] }; + } + + GenoVector<4, T> getWZZY() const { + return { v[3], v[2], v[2], v[1] }; + } + + GenoVector<4, T> getWZZZ() const { + return { v[3], v[2], v[2], v[2] }; + } + + GenoVector<4, T> getWZZW() const { + return { v[3], v[2], v[2], v[3] }; + } + + GenoVector<4, T> getWZWX() const { + return { v[3], v[2], v[3], v[0] }; + } + + GenoVector<4, T> getWZWY() const { + return { v[3], v[2], v[3], v[1] }; + } + + GenoVector<4, T> getWZWZ() const { + return { v[3], v[2], v[3], v[2] }; + } + + GenoVector<4, T> getWZWW() const { + return { v[3], v[2], v[3], v[3] }; + } + + GenoVector<4, T> getWWXX() const { + return { v[3], v[3], v[0], v[0] }; + } + + GenoVector<4, T> getWWXY() const { + return { v[3], v[3], v[0], v[1] }; + } + + GenoVector<4, T> getWWXZ() const { + return { v[3], v[3], v[0], v[2] }; + } + + GenoVector<4, T> getWWXW() const { + return { v[3], v[3], v[0], v[3] }; + } + + GenoVector<4, T> getWWYX() const { + return { v[3], v[3], v[1], v[0] }; + } + + GenoVector<4, T> getWWYY() const { + return { v[3], v[3], v[1], v[1] }; + } + + GenoVector<4, T> getWWYZ() const { + return { v[3], v[3], v[1], v[2] }; + } + + GenoVector<4, T> getWWYW() const { + return { v[3], v[3], v[1], v[3] }; + } + + GenoVector<4, T> getWWZX() const { + return { v[3], v[3], v[2], v[0] }; + } + + GenoVector<4, T> getWWZY() const { + return { v[3], v[3], v[2], v[1] }; + } + + GenoVector<4, T> getWWZZ() const { + return { v[3], v[3], v[2], v[2] }; + } + + GenoVector<4, T> getWWZW() const { + return { v[3], v[3], v[2], v[3] }; + } + + GenoVector<4, T> getWWWX() const { + return { v[3], v[3], v[3], v[0] }; + } + + GenoVector<4, T> getWWWY() const { + return { v[3], v[3], v[3], v[1] }; + } + + GenoVector<4, T> getWWWZ() const { + return { v[3], v[3], v[3], v[2] }; + } + + GenoVector<4, T> getWWWW() const { + return { v[3], v[3], v[3], v[3] }; + } + + virtual ~GenoVector() noexcept { + clean(); + } +}; + +template +GenoVector<4, T> operator-(const GenoVector<4, T> & vector) { + return { + -vector.v[0], + -vector.v[1], + -vector.v[2], + -vector.v[3] + }; +} + +template +GenoVector<4, T> operator+(const GenoVector<4, T> & left, const GenoVector<4, T> & right) { + return { + left.v[0] + right.v[0], + left.v[1] + right.v[1], + left.v[2] + right.v[2], + left.v[3] + right.v[3] + }; +} + +template +GenoVector<4, T> operator-(const GenoVector<4, T> & left, const GenoVector<4, T> & right) { + return { + left.v[0] - right.v[0], + left.v[1] - right.v[1], + left.v[2] - right.v[2], + left.v[3] - right.v[3] + }; +} + +template +GenoVector<4, T> operator*(T left, const GenoVector<4, T> & right) { + return { + left * right.v[0], + left * right.v[1], + left * right.v[2], + left * right.v[3] + }; +} + +template +GenoVector<4, T> operator*(const GenoVector<4, T> & left, T right) { + return { + left.v[0] * right, + left.v[1] * right, + left.v[2] * right, + left.v[3] * right + }; +} + +template +GenoVector<4, T> operator*(const GenoVector<4, T> & left, const GenoVector<4, T> & right) { + return { + left.v[0] * right.v[0], + left.v[1] * right.v[1], + left.v[2] * right.v[2], + left.v[3] * right.v[3] + }; +} + +template +GenoVector<4, T> operator/(const GenoVector<4, T> & left, T right) { + return { + left.v[0] / right, + left.v[1] / right, + left.v[2] / right, + left.v[3] / right + }; +} + +template +GenoVector<4, T> operator/(const GenoVector<4, T> & left, const GenoVector<4, T> & right) { + return { + left.v[0] / right.v[0], + left.v[1] / right.v[1], + left.v[2] / right.v[2], + left.v[3] / right.v[3] + }; +} + +template +GenoVector<4, T> setLength(const GenoVector<4, T> & vector, T length) { + auto scalar = length / vector.getLength(); + return { + vector.v[0] * scalar, + vector.v[1] * scalar, + vector.v[2] * scalar, + vector.v[3] * scalar + }; +} + +template +GenoVector<4, T> & setLength(const GenoVector<4, T> & vector, T length, GenoVector<4, T> & target) { + auto scalar = length / vector.getLength(); + target.v[0] = vector.v[0] * scalar; + target.v[1] = vector.v[1] * scalar; + target.v[2] = vector.v[2] * scalar; + target.v[3] = vector.v[3] * scalar; + return target; +} + +template +GenoVector<4, T> normalize(const GenoVector<4, T> & vector) { + auto scalar = 1 / vector.getLength(); + return { + vector.v[0] * scalar, + vector.v[1] * scalar, + vector.v[2] * scalar, + vector.v[3] * scalar + }; +} + +template +GenoVector<4, T> & normalize(const GenoVector<4, T> & vector, GenoVector<4, T> & target) { + auto scalar = 1 / vector.getLength(); + target.v[0] = vector.v[0] * scalar; + target.v[1] = vector.v[1] * scalar; + target.v[2] = vector.v[2] * scalar; + target.v[3] = vector.v[3] * scalar; + return target; +} + +template +GenoVector<4, T> negate(const GenoVector<4, T> & vector) { + return { + -vector.v[0], + -vector.v[1], + -vector.v[2], + -vector.v[3] + }; +} + +template +GenoVector<4, T> & negate(const GenoVector<4, T> & vector, GenoVector<4, T> & target) { + target.v[0] = -vector.v[0]; + target.v[1] = -vector.v[1]; + target.v[2] = -vector.v[2]; + target.v[3] = -vector.v[3]; + return target; +} + +template +T dot(const GenoVector<4, T> & left, const GenoVector<4, T> & right) { + return ( + left.v[0] * right.v[0] + + left.v[1] * right.v[1] + + left.v[2] * right.v[2] + + left.v[3] * right.v[3] + ); +} + +template +GenoVector<4, T> project(const GenoVector<4, T> & vector, const GenoVector<4, T> & projection) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + return { + scalar * projection.v[0], + scalar * projection.v[1], + scalar * projection.v[2], + scalar * projection.v[3] + }; +} + +template +GenoVector<4, T> & project(const GenoVector<4, T> & vector, const GenoVector<4, T> & projection, GenoVector<4, T> & target) { + auto scalar = dot(vector, projection) / projection.getLengthSquared(); + target.v[0] = scalar * projection.v[0]; + target.v[1] = scalar * projection.v[1]; + target.v[2] = scalar * projection.v[2]; + target.v[3] = scalar * projection.v[3]; + return target; +} + +template +GenoVector<4, T> translate(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> & translate(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> scale(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2] * scale, + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> & scale(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scale(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> & scale(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> setX(const GenoVector<4, T> & vector, T x) { + return { + x, + vector.v[1], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setY(const GenoVector<4, T> & vector, T y) { + return { + vector.v[0], + y, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setZ(const GenoVector<4, T> & vector, T z) { + return { + vector.v[0], + vector.v[1], + z, + vector.v[3] + }; +} + +template +GenoVector<4, T> setW(const GenoVector<4, T> & vector, T w) { + return { + vector.v[0], + vector.v[1], + vector.v[2], + w + }; +} + +template +GenoVector<4, T> setXY(const GenoVector<4, T> & vector, T x, T y) { + return { + x, + y, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setXY(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[0], + set.v[1], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setXZ(const GenoVector<4, T> & vector, T x, T z) { + return { + x, + vector.v[1], + z, + vector.v[3] + }; +} + +template +GenoVector<4, T> setXZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[0], + vector.v[1], + set.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> setXW(const GenoVector<4, T> & vector, T x, T w) { + return { + x, + vector.v[1], + vector.v[2], + w + }; +} + +template +GenoVector<4, T> setXW(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[0], + vector.v[1], + vector.v[2], + set.v[1] + }; +} + +template +GenoVector<4, T> setYX(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[1], + set.v[0], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setYZ(const GenoVector<4, T> & vector, T y, T z) { + return { + vector.v[0], + y, + z, + vector.v[3] + }; +} + +template +GenoVector<4, T> setYZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + set.v[0], + set.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> setYW(const GenoVector<4, T> & vector, T y, T w) { + return { + vector.v[0], + y, + vector.v[2], + w + }; +} + +template +GenoVector<4, T> setYW(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + set.v[0], + vector.v[2], + set.v[1] + }; +} + +template +GenoVector<4, T> setZX(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[1], + vector.v[1], + set.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> setZY(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + set.v[1], + set.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> setZW(const GenoVector<4, T> & vector, T z, T w) { + return { + vector.v[0], + vector.v[1], + z, + w + }; +} + +template +GenoVector<4, T> setZW(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + vector.v[1], + set.v[0], + set.v[1] + }; +} + +template +GenoVector<4, T> setWX(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + set.v[1], + vector.v[1], + vector.v[2], + set.v[0] + }; +} + +template +GenoVector<4, T> setWY(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + set.v[1], + vector.v[2], + set.v[0] + }; +} + +template +GenoVector<4, T> setWZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & set) { + return { + vector.v[0], + vector.v[1], + set.v[1], + set.v[0] + }; +} + +template +GenoVector<4, T> setXYZ(const GenoVector<4, T> & vector, T x, T y, T z) { + return { + x, + y, + z, + vector.v[3] + }; +} + +template +GenoVector<4, T> setXYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[0], + set.v[1], + set.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setXYW(const GenoVector<4, T> & vector, T x, T y, T w) { + return { + x, + y, + vector.v[2], + w + }; +} + +template +GenoVector<4, T> setXYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[0], + set.v[1], + vector.v[2], + set.v[2] + }; +} + +template +GenoVector<4, T> setXZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[0], + set.v[2], + set.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> setXZW(const GenoVector<4, T> & vector, T x, T z, T w) { + return { + x, + vector.v[1], + z, + w + }; +} + +template +GenoVector<4, T> setXZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[0], + vector.v[1], + set.v[1], + set.v[2] + }; +} + +template +GenoVector<4, T> setXWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[0], + set.v[2], + vector.v[2], + set.v[1] + }; +} + +template +GenoVector<4, T> setXWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[0], + vector.v[1], + set.v[2], + set.v[1] + }; +} + +template +GenoVector<4, T> setYXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[1], + set.v[0], + set.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> setYXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[1], + set.v[0], + vector.v[2], + set.v[2] + }; +} + +template +GenoVector<4, T> setYZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[2], + set.v[0], + set.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> setYZW(const GenoVector<4, T> & vector, T y, T z, T w) { + return { + vector.v[0], + y, + z, + w + }; +} + +template +GenoVector<4, T> setYZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + vector.v[0], + set.v[0], + set.v[1], + set.v[2] + }; +} + +template +GenoVector<4, T> setYWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[2], + set.v[0], + vector.v[2], + set.v[1] + }; +} + +template +GenoVector<4, T> setYWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + vector.v[0], + set.v[0], + set.v[2], + set.v[1] + }; +} + +template +GenoVector<4, T> setZXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[1], + set.v[2], + set.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> setZXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[1], + vector.v[1], + set.v[0], + set.v[2] + }; +} + +template +GenoVector<4, T> setZYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[2], + set.v[1], + set.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> setZYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + vector.v[0], + set.v[1], + set.v[0], + set.v[2] + }; +} + +template +GenoVector<4, T> setZWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[2], + vector.v[1], + set.v[0], + set.v[1] + }; +} + +template +GenoVector<4, T> setZWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + vector.v[0], + set.v[2], + set.v[0], + set.v[1] + }; +} + +template +GenoVector<4, T> setWXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[1], + set.v[2], + vector.v[2], + set.v[0] + }; +} + +template +GenoVector<4, T> setWXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[1], + vector.v[1], + set.v[2], + set.v[0] + }; +} + +template +GenoVector<4, T> setWYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[2], + set.v[1], + vector.v[2], + set.v[0] + }; +} + +template +GenoVector<4, T> setWYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + vector.v[0], + set.v[1], + set.v[2], + set.v[0] + }; +} + +template +GenoVector<4, T> setWZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + set.v[2], + vector.v[1], + set.v[1], + set.v[0] + }; +} + +template +GenoVector<4, T> setWZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set) { + return { + vector.v[0], + set.v[2], + set.v[1], + set.v[0] + }; +} + +template +GenoVector<4, T> setX(const GenoVector<4, T> & vector, T x, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setY(const GenoVector<4, T> & vector, T y, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setZ(const GenoVector<4, T> & vector, T z, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = z; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setW(const GenoVector<4, T> & vector, T w, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setXY(const GenoVector<4, T> & vector, T x, T y, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = y; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXY(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = set.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXZ(const GenoVector<4, T> & vector, T x, T z, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + target.v[2] = z; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXW(const GenoVector<4, T> & vector, T x, T w, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setXW(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setYX(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = set.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setYZ(const GenoVector<4, T> & vector, T y, T z, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + target.v[2] = z; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setYZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[0]; + target.v[2] = set.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setYW(const GenoVector<4, T> & vector, T y, T w, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + target.v[2] = vector.v[2]; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setYW(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setZX(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setZY(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[1]; + target.v[2] = set.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setZW(const GenoVector<4, T> & vector, T z, T w, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = z; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setZW(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[0]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setWX(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWY(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[1]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setXYZ(const GenoVector<4, T> & vector, T x, T y, T z, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = y; + target.v[2] = z; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = set.v[1]; + target.v[2] = set.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXYW(const GenoVector<4, T> & vector, T x, T y, T w, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = y; + target.v[2] = vector.v[2]; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setXYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = set.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[2]; + return target; +} + +template +GenoVector<4, T> setXZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = set.v[2]; + target.v[2] = set.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setXZW(const GenoVector<4, T> & vector, T x, T z, T w, GenoVector<4, T> & target) { + target.v[0] = x; + target.v[1] = vector.v[1]; + target.v[2] = z; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setXZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[1]; + target.v[3] = set.v[2]; + return target; +} + +template +GenoVector<4, T> setXWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = set.v[2]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setXWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[2]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setYXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = set.v[0]; + target.v[2] = set.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setYXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = set.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[2]; + return target; +} + +template +GenoVector<4, T> setYZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[2]; + target.v[1] = set.v[0]; + target.v[2] = set.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setYZW(const GenoVector<4, T> & vector, T y, T z, T w, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = y; + target.v[2] = z; + target.v[3] = w; + return target; +} + +template +GenoVector<4, T> setYZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[0]; + target.v[2] = set.v[1]; + target.v[3] = set.v[2]; + return target; +} + +template +GenoVector<4, T> setYWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[2]; + target.v[1] = set.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setYWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[0]; + target.v[2] = set.v[2]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setZXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = set.v[2]; + target.v[2] = set.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setZXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[0]; + target.v[3] = set.v[2]; + return target; +} + +template +GenoVector<4, T> setZYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[2]; + target.v[1] = set.v[1]; + target.v[2] = set.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> setZYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[1]; + target.v[2] = set.v[0]; + target.v[3] = set.v[2]; + return target; +} + +template +GenoVector<4, T> setZWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[2]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[0]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setZWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[2]; + target.v[2] = set.v[0]; + target.v[3] = set.v[1]; + return target; +} + +template +GenoVector<4, T> setWXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = set.v[2]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[2]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[2]; + target.v[1] = set.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[1]; + target.v[2] = set.v[2]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = set.v[2]; + target.v[1] = vector.v[1]; + target.v[2] = set.v[1]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> setWZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & set, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = set.v[2]; + target.v[2] = set.v[1]; + target.v[3] = set.v[0]; + return target; +} + +template +GenoVector<4, T> translateX(const GenoVector<4, T> & vector, T translateX) { + return { + vector.v[0] + translateX, + vector.v[1], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateY(const GenoVector<4, T> & vector, T translateY) { + return { + vector.v[0], + vector.v[1] + translateY, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateZ(const GenoVector<4, T> & vector, T translateZ) { + return { + vector.v[0], + vector.v[1], + vector.v[2] + translateZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> translateW(const GenoVector<4, T> & vector, T translateW) { + return { + vector.v[0], + vector.v[1], + vector.v[2], + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateXY(const GenoVector<4, T> & vector, T translateX, T translateY) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXY(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXZ(const GenoVector<4, T> & vector, T translateX, T translateZ) { + return { + vector.v[0] + translateX, + vector.v[1], + vector.v[2] + translateZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1], + vector.v[2] + translate.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXW(const GenoVector<4, T> & vector, T translateX, T translateW) { + return { + vector.v[0] + translateX, + vector.v[1], + vector.v[2], + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateXW(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1], + vector.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateYX(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateYZ(const GenoVector<4, T> & vector, T translateY, T translateZ) { + return { + vector.v[0], + vector.v[1] + translateY, + vector.v[2] + translateZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> translateYZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateYW(const GenoVector<4, T> & vector, T translateY, T translateW) { + return { + vector.v[0], + vector.v[1] + translateY, + vector.v[2], + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateYW(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[0], + vector.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateZX(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateZY(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateZW(const GenoVector<4, T> & vector, T translateZ, T translateW) { + return { + vector.v[0], + vector.v[1], + vector.v[2] + translateZ, + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateZW(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateWX(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1], + vector.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWY(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[1], + vector.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate) { + return { + vector.v[0], + vector.v[1], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateXYZ(const GenoVector<4, T> & vector, T translateX, T translateY, T translateZ) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY, + vector.v[2] + translateZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXYW(const GenoVector<4, T> & vector, T translateX, T translateY, T translateW) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY, + vector.v[2], + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateXYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateXZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateXZW(const GenoVector<4, T> & vector, T translateX, T translateZ, T translateW) { + return { + vector.v[0] + translateX, + vector.v[1], + vector.v[2] + translateZ, + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateXZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateXWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[2], + vector.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateXWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateYXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateYXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateYZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateYZW(const GenoVector<4, T> & vector, T translateY, T translateZ, T translateW) { + return { + vector.v[0], + vector.v[1] + translateY, + vector.v[2] + translateZ, + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateYZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateYWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[0], + vector.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateYWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateZXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateZXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateZYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> translateZYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateZWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateZWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateWXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[2], + vector.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[1], + vector.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate) { + return { + vector.v[0], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateXYZW(const GenoVector<4, T> & vector, T translateX, T translateY, T translateZ, T translateW) { + return { + vector.v[0] + translateX, + vector.v[1] + translateY, + vector.v[2] + translateZ, + vector.v[3] + translateW + }; +} + +template +GenoVector<4, T> translateXYZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> translateXYWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[3], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateXZYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> translateXZWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[3], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateXWYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[3], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateXWZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[0], + vector.v[1] + translate.v[3], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateYXZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> translateYXWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[3], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateYZXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> translateYZWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[3], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateYWXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[3], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateYWZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[3], + vector.v[1] + translate.v[0], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateZXYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> translateZXWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[3], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateZYXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[3] + }; +} + +template +GenoVector<4, T> translateZYWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[3], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[2] + }; +} + +template +GenoVector<4, T> translateZWXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[3], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateZWYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[3], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[0], + vector.v[3] + translate.v[1] + }; +} + +template +GenoVector<4, T> translateWXYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[3], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWXZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[1], + vector.v[1] + translate.v[3], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWYXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[3], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWYZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[3], + vector.v[1] + translate.v[1], + vector.v[2] + translate.v[2], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWZXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[2], + vector.v[1] + translate.v[3], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateWZYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate) { + return { + vector.v[0] + translate.v[3], + vector.v[1] + translate.v[2], + vector.v[2] + translate.v[1], + vector.v[3] + translate.v[0] + }; +} + +template +GenoVector<4, T> translateX(const GenoVector<4, T> & vector, T translateX, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateY(const GenoVector<4, T> & vector, T translateY, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateZ(const GenoVector<4, T> & vector, T translateZ, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateW(const GenoVector<4, T> & vector, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateXY(const GenoVector<4, T> & vector, T translateX, T translateY, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXY(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXZ(const GenoVector<4, T> & vector, T translateX, T translateZ, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXW(const GenoVector<4, T> & vector, T translateX, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateXW(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateYX(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateYZ(const GenoVector<4, T> & vector, T translateY, T translateZ, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateYZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateYW(const GenoVector<4, T> & vector, T translateY, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateYW(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateZX(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateZY(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateZW(const GenoVector<4, T> & vector, T translateZ, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateZW(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateWX(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWY(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateXYZ(const GenoVector<4, T> & vector, T translateX, T translateY, T translateZ, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXYW(const GenoVector<4, T> & vector, T translateX, T translateY, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateXYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateXZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateXZW(const GenoVector<4, T> & vector, T translateX, T translateZ, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateXZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateXWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateXWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateYXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateYXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateYZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateYZW(const GenoVector<4, T> & vector, T translateY, T translateZ, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateYZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateYWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateYWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateZXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateZXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateZYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> translateZYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateZWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateZWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateWXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateXYZW(const GenoVector<4, T> & vector, T translateX, T translateY, T translateZ, T translateW, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translateX; + target.v[1] = vector.v[1] + translateY; + target.v[2] = vector.v[2] + translateZ; + target.v[3] = vector.v[3] + translateW; + return target; +} + +template +GenoVector<4, T> translateXYZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> translateXYWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[3]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateXZYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> translateXZWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[3]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateXWYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[3]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateXWZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[0]; + target.v[1] = vector.v[1] + translate.v[3]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateYXZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> translateYXWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[3]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateYZXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> translateYZWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[3]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateYWXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[3]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateYWZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[3]; + target.v[1] = vector.v[1] + translate.v[0]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateZXYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> translateZXWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[3]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateZYXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[3]; + return target; +} + +template +GenoVector<4, T> translateZYWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[3]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[2]; + return target; +} + +template +GenoVector<4, T> translateZWXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[3]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateZWYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[3]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[0]; + target.v[3] = vector.v[3] + translate.v[1]; + return target; +} + +template +GenoVector<4, T> translateWXYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[3]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWXZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[1]; + target.v[1] = vector.v[1] + translate.v[3]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWYXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[3]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWYZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[3]; + target.v[1] = vector.v[1] + translate.v[1]; + target.v[2] = vector.v[2] + translate.v[2]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWZXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[2]; + target.v[1] = vector.v[1] + translate.v[3]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> translateWZYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & translate, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] + translate.v[3]; + target.v[1] = vector.v[1] + translate.v[2]; + target.v[2] = vector.v[2] + translate.v[1]; + target.v[3] = vector.v[3] + translate.v[0]; + return target; +} + +template +GenoVector<4, T> scaleX(const GenoVector<4, T> & vector, T scaleX) { + return { + vector.v[0] * scaleX, + vector.v[1], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleY(const GenoVector<4, T> & vector, T scaleY) { + return { + vector.v[0], + vector.v[1] * scaleY, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleZ(const GenoVector<4, T> & vector, T scaleZ) { + return { + vector.v[0], + vector.v[1], + vector.v[2] * scaleZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleW(const GenoVector<4, T> & vector, T scaleW) { + return { + vector.v[0], + vector.v[1], + vector.v[2], + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleXY(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXY(const GenoVector<4, T> & vector, T scaleX, T scaleY) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY, + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXY(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXZ(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1], + vector.v[2] * scale, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXZ(const GenoVector<4, T> & vector, T scaleX, T scaleZ) { + return { + vector.v[0] * scaleX, + vector.v[1], + vector.v[2] * scaleZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1], + vector.v[2] * scale.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1], + vector.v[2], + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleXW(const GenoVector<4, T> & vector, T scaleX, T scaleW) { + return { + vector.v[0] * scaleX, + vector.v[1], + vector.v[2], + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleXW(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1], + vector.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleYX(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleYZ(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0], + vector.v[1] * scale, + vector.v[2] * scale, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleYZ(const GenoVector<4, T> & vector, T scaleY, T scaleZ) { + return { + vector.v[0], + vector.v[1] * scaleY, + vector.v[2] * scaleZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleYZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleYW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0], + vector.v[1] * scale, + vector.v[2], + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleYW(const GenoVector<4, T> & vector, T scaleY, T scaleW) { + return { + vector.v[0], + vector.v[1] * scaleY, + vector.v[2], + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleYW(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[0], + vector.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleZX(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1], + vector.v[2] * scale.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleZY(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleZW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0], + vector.v[1], + vector.v[2] * scale, + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleZW(const GenoVector<4, T> & vector, T scaleZ, T scaleW) { + return { + vector.v[0], + vector.v[1], + vector.v[2] * scaleZ, + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleZW(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleWX(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1], + vector.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWY(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[1], + vector.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale) { + return { + vector.v[0], + vector.v[1], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleXYZ(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2] * scale, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXYZ(const GenoVector<4, T> & vector, T scaleX, T scaleY, T scaleZ) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY, + vector.v[2] * scaleZ, + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXYW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2], + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleXYW(const GenoVector<4, T> & vector, T scaleX, T scaleY, T scaleW) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY, + vector.v[2], + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleXYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleXZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleXZW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1], + vector.v[2] * scale, + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleXZW(const GenoVector<4, T> & vector, T scaleX, T scaleZ, T scaleW) { + return { + vector.v[0] * scaleX, + vector.v[1], + vector.v[2] * scaleZ, + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleXZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleXWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[2], + vector.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleXWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleYXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[2], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleYXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleYZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleYZW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0], + vector.v[1] * scale, + vector.v[2] * scale, + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleYZW(const GenoVector<4, T> & vector, T scaleY, T scaleZ, T scaleW) { + return { + vector.v[0], + vector.v[1] * scaleY, + vector.v[2] * scaleZ, + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleYZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleYWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[0], + vector.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleYWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleZXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleZXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleZYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0], + vector.v[3] + }; +} + +template +GenoVector<4, T> scaleZYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleZWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleZWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleWXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[2], + vector.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[1], + vector.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale) { + return { + vector.v[0], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleXYZW(const GenoVector<4, T> & vector, T scale) { + return { + vector.v[0] * scale, + vector.v[1] * scale, + vector.v[2] * scale, + vector.v[3] * scale + }; +} + +template +GenoVector<4, T> scaleXYZW(const GenoVector<4, T> & vector, T scaleX, T scaleY, T scaleZ, T scaleW) { + return { + vector.v[0] * scaleX, + vector.v[1] * scaleY, + vector.v[2] * scaleZ, + vector.v[3] * scaleW + }; +} + +template +GenoVector<4, T> scaleXYZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> scaleXYWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[3], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleXZYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> scaleXZWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[3], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleXWYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[3], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleXWZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[0], + vector.v[1] * scale.v[3], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleYXZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> scaleYXWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[3], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleYZXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> scaleYZWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[3], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleYWXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[3], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleYWZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[3], + vector.v[1] * scale.v[0], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleZXYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> scaleZXWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[3], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleZYXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[3] + }; +} + +template +GenoVector<4, T> scaleZYWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[3], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[2] + }; +} + +template +GenoVector<4, T> scaleZWXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[3], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleZWYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[3], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[0], + vector.v[3] * scale.v[1] + }; +} + +template +GenoVector<4, T> scaleWXYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[3], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWXZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[1], + vector.v[1] * scale.v[3], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWYXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[3], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWYZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[3], + vector.v[1] * scale.v[1], + vector.v[2] * scale.v[2], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWZXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[2], + vector.v[1] * scale.v[3], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleWZYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale) { + return { + vector.v[0] * scale.v[3], + vector.v[1] * scale.v[2], + vector.v[2] * scale.v[1], + vector.v[3] * scale.v[0] + }; +} + +template +GenoVector<4, T> scaleX(const GenoVector<4, T> & vector, T scaleX, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleY(const GenoVector<4, T> & vector, T scaleY, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZ(const GenoVector<4, T> & vector, T scaleZ, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleW(const GenoVector<4, T> & vector, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleXY(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXY(const GenoVector<4, T> & vector, T scaleX, T scaleY, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXY(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXZ(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXZ(const GenoVector<4, T> & vector, T scaleX, T scaleZ, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleXW(const GenoVector<4, T> & vector, T scaleX, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleXW(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleYX(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYZ(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYZ(const GenoVector<4, T> & vector, T scaleY, T scaleZ, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleYW(const GenoVector<4, T> & vector, T scaleY, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleYW(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleZX(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZY(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleZW(const GenoVector<4, T> & vector, T scaleZ, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleZW(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleWX(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWY(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWZ(const GenoVector<4, T> & vector, const GenoVector<2, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleXYZ(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXYZ(const GenoVector<4, T> & vector, T scaleX, T scaleY, T scaleZ, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXYW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleXYW(const GenoVector<4, T> & vector, T scaleX, T scaleY, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleXYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleXZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXZW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleXZW(const GenoVector<4, T> & vector, T scaleX, T scaleZ, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleXZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleXWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleXWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleYXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleYZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYZW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleYZW(const GenoVector<4, T> & vector, T scaleY, T scaleZ, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleYZW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleYWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleYWZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleZXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZXW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleZYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZYW(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleZWX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleZWY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleWXY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWXZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWYX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWYZ(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWZX(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWZY(const GenoVector<4, T> & vector, const GenoVector<3, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleXYZW(const GenoVector<4, T> & vector, T scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale; + target.v[1] = vector.v[1] * scale; + target.v[2] = vector.v[2] * scale; + target.v[3] = vector.v[3] * scale; + return target; +} + +template +GenoVector<4, T> scaleXYZW(const GenoVector<4, T> & vector, T scaleX, T scaleY, T scaleZ, T scaleW, const GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scaleX; + target.v[1] = vector.v[1] * scaleY; + target.v[2] = vector.v[2] * scaleZ; + target.v[3] = vector.v[3] * scaleW; + return target; +} + +template +GenoVector<4, T> scaleXYZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXYWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[3]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleXZYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> scaleXZWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[3]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleXWYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[3]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleXWZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[0]; + target.v[1] = vector.v[1] * scale.v[3]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleYXZW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYXWZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[3]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleYZXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> scaleYZWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[3]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleYWXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[3]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleYWZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[3]; + target.v[1] = vector.v[1] * scale.v[0]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleZXYW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZXWY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[3]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleZYXW(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[3]; + return target; +} + +template +GenoVector<4, T> scaleZYWX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[3]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[2]; + return target; +} + +template +GenoVector<4, T> scaleZWXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[3]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleZWYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[3]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[0]; + target.v[3] = vector.v[3] * scale.v[1]; + return target; +} + +template +GenoVector<4, T> scaleWXYZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[3]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWXZY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[1]; + target.v[1] = vector.v[1] * scale.v[3]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWYXZ(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[3]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWYZX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[3]; + target.v[1] = vector.v[1] * scale.v[1]; + target.v[2] = vector.v[2] * scale.v[2]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWZXY(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[2]; + target.v[1] = vector.v[1] * scale.v[3]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +GenoVector<4, T> scaleWZYX(const GenoVector<4, T> & vector, const GenoVector<4, T> & scale, GenoVector<4, T> & target) { + target.v[0] = vector.v[0] * scale.v[3]; + target.v[1] = vector.v[1] * scale.v[2]; + target.v[2] = vector.v[2] * scale.v[1]; + target.v[3] = vector.v[3] * scale.v[0]; + return target; +} + +template +std::ostream & operator<<(std::ostream & stream, const GenoVector<4, T> & vector) { + return stream << '<' << vector.v[0] << ", " << vector.v[1] << ", " << vector.v[2] << ", " << vector.v[3] << '>'; +} + +template using GenoVector4 = GenoVector<4, T>; + +using GenoVector4b = GenoVector4< int8 >; +using GenoVector4ub = GenoVector4; +using GenoVector4s = GenoVector4< int16>; +using GenoVector4us = GenoVector4; +using GenoVector4i = GenoVector4< int32>; +using GenoVector4ui = GenoVector4; +using GenoVector4l = GenoVector4< int64>; +using GenoVector4ul = GenoVector4; +using GenoVector4f = GenoVector4; +using GenoVector4d = GenoVector4; + +#define GNARLY_GENOME_VECTOR4_FORWARD +#endif // GNARLY_GENOME_VECTOR4 \ No newline at end of file diff --git a/src/geno/math/linear/GenoVectorDimensions.cpp b/src/geno/math/linear/GenoVectorDimensions.cpp new file mode 100644 index 0000000..a331559 --- /dev/null +++ b/src/geno/math/linear/GenoVectorDimensions.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "GenoVectorDimensions.h" + +namespace GenoVectorDimensions { + GenoVectorDimension<0> x; + GenoVectorDimension<1> y; + GenoVectorDimension<2> z; + GenoVectorDimension<3> w; +} \ No newline at end of file diff --git a/src/geno/math/linear/GenoVectorDimensions.h b/src/geno/math/linear/GenoVectorDimensions.h new file mode 100644 index 0000000..8275571 --- /dev/null +++ b/src/geno/math/linear/GenoVectorDimensions.h @@ -0,0 +1,41 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_VECTOR_DIMENSIONS +#define GNARLY_GENOME_VECTOR_DIMENSIONS + +#include "../../GenoInts.h" + +namespace GenoVectorDimensions { + + template + struct GenoVectorDimension { + const static uint32 dimension = N; + }; +} + +#define GNARLY_GENOME_VECTOR_DIMENSIONS_FORWARD +#endif // GNARLY_GENOME_VECTOR_DIMENSIONS \ No newline at end of file diff --git a/src/geno/shaders/GenoShader2c.cpp b/src/geno/shaders/GenoShader2c.cpp new file mode 100644 index 0000000..ca08dd8 --- /dev/null +++ b/src/geno/shaders/GenoShader2c.cpp @@ -0,0 +1,42 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../gl/GenoGL.h" + +#include "GenoShader2c.h" + +GenoShader2c::GenoShader2c() : + GenoMvpShader("src/geno/shaders/src/Shader2c/Shader2cv.gls", + "src/geno/shaders/src/Shader2c/Shader2cf.gls", + GENO_SHADER_STRING_IS_PATH) { + colorLoc = glGetUniformLocation(program, "inputColor"); +} + +void GenoShader2c::setColor(float r, float g, float b, float a) { + glUniform4f(colorLoc, r, g, b, a); +} + +GenoShader2c::~GenoShader2c() {} \ No newline at end of file diff --git a/src/geno/shaders/GenoShader2c.h b/src/geno/shaders/GenoShader2c.h new file mode 100644 index 0000000..22c9239 --- /dev/null +++ b/src/geno/shaders/GenoShader2c.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_SHADER2C +#define GNARLY_GENOME_SHADER2C + +#include "../GenoInts.h" +#include "../gl/GenoShader.h" + +class GenoShader2c : public GenoMvpShader { + private: + uint32 colorLoc; + public: + GenoShader2c(); + void setColor(float r, float g, float b, float a); + ~GenoShader2c(); +}; + +#define GNARLY_GENOME_SHADER2C_FORWARD +#endif // GNARLY_GENOME_SHADER2C \ No newline at end of file diff --git a/src/geno/shaders/GenoShader2ss.cpp b/src/geno/shaders/GenoShader2ss.cpp new file mode 100644 index 0000000..d6aa269 --- /dev/null +++ b/src/geno/shaders/GenoShader2ss.cpp @@ -0,0 +1,42 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../gl/GenoGL.h" + +#include "GenoShader2ss.h" + +GenoShader2ss::GenoShader2ss() : + GenoMvpShader("src/geno/shaders/src/Shader2ss/Shader2ssv.gls", + "src/geno/shaders/src/Shader2ss/Shader2ssf.gls", + GENO_SHADER_STRING_IS_PATH) { + textureTransformLoc = glGetUniformLocation(program, "textureTransform"); +} + +void GenoShader2ss::setTextureTransform(const GenoMatrix4f & matrix) { + glUniformMatrix4fv(textureTransformLoc, 1, GL_FALSE, matrix.m); +} + +GenoShader2ss::~GenoShader2ss() {} \ No newline at end of file diff --git a/src/geno/shaders/GenoShader2ss.h b/src/geno/shaders/GenoShader2ss.h new file mode 100644 index 0000000..9f287a4 --- /dev/null +++ b/src/geno/shaders/GenoShader2ss.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_SHADER2SS +#define GNARLY_GENOME_SHADER2SS + +#include "../GenoInts.h" +#include "../gl/GenoShader.h" + +class GenoShader2ss : public GenoMvpShader { + private: + uint32 textureTransformLoc; + public: + GenoShader2ss(); + void setTextureTransform(const GenoMatrix4f & matrix); + ~GenoShader2ss(); +}; + +#define GNARLY_GENOME_SHADER2SS_FORWARD +#endif // GNARLY_GENOME_SHADER2SS \ No newline at end of file diff --git a/src/geno/shaders/GenoShader2t.cpp b/src/geno/shaders/GenoShader2t.cpp new file mode 100644 index 0000000..5262534 --- /dev/null +++ b/src/geno/shaders/GenoShader2t.cpp @@ -0,0 +1,37 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../gl/GenoGL.h" + +#include "GenoShader2t.h" + +GenoShader2t::GenoShader2t() : + GenoMvpShader("src/geno/shaders/src/Shader2t/Shader2tv.gls", + "src/geno/shaders/src/Shader2t/Shader2tf.gls", + GENO_SHADER_STRING_IS_PATH) { +} + +GenoShader2t::~GenoShader2t() {} \ No newline at end of file diff --git a/src/geno/shaders/GenoShader2t.h b/src/geno/shaders/GenoShader2t.h new file mode 100644 index 0000000..f31e607 --- /dev/null +++ b/src/geno/shaders/GenoShader2t.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_SHADER2T +#define GNARLY_GENOME_SHADER2T + +#include "../gl/GenoShader.h" + +class GenoShader2t : public GenoMvpShader { + public: + GenoShader2t(); + ~GenoShader2t(); +}; + +#define GNARLY_GENOME_SHADER2T_FORWARD +#endif // GNARLY_GENOME_SHADER2T \ No newline at end of file diff --git a/src/geno/shaders/src/Shader2c/Shader2cf.gls b/src/geno/shaders/src/Shader2c/Shader2cf.gls new file mode 100644 index 0000000..cff410b --- /dev/null +++ b/src/geno/shaders/src/Shader2c/Shader2cf.gls @@ -0,0 +1,35 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#version 330 core + +uniform vec4 inputColor = vec4(1, 0.5, 0.9, 1); + +layout (location = 0) out vec4 color; + +void main() { + color = inputColor; +} \ No newline at end of file diff --git a/src/geno/shaders/src/Shader2c/Shader2cv.gls b/src/geno/shaders/src/Shader2c/Shader2cv.gls new file mode 100644 index 0000000..d653deb --- /dev/null +++ b/src/geno/shaders/src/Shader2c/Shader2cv.gls @@ -0,0 +1,35 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#version 330 core + +uniform mat4 mvp; + +layout (location = 0) in vec3 vertices; + +void main() { + gl_Position = mvp * vec4(vertices, 1); +} \ No newline at end of file diff --git a/src/geno/shaders/src/Shader2ss/Shader2ssf.gls b/src/geno/shaders/src/Shader2ss/Shader2ssf.gls new file mode 100644 index 0000000..658e5e6 --- /dev/null +++ b/src/geno/shaders/src/Shader2ss/Shader2ssf.gls @@ -0,0 +1,37 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#version 330 core + +uniform sampler2D tex; + +in vec2 texCoords; + +layout (location = 0) out vec4 color; + +void main() { + color = texture(tex, texCoords); +} \ No newline at end of file diff --git a/src/geno/shaders/src/Shader2ss/Shader2ssv.gls b/src/geno/shaders/src/Shader2ss/Shader2ssv.gls new file mode 100644 index 0000000..84e2689 --- /dev/null +++ b/src/geno/shaders/src/Shader2ss/Shader2ssv.gls @@ -0,0 +1,40 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#version 330 core + +uniform mat4 mvp; +uniform mat4 textureTransform = mat4(1.0); + +layout (location = 0) in vec3 vertices; +layout (location = 1) in vec2 textureCoords; + +out vec2 texCoords; + +void main() { + gl_Position = mvp * vec4(vertices, 1); + texCoords = (textureTransform * vec4(textureCoords, 0, 1)).xy; +} \ No newline at end of file diff --git a/src/geno/shaders/src/Shader2t/Shader2tf.gls b/src/geno/shaders/src/Shader2t/Shader2tf.gls new file mode 100644 index 0000000..658e5e6 --- /dev/null +++ b/src/geno/shaders/src/Shader2t/Shader2tf.gls @@ -0,0 +1,37 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#version 330 core + +uniform sampler2D tex; + +in vec2 texCoords; + +layout (location = 0) out vec4 color; + +void main() { + color = texture(tex, texCoords); +} \ No newline at end of file diff --git a/src/geno/shaders/src/Shader2t/Shader2tv.gls b/src/geno/shaders/src/Shader2t/Shader2tv.gls new file mode 100644 index 0000000..c93e60a --- /dev/null +++ b/src/geno/shaders/src/Shader2t/Shader2tv.gls @@ -0,0 +1,39 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#version 330 core + +uniform mat4 mvp; + +layout (location = 0) in vec3 vertices; +layout (location = 1) in vec2 textureCoords; + +out vec2 texCoords; + +void main() { + gl_Position = mvp * vec4(vertices, 1); + texCoords = textureCoords; +} \ No newline at end of file diff --git a/src/geno/template/GenoArrayList.h b/src/geno/template/GenoArrayList.h new file mode 100644 index 0000000..6db58da --- /dev/null +++ b/src/geno/template/GenoArrayList.h @@ -0,0 +1,168 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_ARRAY_LIST +#define GNARLY_GENOME_ARRAY_LIST + +#include +#include + +#include "../GenoInts.h" +#include "../exceptions/GenoMaxCapacityException.h" + +template +class GenoArrayList { + private: + uint32 capacity; + uint32 length; + T * array; + + void clean() noexcept { + delete [] array; + } + + void reallocate(uint32 newCapacity) { + capacity = newCapacity; + auto newArray = new T[capacity]; + for (uint32 i = 0; i < length; ++i) + newArray[i] = std::move(array[i]); + clean(); + array = newArray; + } + + void checkCapacity() { + if (length == capacity) { + if (capacity == 0xFFFFFFFF) + throw GenoMaxCapacityException(); + else if (capacity > 0x7FFFFFFF) + reallocate(0xFFFFFFFF); + else + reallocate(capacity << 1); + } + } + + public: + GenoArrayList(uint32 capacity = 16) : + capacity(capacity), + array(new T[capacity]) {} + + GenoArrayList(std::initializer_list list) : + capacity(list.size() * 2), + length(list.size()), + array(new T[capacity]) { + auto init = list.begin(); + for (uint32 i = 0; i < list.size(); ++i) + array[i] = init[i]; + } + + GenoArrayList(const GenoArrayList & list) : + capacity(list.capacity), + length(list.length), + array(new T[capacity]) { + for (uint32 i = 0; i < list.length; ++i) + array[i] = list.array[i]; + } + + GenoArrayList(GenoArrayList && list) noexcept : + capacity(list.capacity), + length(list.length), + array(list.array) { + list.array = 0; + } + + GenoArrayList & operator=(const GenoArrayList & list) { + clean(); + capacity = list.capacity; + length = list.length; + array = new T[capacity]; + for (uint32 i = 0; i < list.length; ++i) + array[i] = list.array[i]; + return *this; + } + + GenoArrayList & operator=(GenoArrayList && list) noexcept { + clean(); + capacity = list.capacity; + length = list.length; + array = list.array; + list.array = 0; + return *this; + } + + T & operator[](uint32 index) noexcept { + return array[index]; + } + + const T & operator[](uint32 index) const noexcept { + return array[index]; + } + + uint32 getLength() const noexcept { + return length; + } + + void add(const T & element) { + checkCapacity(); + array[length] = element; + ++length; + } + + void add(uint32 index, const T & element) { + checkCapacity(); + for (uint32 i = length; i > index; --i) + array[i] = std::move(array[i - 1]); + array[index] = element; + ++length; + } + + void remove(uint32 index) { + --length; + for (uint32 i = index; i < length; ++i) + array[i] = std::move(array[i + 1]); + } + + void remove(uint32 begin, uint32 end) { + auto distance = end - begin; + length -= end; + for (uint32 i = begin; i < length; ++i) + array[i] = std::move(array[i + distance]); + } + + void clear() noexcept { + length = 0; + } + + void pack() { + reallocate(length); + } + + ~GenoArrayList() { + clean(); + } +}; + +#define GNARLY_GENOME_ARRAY_LIST_FORWARD +#endif // GNARLY_GENOME_ARRAY_LIST \ No newline at end of file diff --git a/src/geno/template/GenoQueue.h b/src/geno/template/GenoQueue.h new file mode 100644 index 0000000..a78d2f2 --- /dev/null +++ b/src/geno/template/GenoQueue.h @@ -0,0 +1,150 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_QUEUE +#define GNARLY_GENOME_QUEUE + +#include +#include + +#include "../GenoInts.h" +#include "../exceptions/GenoMaxCapacityException.h" + +template +class GenoQueue { + private: + uint32 capacity; + uint32 read; + uint32 write; + uint32 length; + T * array; + + void clean() noexcept { + delete [] array; + } + + void reallocate(uint32 newCapacity) { + auto newArray = new T[newCapacity]; + for (uint32 i = 0, j = read - 1; i < length; ++i) + newArray[i] = std::move(array[(++j) %= capacity]); + clean(); + capacity = newCapacity; + read = 0; + write = length; + array = newArray; + } + + void checkCapacity() { + if (length == capacity) { + if (capacity == 0xFFFFFFFF) + throw GenoMaxCapacityException(); + else if (capacity > 0x7FFFFFFF) + reallocate(0xFFFFFFFF); + else + reallocate(capacity << 1); + } + } + + public: + GenoQueue(uint32 capacity = 16) : + capacity(capacity), + array(new T[capacity]) {} + + GenoQueue(std::initializer_list list) : + capacity(list.size() * 2), + write(list.size()), + length(list.size()), + array(new T[capacity]) { + auto init = list.begin(); + for (uint32 i = 0; i < list.size(); ++i) + array[i] = init[i]; + } + + GenoQueue(const GenoQueue & queue) : + capacity(queue.capacity), + read(queue.read), + write(queue.write), + length(queue.length), + array(new T[capacity]) { + for (uint32 i = read; i != write; (++i) %= capacity) + array[i] = queue.array[i]; + } + + GenoQueue(GenoQueue && queue) noexcept : + capacity(queue.capacity), + read(queue.read), + write(queue.write), + length(queue.length), + array(queue.array) { + queue.array = 0; + } + + GenoQueue & operator=(const GenoQueue & queue) { + clean(); + capacity = queue.capacity; + length = queue.length; + array = new T[capacity]; + for (uint32 i = read; i != write; (++i) %= capacity) + array[i] = queue.array[i]; + return *this; + } + + GenoQueue & operator=(GenoQueue && queue) noexcept { + clean(); + capacity = queue.capacity; + read = queue.read; + write = queue.write; + length = queue.length; + array = queue.array; + queue.array = 0; + return *this; + } + + void enqueue(const T & element) { + checkCapacity(); + array[write] = element; + (++write) %= capacity; + ++length; + } + + T dequeue() { + uint32 index = read; + (++read) %= capacity; + --length; + return std::move(array[index]); + } + + void pack() { + reallocate(length); + } + + ~GenoQueue() { + clean(); + } +}; + +#define GNARLY_GENOME_QUEUE_FORWARD +#endif // GNARLY_GENOME_QUEUE \ No newline at end of file diff --git a/src/geno/template/GenoStack.h b/src/geno/template/GenoStack.h new file mode 100644 index 0000000..c71aebb --- /dev/null +++ b/src/geno/template/GenoStack.h @@ -0,0 +1,131 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_STACK +#define GNARLY_GENOME_STACK + +#include +#include + +#include "../GenoInts.h" +#include "../exceptions/GenoMaxCapacityException.h" + +template +class GenoStack { + private: + uint32 capacity; + uint32 length; + T * array; + + void clean() noexcept { + delete [] array; + } + + void reallocate(uint32 newCapacity) { + capacity = newCapacity; + auto newArray = new T[capacity]; + for (uint32 i = 0; i < length; ++i) + newArray[i] = std::move(array[i]); + clean(); + array = newArray; + } + + void checkCapacity() { + if (length == capacity) { + if (capacity == 0xFFFFFFFF) + throw GenoMaxCapacityException(); + else if (capacity > 0x7FFFFFFF) + reallocate(0xFFFFFFFF); + else + reallocate(capacity << 1); + } + } + + public: + GenoStack(uint32 capacity = 16) : + capacity(capacity), + array(new T[capacity]) {} + + GenoStack(std::initializer_list list) : + capacity(list.size() * 2), + length(list.size()), + array(new T[capacity]) { + auto init = list.begin(); + for (uint32 i = 0; i < list.size(); ++i) + array[i] = init[i]; + } + + GenoStack(const GenoStack & stack) : + capacity(stack.capacity), + length(stack.length), + array(new T[capacity]) { + for (uint32 i = 0; i < stack.length; ++i) + array[i] = stack.array[i]; + } + + GenoStack(GenoStack && stack) noexcept : + capacity(stack.capacity), + length(stack.length), + array(stack.array) { + stack.array = 0; + } + + GenoStack & operator=(const GenoStack & stack) { + clean(); + capacity = stack.capacity; + length = stack.length; + array = new T[capacity]; + for (uint32 i = 0; i < stack.length; ++i) + array[i] = stack.array[i]; + return *this; + } + + GenoStack & operator=(GenoArrayList && stack) noexcept { + clean(); + capacity = stack.capacity; + length = stack.length; + array = stack.array; + stack.array = 0; + return *this; + } + + void push(const T & element) { + checkCapacity(); + array[length] = element; + ++length; + } + + T pop() { + return std::move(array[--length]); + } + + ~GenoStack() { + clean(); + } +}; + +#define GNARLY_GENOME_STACK_FORWARD +#endif // GNARLY_GENOME_STACK \ No newline at end of file diff --git a/src/geno/thread/GenoThreadPool.cpp b/src/geno/thread/GenoThreadPool.cpp new file mode 100644 index 0000000..3a37077 --- /dev/null +++ b/src/geno/thread/GenoThreadPool.cpp @@ -0,0 +1,104 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include "GenoThreadPool.h" + +void GenoThreadPool::threadLoop(uint32 threadId, GenoThreadPool * pool) { + while (pool->isActive.load()) { + GenoThreadPoolJobPackage * job = pool->requestJob(threadId); + if (job != 0) { + job->job(job->data); + pool->activeThreads[threadId].store(false); + } + else + std::this_thread::sleep_for(std::chrono::duration(1)); + } +} + +GenoThreadPool::GenoThreadPoolJobPackage * GenoThreadPool::requestJob(uint32 threadId) { + std::lock_guard lock(jobMutex); + if (jobCount > 0) { + activeThreads[threadId].store(true); + --jobCount; + return &jobs[jobCount]; + } + else + return 0; +} + +uint32 GenoThreadPool::physicalThreadCount() { + return std::thread::hardware_concurrency(); +} + +GenoThreadPool::GenoThreadPool(uint32 numThreads, uint32 initialQueueCapacity) : + isActive(true), + numThreads(numThreads), + threads(new std::thread[numThreads]), + activeThreads(new std::atomic_bool[numThreads]), + jobCount(0), + jobCapacity(initialQueueCapacity == 0 ? 16 : initialQueueCapacity), + jobs(new GenoThreadPoolJobPackage[jobCapacity]) { + for (uint32 i = 0; i < numThreads; ++i) { + threads[i] = std::thread(threadLoop, i, this); + activeThreads[i].store(false); + } +} + +void GenoThreadPool::submitJob(GenoThreadPoolJob job, GenoThreadPoolJobData data) { + std::lock_guard lock(jobMutex); + if (jobCount >= jobCapacity) { + jobCapacity *= 2; + GenoThreadPoolJobPackage * newJobs = new GenoThreadPoolJobPackage[jobCapacity]; + memcpy(newJobs, jobs, sizeof(GenoThreadPoolJobPackage) * jobCount); + delete [] jobs; + jobs = newJobs; + } + jobs[jobCount] = { job, data }; + ++jobCount; +} + +void GenoThreadPool::wait() { + while (jobCount > 0) + std::this_thread::sleep_for(std::chrono::duration(1)); + for (uint32 i = 0; i < numThreads; ++i) { + if (activeThreads[i].load()) { + std::this_thread::sleep_for(std::chrono::duration(1)); + i = 0; + } + } +} + +GenoThreadPool::~GenoThreadPool() { + isActive.store(false); + for (uint32 i = 0; i < numThreads; ++i) + threads[i].join(); + delete [] threads; + delete [] activeThreads; + delete [] jobs; +} \ No newline at end of file diff --git a/src/geno/thread/GenoThreadPool.h b/src/geno/thread/GenoThreadPool.h new file mode 100644 index 0000000..2f47c00 --- /dev/null +++ b/src/geno/thread/GenoThreadPool.h @@ -0,0 +1,98 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_THREAD_POOL +#define GNARLY_GENOME_THREAD_POOL + +#include +#include +#include + +#include "../GenoInts.h" + +typedef void * GenoThreadPoolJobData; +typedef void (*GenoThreadPoolJob)(GenoThreadPoolJobData data); + +/** + * A thread pool +**/ +class GenoThreadPool { + private: + struct GenoThreadPoolJobPackage { + GenoThreadPoolJob job; + GenoThreadPoolJobData data; + }; + + std::atomic_bool isActive; + uint32 numThreads; + std::mutex jobMutex; + std::thread * threads; + std::atomic_bool * activeThreads; + + uint32 jobCount; + uint32 jobCapacity; + GenoThreadPoolJobPackage * jobs; + + static void threadLoop(uint32 threadId, GenoThreadPool * pool); + + GenoThreadPoolJobPackage * requestJob(uint32 threadId); + public: + /** + * Returns the number of physical threads the system has if possible + **/ + static uint32 physicalThreadCount(); + + /** + * Creates a thread pool + * + * @param numThreads - The number of threads in the pool, defaults to physicalThreadCount() + * @param initialQueueCapacity - The initial capacity of the job queue. Queue will grow to fit but resizing is expensive + **/ + GenoThreadPool(uint32 numThreads = physicalThreadCount(), uint32 initialQueueCapacity = 16); + + /** + * Submits a job to the thread pool + * + * @param job - The job to be queued + * @param data - The data for the queued job + **/ + void submitJob(GenoThreadPoolJob job, GenoThreadPoolJobData data = 0); + + /** + * Waits until all submitted jobs have finished + **/ + void wait(); + + /** + * Destroys the thread pool + * + * Waits until all jobs have been completed before exiting + **/ + ~GenoThreadPool(); +}; + +#define GNARLY_GENOME_THREAD_POOL_FORWARD +#endif // GNARLY_GENOME_THREAD_POOL \ No newline at end of file diff --git a/src/geno/thread/GenoTime.cpp b/src/geno/thread/GenoTime.cpp new file mode 100644 index 0000000..40916d1 --- /dev/null +++ b/src/geno/thread/GenoTime.cpp @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include + +#include "GenoTime.h" + +double GenoTime::getTime(GenoTimeScale scale) { + return glfwGetTime() * scale; +} + +void GenoTime::sleep(double time, GenoTimeScale scale) { + std::this_thread::sleep_for(std::chrono::duration(time * milliseconds / scale)); +} + +void GenoTime::sleepUntil(double time, GenoTimeScale scale) { + std::this_thread::sleep_for(std::chrono::duration((time - getTime(scale)) * milliseconds / scale)); +} \ No newline at end of file diff --git a/src/geno/thread/GenoTime.h b/src/geno/thread/GenoTime.h new file mode 100644 index 0000000..026a37f --- /dev/null +++ b/src/geno/thread/GenoTime.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * + * Copyright (c) 2018 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#ifndef GNARLY_GENOME_TIME +#define GNARLY_GENOME_TIME + +#include "../GenoInts.h" + +enum GenoTimeScale : uint32 { seconds = 1, milliseconds = 1000, microseconds = 1000000, nanoseconds = 1000000000 }; + +class GenoTime final { + public: + + /** + * Returns the time since the initialization of the engine + * + * @param scale - The time scale in which to return the time + **/ + static double getTime(GenoTimeScale scale = milliseconds); + + /** + * Sleeps the current thread for the specified amount of time + * + * @param scale - The time scale of the time provided + **/ + static void sleep(double time, GenoTimeScale scale = milliseconds); + + /** + * Sleeps the current thread until the specified time + * + * @param scale - The time scale of the time provided + **/ + static void sleepUntil(double time, GenoTimeScale scale = milliseconds); +}; + +#define GNARLY_GENOME_TIME_FORWARD +#endif // YOUR_DEFINE_HERE \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e745bf5 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,156 @@ +/******************************************************************************* + * + * Copyright (c) 2019 Gnarly Narwhal + * + * ----------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files(the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include "geno/GenoInts.h" +#include "geno/GenoMacros.h" + +#include "geno/thread/GenoTime.h" +#include "geno/engine/GenoEngine.h" +#include "geno/engine/GenoLoop.h" +#include "geno/engine/GenoInput.h" +#include "geno/engine/GenoWindow.h" +#include "geno/engine/GenoCamera2D.h" +#include "geno/gl/GenoFramebuffer.h" + +bool init(); +void begin(); +void loop(); +void update(); +void render(); +void cleanup(); + +GenoWindow * window; +GenoCamera2D * camera; + +int32 main(int32 argc, char ** argv) { + + init(); + begin(); + cleanup(); + + /////// TIME TRIALS - LEAVE FOR FUTURE USE /////// +/* + const uint32 NUM_ITERATIONS = 1000000; + + auto begin1 = std::chrono::high_resolution_clock::now(); + auto end1 = std::chrono::high_resolution_clock::now(); + + auto begin2 = std::chrono::high_resolution_clock::now(); + auto end2 = std::chrono::high_resolution_clock::now(); + + std::cout << std::chrono::duration_cast(end1 - begin1).count() << std::endl; + std::cout << std::chrono::duration_cast(end2 - begin2).count() << std::endl; +*/ + //////// DO NOT REMOVE BELOW //////// + + #ifdef _DEBUG + + std::cout << "Press enter to continue . . ." << std::endl; + std::cin.get(); + + #endif // _DEBUG + + return 0; +} + +bool init() { + GenoEngine::init(); + + GenoLoopCreateInfo loopInfo = {}; + loopInfo.targetFps = GenoMonitors::getPrimaryMonitor()->getDefaultVideoMode()->getRefreshRate(); + loopInfo.deltaScale = 1; + loopInfo.callback = loop; + loopInfo.numSubLoops = 0; + loopInfo.subLoops = 0; + + GenoEngine::setLoop(loopInfo); + + int32 winHints[] = { + GLFW_CONTEXT_VERSION_MAJOR, 3, + GLFW_CONTEXT_VERSION_MINOR, 3, + GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE, + GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE + }; + + GenoWindowCreateInfo winInfo = {}; + winInfo.defaultPosition = true; + winInfo.fullscreen = true; + winInfo.title = "Genome"; + winInfo.numHints = GENO_ARRAY_SIZE(winHints) / 2; + winInfo.hints = winHints; + winInfo.depth = true; + winInfo.clearRed = 0; + winInfo.clearGreen = 0; + winInfo.clearBlue = 0; + + window = GenoWindow::create(winInfo); + if (window == 0) { + std::cerr << "Window creation failed!" << std::endl; + GenoEngine::stopLoop(); + return false; + } + window->activate(); + + GenoEngine::setSwapInterval(1); + GenoEngine::initGlew(); + + camera = new GenoCamera2D(0, 1, 1, 0, 0, 1); + + GenoFramebuffer::bindDefault(); + + return true; +} + +void begin() { + GenoEngine::startLoop(); +} + +void loop() { + update(); + render(); +} + +void update() { + if (window->shouldClose()) + GenoEngine::stopLoop(); + + camera->update(); +} + +void render() { + GenoFramebuffer::clear(); + window->swap(); +} + +void cleanup() { + delete camera; + delete window; + + GenoEngine::destroy(); +}