[
  {
    "path": ".travis.yml",
    "content": "language: cpp\n\nos:\n  - linux\n  - osx\n\ncompiler:\n  - gcc\n  - clang\n\nbefore_install:\n    # GCC update for linux, to ensure C++11 support.\n  - if [ $TRAVIS_OS_NAME == linux ]; then\n        sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test;\n        sudo apt-get update -qq;\n    fi\n\n    # GLFW install on linux:\n  - if [ $TRAVIS_OS_NAME == linux ]; then\n        sudo add-apt-repository -y ppa:pyglfw/pyglfw;\n        sudo apt-get update -qq;\n        sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev;\n    fi\n\n    # GLFW install on MacOS: (make sure brew can install GLFW in usr/local)\n  - if [ $TRAVIS_OS_NAME == osx ]; then\n        sudo chown -R $(whoami) /usr/local;\n        brew update;\n        brew install glfw3;\n    fi\n\ninstall:\n    # Finish the GCC install for linux:\n  - if [ $TRAVIS_OS_NAME == linux ]; then\n        sudo apt-get install -qq g++-5;\n        export CXX=\"g++-5\";\n        export CC=\"gcc-5\";\n    fi\n\nscript:\n  - $CXX --version\n  - make -C samples\n\n"
  },
  {
    "path": "README.md",
    "content": "\n# Debug Draw\n\n[![Build Status](https://travis-ci.org/glampert/debug-draw.svg)](https://travis-ci.org/glampert/debug-draw)\n\nAn immediate-mode, renderer agnostic, lightweight debug drawing API for C++.\n\n![Debug Draw](https://raw.githubusercontent.com/glampert/debug-draw/master/samples/images/shapes.png \"Debug Draw sample\")\n\n## License\n\nThis software is in the public domain. Where that dedication is not recognized,\nyou are granted a perpetual, irrevocable license to copy, distribute, and modify\nthe source code as you see fit.\n\nThe source code is provided \"as is\", without warranty of any kind, express or implied.\nNo attribution is required, but a mention about the author(s) is appreciated.\n\n## Using Debug Draw\n\nDebug Draw is a single source file library, so the \"header\" forward declarations and\nthe implementation are contained in the same file (`debug_draw.hpp`). This should facilitate\ndeployment and integration with your own projects. All you have to do is `#include` the library\nfile in one of your own source files and define `DEBUG_DRAW_IMPLEMENTATION` in that\nfile to generate the implementation. You can also still include the library in other\nplaces. When `DEBUG_DRAW_IMPLEMENTATION` is not defined, it acts as a normal C++ header file.\nExample:\n\nIn `my_program.cpp`:\n\n```cpp\n#define DEBUG_DRAW_IMPLEMENTATION\n#include \"debug_draw.hpp\"\n```\n\nNow in `my_program.hpp` or any other header or source file,\nyou can include it as a normal C++ header:\n\n```cpp\n#include \"debug_draw.hpp\"\n```\n\nThat's it, you should now be able to build Debug Draw into your own application.\n\n### Interfacing with your renderer\n\nDebug Draw doesn't make assumptions about the underlaying renderer API, so it can be\nintegrated very easily with Direct3D or OpenGL or any other rendering engine of\nyour choice. All that is required is that you provide an implementation for the\n`dd::RenderInterface` abstract class, which provides Debug Draw with basic methods\nto draw points, lines and character glyphs. The following is what `dd::RenderInterface` looks like:\n\n```cpp\nclass RenderInterface\n{\npublic:\n    virtual void beginDraw();\n    virtual void endDraw();\n\n    virtual GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels);\n    virtual void destroyGlyphTexture(GlyphTextureHandle glyphTex);\n\n    virtual void drawPointList(const DrawVertex * points, int count, bool depthEnabled);\n    virtual void drawLineList(const DrawVertex * lines, int count, bool depthEnabled);\n    virtual void drawGlyphList(const DrawVertex * glyphs, int count, GlyphTextureHandle glyphTex);\n\n    virtual ~RenderInterface() = 0;\n};\n```\n\nNot all methods have to be implemented, you decide which features to support!\nLook into the source code for the declaration of `RenderInterface`. Each method is\nwell commented and describes the expected behavior that you should implement.\nFor reference implementations of the `RenderInterface` using standard APIs like OpenGL,\nrefer to the `samples/` directory in this project.\n\nOnce you implement a `RenderInterface` for your renderer, all you need to do before starting\nto use Debug Draw is to call `dd::initialize()` passing it a pointer to your custom `RenderInterface`:\n\n```cpp\nMyRenderInterface renderIface;\ndd::initialize(&renderIface);\n```\n\nNote however that Debug Draw batches all primitives to reduce the number of calls to `RenderInterface`,\nso drawing will only actually take place by the time you call `dd::flush()`, which is normally done\nat the end of a frame, before flipping the screen buffers:\n\n```cpp\n// You only have to pass the current time if you have timed debug\n// draws in the queues. Otherwise just omit the argument or pass 0.\ndd::flush(getTimeMilliseconds());\n```\n\nSo the overall setup should look something like the following:\n\n```cpp\nclass MyRenderInterface : public dd::RenderInterface\n{\n    // Cherrypick the methods you want to implement or implement them all\n    ...\n};\n\nint main()\n{\n    MyRenderInterface renderIface;\n    dd::initialize(&renderIface);\n\n    while (!quitting)\n    {\n        // Any other drawing that you already do\n        ...\n\n        // Call any dd:: functions to add debug primitives to the draw queues\n        ...\n\n        dd::flush(getTimeMilliseconds());\n\n        // Swap buffers to present the scene\n        ...\n    }\n\n    dd::shutdown();\n}\n```\n\n### Configuration switches\n\nDebug Draw provides several compiler switches for library configuration and customization.\nCheck the documentation in `debug_draw.hpp` for a list of all switches plus detailed description of each.\n\n### Language/compiler requirements\n\nThe library has very few language requirements. One of its main goals is to be painless to integrate\nand portable. The only requirement is a fairly recent C++ compiler with minimal Standard Library support.\nSome C++11 features are assumed, such as `nullptr` and `<cstdint>`. The samples included make heavier use\nof the C++ Standard Library to demonstrate Debug Draw usage with threads.\n\nRTTI and C++ Exceptions **are not used**, so you should have no problems integrating\nthe library with projects that disable those features.\n\nThe memory footprint is also small and you can manage the amount of memory that gets committed\nto the internal queues via preprocessor directives. We currently only allocate a small amount of\ndynamic memory at library startup to decompress the font glyphs for the debug text drawing functions\nand for the draw queues and library context data.\n\n### Thread safety and explicit contexts\n\nBy default, Debug Draw will use a static global context internally, providing a procedural-style API that\n*is not thread safe*. This is the \"classic\" Debug Draw mode that is the easiest to use and set up, but\nthe library also supports two other modes that are thread safe and configurable at compile time:\n\n- `DEBUG_DRAW_PER_THREAD_CONTEXT`: If this is defined before the implementation, the library will use\n  a thread-local context instead of the global shared default. This allows calling the library from\n  different threads since each will keep its private context and draw queues. This mode provides\n  the same public library interface but requires TLS (Thread Local Storage) support from the compiler.\n\n- `DEBUG_DRAW_EXPLICIT_CONTEXT`: If this is defined before the implementation, the library expects the\n  user to supply a handle to a context. This mode exposes the `dd::ContextHandle` type and changes each\n  function in the library to take this handle as the first argument. This mode makes the library fully\n  stateless, so that each rendering thread that calls into the library can create and maintain its own\n  instance of Debug Draw.\n\nThe explicit context mode is a cleaner and more functional-style API and should be the preferred one for new users.\nThe procedural mode is still kept as the default for compatibility with older library versions, but it is\nrecommended that you use the explicit context mode by adding `#define DEBUG_DRAW_EXPLICIT_CONTEXT` together\nwith `DEBUG_DRAW_IMPLEMENTATION`. In the future, the procedural stateful API will be deprecated in favor of the explicit one.\n\n## Samples\n\nDrawing a box with a set of coordinate axes in its center:\n\n```cpp\nconst ddVec3 boxColor  = { 0.0f, 0.8f, 0.8f };\nconst ddVec3 boxCenter = { 0.0f, 0.0f, 3.0f };\n\ndd::box(boxCenter, boxColor, 1.5f, 1.5f, 1.5f);\ndd::cross(boxCenter, 1.0f);\n```\n\n![box](https://raw.githubusercontent.com/glampert/debug-draw/master/samples/images/box.png \"Box with coordinate axes\")\n\nTo visualize a matrix transform, you can use `dd::axisTriad()`\nto draw the transform as three arrows:\n\n```cpp\nconst ddMat4x4 transform = { // The identity matrix\n    1.0f, 0.0f, 0.0f, 0.0f,\n    0.0f, 1.0f, 0.0f, 0.0f,\n    0.0f, 0.0f, 1.0f, 0.0f,\n    0.0f, 0.0f, 0.0f, 1.0f\n};\ndd::axisTriad(transform, 0.3f, 2.0f);\n```\n\n![arrows](https://raw.githubusercontent.com/glampert/debug-draw/master/samples/images/arrows.png \"Axis triad repesenting a 3D transform\")\n\nMore complex samples and examples on how to integrate Debug Draw with your own renderer can\nbe found inside the `samples/` directory. Each function provided in the public API is also well\ndocumented in the header file. You will find a descriptive header comment before\nthe prototype of each public function exported by the library.\n\n"
  },
  {
    "path": "debug_draw.hpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   debug_draw.hpp\n// Author: Guilherme R. Lampert\n// Brief:  Debug Draw - an immediate-mode, renderer agnostic, lightweight debug drawing API.\n// ================================================================================================\n\n#ifndef DEBUG_DRAW_HPP\n#define DEBUG_DRAW_HPP\n\n// ========================================================\n// Library Overview:\n// ========================================================\n//\n// ---------\n//  LICENSE\n// ---------\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n//\n// The source code is provided \"as is\", without warranty of any kind, express or implied.\n// No attribution is required, but a mention about the author(s) is appreciated.\n//\n// -------------\n//  QUICK SETUP\n// -------------\n// In *one* C++ source file, *before* including this file, do this:\n//\n//   #define DEBUG_DRAW_IMPLEMENTATION\n//\n// To enable the implementation. Further includes of this\n// file *should not* redefine DEBUG_DRAW_IMPLEMENTATION.\n// Example:\n//\n// In my_program.cpp:\n//\n//   #define DEBUG_DRAW_IMPLEMENTATION\n//   #include \"debug_draw.hpp\"\n//\n// In my_program.hpp:\n//\n//   #include \"debug_draw.hpp\"\n//\n// ----------------------\n//  COMPILATION SWITCHES\n// ----------------------\n//\n// DEBUG_DRAW_CXX11_SUPPORTED\n//  Enables the use of some C++11 features. If your compiler supports C++11\n//  or better, you should define this switch globally or before every inclusion\n//  of this file. If it is not defined, we try to guess it from the value of the\n//  '__cplusplus' built-in macro constant.\n//\n// DEBUG_DRAW_MAX_*\n//  Sizes of internal intermediate buffers, which are allocated on initialization\n//  by the implementation. If you need to draw more primitives than the sizes of\n//  these buffers, you need to redefine the macros and recompile.\n//\n// DEBUG_DRAW_VERTEX_BUFFER_SIZE\n//  Size in dd::DrawVertex elements of the intermediate vertex buffer used\n//  to batch primitives before sending them to dd::RenderInterface. A bigger\n//  buffer will reduce the number of calls to dd::RenderInterface when drawing\n//  large sets of debug primitives.\n//\n// DEBUG_DRAW_OVERFLOWED(message)\n//  An error handler called if any of the DEBUG_DRAW_MAX_* sizes overflow.\n//  By default it just prints a message to stderr.\n//\n// DEBUG_DRAW_USE_STD_MATH\n//  If defined to nonzero, uses cmath/math.h. If you redefine it to zero before\n//  the library implementation, it will force the use of local replacements\n//  for the Standard Library. This might be useful if you want to avoid the\n//  dependency. It is defined to zero by default (i.e. we use cmath by default).\n//\n// DEBUG_DRAW_*_TYPE_DEFINED\n//  The compound types used by Debug Draw can also be customized.\n//  By default, ddVec3 and ddMat4x4 are plain C-arrays, but you can\n//  redefine them to use your own classes or structures (see below).\n//  ddStr is by default a std::string, but you can redefine it to\n//  a custom string type if necessary. The only requirements are that\n//  it provides a 'c_str()' method returning a null terminated\n//  const char* string and an assignment operator (=).\n//\n// DEBUG_DRAW_STR_DEALLOC_FUNC(str)\n//  If you define a custom string type for ddStr and it requires some\n//  extra cleanup besides the class destructor, you might define this\n//  function macro to perform said cleanup. It is called by dd::clear()\n//  and dd::shutdown() on every instance of the internal DebugString buffer.\n//\n// DEBUG_DRAW_NO_DEFAULT_COLORS\n//  If defined, doesn't add the set of predefined color constants inside\n//  dd::colors:: namespace. Each color is a ddVec3, so you can define this\n//  to prevent adding more global data to the binary if you don't need them.\n//\n// DEBUG_DRAW_PER_THREAD_CONTEXT\n//  If defined, a per-thread global context will be created for Debug Draw.\n//  This allows having an instance of the library for each thread in\n//  your application. You must then call initialize/shutdown/flush/etc\n//  for each thread that wishes to use the library. If this is not\n//  defined it defaults to a single threaded global context.\n//\n// DEBUG_DRAW_EXPLICIT_CONTEXT\n//  If defined, each Debug Draw function will expect and additional argument\n//  (the first one) which is the library context instance. This is an alternative\n//  to DEBUG_DRAW_PER_THREAD_CONTEXT to allow having multiple instances of the\n//  library in the same application. This flag is mutually exclusive with\n//  DEBUG_DRAW_PER_THREAD_CONTEXT.\n//\n// -------------------\n//  MEMORY ALLOCATION\n// -------------------\n// Debug Draw will only perform a couple of memory allocations during startup to decompress\n// the built-in glyph bitmap used for debug text rendering and to allocate the vertex buffers\n// and intermediate draw/batch buffers and context data used internally.\n//\n// Memory allocation and deallocation for Debug Draw will be done via:\n//\n//   DD_MALLOC(size)\n//   DD_MFREE(ptr)\n//\n// These two macros can be redefined if you'd like to supply you own memory allocator.\n// By default, they are defined to use std::malloc and std::free, respectively.\n// Note: If you redefine one, you must also provide the other.\n//\n// --------------------------------\n//  INTERFACING WITH YOUR RENDERER\n// --------------------------------\n// Debug Draw doesn't touch on any renderer-specific aspects or APIs, instead you provide\n// the library with all of it's rendering needs via the dd::RenderInterface abstract class.\n//\n// See the declaration of dd::RenderInterface for details. Not all methods are\n// required. In fact, you could also implement a full no-op RenderInterface that\n// disables debug drawing by simply inheriting from dd::RenderInterface and not overriding\n// any of the methods (or even easier, call dd::initialize(nullptr) to make everything a no-op).\n//\n// For examples on how to implement your own dd::RenderInterface, see the accompanying samples.\n// You can also find them in the source code repository for this project:\n// https://github.com/glampert/debug-draw\n//\n// ------------------\n//  CONVENTIONS USED\n// ------------------\n// Points and lines are always specified in world-space positions. This also\n// applies to shapes drawn from lines, like boxes, spheres, cones, etc.\n//\n// 2D screen-text is in screen-space pixels (from 0,0 in the upper-left\n// corner of the screen to screen_width-1 and screen_height-1).\n// RenderInterface::drawGlyphList() also receives vertexes in screen-space.\n//\n// We make some usage of matrices for things like the projected text labels.\n// Matrix layout used is column-major and vectors multiply as columns.\n// This is the convention normally used by standard OpenGL.\n//\n// C++ Exceptions are not used. Little error checking is provided or\n// done inside the library. We favor simpler, faster and easier to maintain\n// code over more sophisticated error handling. The rationale is that a\n// debug drawing API doesn't have to be very robust, since it won't make\n// into the final release executable in most cases.\n//\n\n// ========================================================\n// Configurable compilation switches:\n// ========================================================\n\n//\n// If the user didn't specify if C++11 or above are supported, try to guess\n// from the value of '__cplusplus'. It should be 199711L for pre-C++11 compilers\n// and 201103L in those supporting C++11, but this is not a guarantee that all\n// C++11 features will be available and stable, so again, we are making a guess.\n// It is recommended to instead supply the DEBUG_DRAW_CXX11_SUPPORTED switch\n// yourself before including this file.\n//\n#ifndef DEBUG_DRAW_CXX11_SUPPORTED\n    #if (__cplusplus > 199711L)\n        #define DEBUG_DRAW_CXX11_SUPPORTED 1\n    #endif // __cplusplus\n#endif // DEBUG_DRAW_CXX11_SUPPORTED\n\n//\n// Max elements of each type at any given time.\n// We supply these reasonable defaults, but you can provide your\n// own tunned values to save memory or fit all of your debug data.\n// These are hard constraints. If not enough, change and recompile.\n//\n#ifndef DEBUG_DRAW_MAX_STRINGS\n    #define DEBUG_DRAW_MAX_STRINGS 512\n#endif // DEBUG_DRAW_MAX_STRINGS\n\n#ifndef DEBUG_DRAW_MAX_POINTS\n    #define DEBUG_DRAW_MAX_POINTS 8192\n#endif // DEBUG_DRAW_MAX_POINTS\n\n#ifndef DEBUG_DRAW_MAX_LINES\n    #define DEBUG_DRAW_MAX_LINES 32768\n#endif // DEBUG_DRAW_MAX_LINES\n\n//\n// Size in vertexes of a local buffer we use to sort elements\n// drawn with and without depth testing before submitting them to\n// the dd::RenderInterface. A larger buffer will require less flushes\n// (e.g. dd::RenderInterface calls) when drawing large amounts of\n// primitives. Less will obviously save more memory. Each DrawVertex\n// is about 32 bytes in size, we keep a context-specific array\n// with this many entries.\n//\n#ifndef DEBUG_DRAW_VERTEX_BUFFER_SIZE\n    #define DEBUG_DRAW_VERTEX_BUFFER_SIZE 4096\n#endif // DEBUG_DRAW_VERTEX_BUFFER_SIZE\n\n//\n// This macro is called with an error message if any of the above\n// sizes is overflowed during runtime. In a debug build, you might\n// keep this enabled to be able to log and find out if more space\n// is needed for the debug data arrays. Default output is stderr.\n//\n#ifndef DEBUG_DRAW_OVERFLOWED\n    #include <cstdio>\n    #define DEBUG_DRAW_OVERFLOWED(message) std::fprintf(stderr, \"%s\\n\", message)\n#endif // DEBUG_DRAW_OVERFLOWED\n\n//\n// Use <math.h> and <float.h> for trigonometry functions by default.\n// If you wish to avoid those dependencies, DD provides local approximations\n// of the required functions as a portable replacement. Just define\n// DEBUG_DRAW_USE_STD_MATH to zero before including this file.\n//\n#ifndef DEBUG_DRAW_USE_STD_MATH\n    #define DEBUG_DRAW_USE_STD_MATH 1\n#endif // DEBUG_DRAW_USE_STD_MATH\n\n// ========================================================\n// Overridable Debug Draw types:\n// ========================================================\n\n#include <cstddef>\n#include <cstdint>\n\n//\n// Following typedefs are not members of the dd:: namespace to allow easy redefinition by the user.\n// If you provide a custom implementation for them before including this file, be sure to\n// also define the proper DEBUG_DRAW_*_TYPE_DEFINED switch to disable the default typedefs.\n//\n// The only requirement placed on the vector/matrix types is that they provide\n// an array subscript operator [] and have the expected number of elements. Apart\n// from that, they could be structs, classes, what-have-you. POD types are recommended\n// but not mandatory.\n//\n\n#ifndef DEBUG_DRAW_VEC3_TYPE_DEFINED\n    // ddVec3:\n    //  A small array of floats with at least three elements, but\n    //  it could have more for alignment purposes, extra slots are ignored.\n    //  A custom ddVec3 type must provide the array subscript operator.\n    typedef float ddVec3[3];\n\n    // ddVec3_In/ddVec3_Out:\n    //  Since our default ddVec3 is a plain C-array, it decays to a pointer\n    //  when passed as an input parameter to a function, so we can use it directly.\n    //  If you change it to some structured type, it might be more efficient\n    //  passing by const reference instead, however, some platforms have optimized\n    //  hardware registers for vec3s/vec4s, so passing by value might also be efficient.\n    typedef const ddVec3 ddVec3_In;\n    typedef       ddVec3 ddVec3_Out;\n\n    #define DEBUG_DRAW_VEC3_TYPE_DEFINED 1\n#endif // DEBUG_DRAW_VEC3_TYPE_DEFINED\n\n#ifndef DEBUG_DRAW_MAT4X4_TYPE_DEFINED\n    // ddMat4x4:\n    //  Homogeneous matrix of 16 floats, representing rotations as well as\n    //  translation/scaling and projections. The internal matrix layout used by this\n    //  library is COLUMN-MAJOR, vectors multiplying as columns (usual OpenGL convention).\n    //  Column-major matrix layout:\n    //          c.0   c.1   c.2    c.3\n    //    r.0 | 0.x   4.x   8.x    12.x |\n    //    r.1 | 1.y   5.y   9.y    13.y |\n    //    r.2 | 2.z   6.z   10.z   14.z |\n    //    r.3 | 3.w   7.w   11.w   15.w |\n    //  If your custom matrix type uses row-major format internally, you'll\n    //  have to transpose them before passing your matrices to the DD functions.\n    //  We use the array subscript operator internally, so it must also be provided.\n    typedef float ddMat4x4[4 * 4];\n\n    // ddMat4x4_In/ddMat4x4_Out:\n    //  Since our default ddMat4x4 is a plain C-array, it decays to a pointer\n    //  when passed as an input parameter to a function, so we can use it directly.\n    //  If you change it to some structured type, it might be more efficient\n    //  passing by const reference instead.\n    typedef const ddMat4x4 ddMat4x4_In;\n    typedef       ddMat4x4 ddMat4x4_Out;\n\n    #define DEBUG_DRAW_MAT4X4_TYPE_DEFINED 1\n#endif // DEBUG_DRAW_MAT4X4_TYPE_DEFINED\n\n#ifndef DEBUG_DRAW_STRING_TYPE_DEFINED\n    // ddStr:\n    //  String type used internally to store the debug text strings.\n    //  A custom string type must provide at least an assignment\n    //  operator (=) and a 'c_str()' method that returns a\n    //  null-terminated const char* string pointer. That's it.\n    //  An array subscript operator [] is not required for ddStr.\n    #include <string>\n    typedef std::string   ddStr;\n    typedef const ddStr & ddStr_In;\n    typedef       ddStr & ddStr_Out;\n\n    #define DEBUG_DRAW_STRING_TYPE_DEFINED 1\n#endif // DEBUG_DRAW_STRING_TYPE_DEFINED\n\nnamespace dd\n{\n\n// ========================================================\n// Optional built-in colors in RGB float format:\n// ========================================================\n\n#ifndef DEBUG_DRAW_NO_DEFAULT_COLORS\nnamespace colors\n{\nextern const ddVec3 AliceBlue;\nextern const ddVec3 AntiqueWhite;\nextern const ddVec3 Aquamarine;\nextern const ddVec3 Azure;\nextern const ddVec3 Beige;\nextern const ddVec3 Bisque;\nextern const ddVec3 Black;\nextern const ddVec3 BlanchedAlmond;\nextern const ddVec3 Blue;\nextern const ddVec3 BlueViolet;\nextern const ddVec3 Brown;\nextern const ddVec3 BurlyWood;\nextern const ddVec3 CadetBlue;\nextern const ddVec3 Chartreuse;\nextern const ddVec3 Chocolate;\nextern const ddVec3 Coral;\nextern const ddVec3 CornflowerBlue;\nextern const ddVec3 Cornsilk;\nextern const ddVec3 Crimson;\nextern const ddVec3 Cyan;\nextern const ddVec3 DarkBlue;\nextern const ddVec3 DarkCyan;\nextern const ddVec3 DarkGoldenRod;\nextern const ddVec3 DarkGray;\nextern const ddVec3 DarkGreen;\nextern const ddVec3 DarkKhaki;\nextern const ddVec3 DarkMagenta;\nextern const ddVec3 DarkOliveGreen;\nextern const ddVec3 DarkOrange;\nextern const ddVec3 DarkOrchid;\nextern const ddVec3 DarkRed;\nextern const ddVec3 DarkSalmon;\nextern const ddVec3 DarkSeaGreen;\nextern const ddVec3 DarkSlateBlue;\nextern const ddVec3 DarkSlateGray;\nextern const ddVec3 DarkTurquoise;\nextern const ddVec3 DarkViolet;\nextern const ddVec3 DeepPink;\nextern const ddVec3 DeepSkyBlue;\nextern const ddVec3 DimGray;\nextern const ddVec3 DodgerBlue;\nextern const ddVec3 FireBrick;\nextern const ddVec3 FloralWhite;\nextern const ddVec3 ForestGreen;\nextern const ddVec3 Gainsboro;\nextern const ddVec3 GhostWhite;\nextern const ddVec3 Gold;\nextern const ddVec3 GoldenRod;\nextern const ddVec3 Gray;\nextern const ddVec3 Green;\nextern const ddVec3 GreenYellow;\nextern const ddVec3 HoneyDew;\nextern const ddVec3 HotPink;\nextern const ddVec3 IndianRed;\nextern const ddVec3 Indigo;\nextern const ddVec3 Ivory;\nextern const ddVec3 Khaki;\nextern const ddVec3 Lavender;\nextern const ddVec3 LavenderBlush;\nextern const ddVec3 LawnGreen;\nextern const ddVec3 LemonChiffon;\nextern const ddVec3 LightBlue;\nextern const ddVec3 LightCoral;\nextern const ddVec3 LightCyan;\nextern const ddVec3 LightGoldenYellow;\nextern const ddVec3 LightGray;\nextern const ddVec3 LightGreen;\nextern const ddVec3 LightPink;\nextern const ddVec3 LightSalmon;\nextern const ddVec3 LightSeaGreen;\nextern const ddVec3 LightSkyBlue;\nextern const ddVec3 LightSlateGray;\nextern const ddVec3 LightSteelBlue;\nextern const ddVec3 LightYellow;\nextern const ddVec3 Lime;\nextern const ddVec3 LimeGreen;\nextern const ddVec3 Linen;\nextern const ddVec3 Magenta;\nextern const ddVec3 Maroon;\nextern const ddVec3 MediumAquaMarine;\nextern const ddVec3 MediumBlue;\nextern const ddVec3 MediumOrchid;\nextern const ddVec3 MediumPurple;\nextern const ddVec3 MediumSeaGreen;\nextern const ddVec3 MediumSlateBlue;\nextern const ddVec3 MediumSpringGreen;\nextern const ddVec3 MediumTurquoise;\nextern const ddVec3 MediumVioletRed;\nextern const ddVec3 MidnightBlue;\nextern const ddVec3 MintCream;\nextern const ddVec3 MistyRose;\nextern const ddVec3 Moccasin;\nextern const ddVec3 NavajoWhite;\nextern const ddVec3 Navy;\nextern const ddVec3 OldLace;\nextern const ddVec3 Olive;\nextern const ddVec3 OliveDrab;\nextern const ddVec3 Orange;\nextern const ddVec3 OrangeRed;\nextern const ddVec3 Orchid;\nextern const ddVec3 PaleGoldenRod;\nextern const ddVec3 PaleGreen;\nextern const ddVec3 PaleTurquoise;\nextern const ddVec3 PaleVioletRed;\nextern const ddVec3 PapayaWhip;\nextern const ddVec3 PeachPuff;\nextern const ddVec3 Peru;\nextern const ddVec3 Pink;\nextern const ddVec3 Plum;\nextern const ddVec3 PowderBlue;\nextern const ddVec3 Purple;\nextern const ddVec3 RebeccaPurple;\nextern const ddVec3 Red;\nextern const ddVec3 RosyBrown;\nextern const ddVec3 RoyalBlue;\nextern const ddVec3 SaddleBrown;\nextern const ddVec3 Salmon;\nextern const ddVec3 SandyBrown;\nextern const ddVec3 SeaGreen;\nextern const ddVec3 SeaShell;\nextern const ddVec3 Sienna;\nextern const ddVec3 Silver;\nextern const ddVec3 SkyBlue;\nextern const ddVec3 SlateBlue;\nextern const ddVec3 SlateGray;\nextern const ddVec3 Snow;\nextern const ddVec3 SpringGreen;\nextern const ddVec3 SteelBlue;\nextern const ddVec3 Tan;\nextern const ddVec3 Teal;\nextern const ddVec3 Thistle;\nextern const ddVec3 Tomato;\nextern const ddVec3 Turquoise;\nextern const ddVec3 Violet;\nextern const ddVec3 Wheat;\nextern const ddVec3 White;\nextern const ddVec3 WhiteSmoke;\nextern const ddVec3 Yellow;\nextern const ddVec3 YellowGreen;\n} // namespace colors\n#endif // DEBUG_DRAW_NO_DEFAULT_COLORS\n\n// ========================================================\n// Optional explicit context mode:\n// ========================================================\n\n#ifdef DEBUG_DRAW_EXPLICIT_CONTEXT\n    struct OpaqueContextType { };\n    typedef OpaqueContextType * ContextHandle;\n    #define DD_EXPLICIT_CONTEXT_ONLY(...) __VA_ARGS__\n#else // !DEBUG_DRAW_EXPLICIT_CONTEXT\n    #define DD_EXPLICIT_CONTEXT_ONLY(...) /* nothing */\n#endif // DEBUG_DRAW_EXPLICIT_CONTEXT\n\n// ========================================================\n// Debug Draw functions:\n// - Durations are always in milliseconds.\n// - Colors are RGB floats in the [0,1] range.\n// - Positions are in world-space, unless stated otherwise.\n// ========================================================\n\n// Add a point in 3D space to the debug draw queue.\n// Point is expressed in world-space coordinates.\n// Note that not all renderer support configurable point\n// size, so take the 'size' parameter as a hint only\nvoid point(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n           ddVec3_In pos,\n           ddVec3_In color,\n           float size = 1.0f,\n           int durationMillis = 0,\n           bool depthEnabled = true);\n\n// Add a 3D line to the debug draw queue. Note that\n// lines are expressed in world coordinates, and so are\n// all wireframe primitives which are built from lines.\nvoid line(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n          ddVec3_In from,\n          ddVec3_In to,\n          ddVec3_In color,\n          int durationMillis = 0,\n          bool depthEnabled = true);\n\n// Add a 2D text string as an overlay to the current view, using a built-in font.\n// Position is in screen-space pixels, origin at the top-left corner of the screen.\n// The third element (Z) of the position vector is ignored.\n// Note: Newlines and tabs are handled (1 tab = 4 spaces).\nvoid screenText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n                const char * str,\n                ddVec3_In pos,\n                ddVec3_In color,\n                float scaling = 1.0f,\n                int durationMillis = 0);\n\n// Add a 3D text label centered at the given world position that\n// gets projected to screen-space. The label always faces the viewer.\n// sx/sy, sw/sh are the viewport coordinates/size, in pixels.\n// 'vpMatrix' is the view * projection transform to map the text from 3D to 2D.\nvoid projectedText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n                   const char * str,\n                   ddVec3_In pos,\n                   ddVec3_In color,\n                   ddMat4x4_In vpMatrix,\n                   int sx, int sy,\n                   int sw, int sh,\n                   float scaling = 1.0f,\n                   int durationMillis = 0);\n\n// Add a set of three coordinate axis depicting the position and orientation of the given transform.\n// 'size' defines the size of the arrow heads. 'length' defines the length of the arrow's base line.\nvoid axisTriad(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n               ddMat4x4_In transform,\n               float size,\n               float length,\n               int durationMillis = 0,\n               bool depthEnabled = true);\n\n// Add a 3D line with an arrow-like end to the debug draw queue.\n// 'size' defines the arrow head size. 'from' and 'to' the length of the arrow's base line.\nvoid arrow(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n           ddVec3_In from,\n           ddVec3_In to,\n           ddVec3_In color,\n           float size,\n           int durationMillis = 0,\n           bool depthEnabled = true);\n\n// Add an axis-aligned cross (3 lines converging at a point) to the debug draw queue.\n// 'length' defines the length of the crossing lines.\n// 'center' is the world-space point where the lines meet.\nvoid cross(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n           ddVec3_In center,\n           float length,\n           int durationMillis = 0,\n           bool depthEnabled = true);\n\n// Add a wireframe circle to the debug draw queue.\nvoid circle(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n            ddVec3_In center,\n            ddVec3_In planeNormal,\n            ddVec3_In color,\n            float radius,\n            float numSteps,\n            int durationMillis = 0,\n            bool depthEnabled = true);\n\n// Add a wireframe plane in 3D space to the debug draw queue.\n// If 'normalVecScale' is not zero, a line depicting the plane normal is also draw.\nvoid plane(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n           ddVec3_In center,\n           ddVec3_In planeNormal,\n           ddVec3_In planeColor,\n           ddVec3_In normalVecColor,\n           float planeScale,\n           float normalVecScale,\n           int durationMillis = 0,\n           bool depthEnabled = true);\n\n// Add a wireframe sphere to the debug draw queue.\nvoid sphere(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n            ddVec3_In center,\n            ddVec3_In color,\n            float radius,\n            int durationMillis = 0,\n            bool depthEnabled = true);\n\n// Add a wireframe cone to the debug draw queue.\n// The cone 'apex' is the point where all lines meet.\n// The length of the 'dir' vector determines the thickness.\n// 'baseRadius' & 'apexRadius' are in degrees.\nvoid cone(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n          ddVec3_In apex,\n          ddVec3_In dir,\n          ddVec3_In color,\n          float baseRadius,\n          float apexRadius,\n          int durationMillis = 0,\n          bool depthEnabled = true);\n\n// Wireframe box from the eight points that define it.\nvoid box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n         const ddVec3 points[8],\n         ddVec3_In color,\n         int durationMillis = 0,\n         bool depthEnabled = true);\n\n// Add a wireframe box to the debug draw queue.\nvoid box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n         ddVec3_In center,\n         ddVec3_In color,\n         float width,\n         float height,\n         float depth,\n         int durationMillis = 0,\n         bool depthEnabled = true);\n\n// Add a wireframe Axis Aligned Bounding Box (AABB) to the debug draw queue.\nvoid aabb(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n          ddVec3_In mins,\n          ddVec3_In maxs,\n          ddVec3_In color,\n          int durationMillis = 0,\n          bool depthEnabled = true);\n\n// Add a wireframe frustum pyramid to the debug draw queue.\n// 'invClipMatrix' is the inverse of the matrix defining the frustum\n// (AKA clip) volume, which normally consists of the projection * view matrix.\n// E.g.: inverse(projMatrix * viewMatrix)\nvoid frustum(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n             ddMat4x4_In invClipMatrix,\n             ddVec3_In color,\n             int durationMillis = 0,\n             bool depthEnabled = true);\n\n// Add a vertex normal for debug visualization.\n// The normal vector 'normal' is assumed to be already normalized.\nvoid vertexNormal(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n                  ddVec3_In origin,\n                  ddVec3_In normal,\n                  float length,\n                  int durationMillis = 0,\n                  bool depthEnabled = true);\n\n// Add a \"tangent basis\" at a given point in world space.\n// Color scheme used is: normal=WHITE, tangent=YELLOW, bi-tangent=MAGENTA.\n// The normal vector, tangent and bi-tangent vectors are assumed to be already normalized.\nvoid tangentBasis(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n                  ddVec3_In origin,\n                  ddVec3_In normal,\n                  ddVec3_In tangent,\n                  ddVec3_In bitangent,\n                  float lengths,\n                  int durationMillis = 0,\n                  bool depthEnabled = true);\n\n// Makes a 3D square grid of lines along the X and Z planes.\n// 'y' defines the height in the Y axis where the grid is placed.\n// The grid will go from 'mins' to 'maxs' units in both the X and Z.\n// 'step' defines the gap between each line of the grid.\nvoid xzSquareGrid(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n                  float mins,\n                  float maxs,\n                  float y,\n                  float step,\n                  ddVec3_In color,\n                  int durationMillis = 0,\n                  bool depthEnabled = true);\n\n// Add a wireframe capsule to the debug draw queue.\nvoid capsule(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n    ddVec3_In center, \n    ddVec3_In axis,\n    float length, \n    float radius, \n    ddVec3_In color, \n    const int durationMillis = 0, \n    const bool depthEnabled = true);\n\n// ========================================================\n// Debug Draw vertex type:\n// The only drawing type the user has to interface with.\n// ========================================================\n\nunion DrawVertex\n{\n    struct\n    {\n        float x, y, z;\n        float r, g, b;\n        float size;\n    } point;\n\n    struct\n    {\n        float x, y, z;\n        float r, g, b;\n    } line;\n\n    struct\n    {\n        float x, y;\n        float u, v;\n        float r, g, b;\n    } glyph;\n};\n\n//\n// Opaque handle to a texture object.\n// Used by the debug text drawing functions.\n//\nstruct OpaqueTextureType { };\ntypedef OpaqueTextureType * GlyphTextureHandle;\n\n// ========================================================\n// Debug Draw rendering callbacks:\n// Implementation is provided by the user so we don't\n// tie this code directly to a specific rendering API.\n// ========================================================\n\nclass RenderInterface\n{\npublic:\n\n    //\n    // These are called by dd::flush() before any drawing and after drawing is finished.\n    // User can override these to perform any common setup for subsequent draws and to\n    // cleanup afterwards. By default, no-ops stubs are provided.\n    //\n    virtual void beginDraw();\n    virtual void endDraw();\n\n    //\n    // Create/free the glyph bitmap texture used by the debug text drawing functions.\n    // The debug renderer currently only creates one of those on startup.\n    //\n    // You're not required to implement these two if you don't care about debug text drawing.\n    // Default no-op stubs are provided by default, which disable debug text rendering.\n    //\n    // Texture dimensions are in pixels, data format is always 8-bits per pixel (Grayscale/GL_RED).\n    // The pixel values range from 255 for a pixel within a glyph to 0 for a transparent pixel.\n    // If createGlyphTexture() returns null, the renderer will disable all text drawing functions.\n    //\n    virtual GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels);\n    virtual void destroyGlyphTexture(GlyphTextureHandle glyphTex);\n\n    //\n    // Batch drawing methods for the primitives used by the debug renderer.\n    // If you don't wish to support a given primitive type, don't override the method.\n    //\n    virtual void drawPointList(const DrawVertex * points, int count, bool depthEnabled);\n    virtual void drawLineList(const DrawVertex * lines, int count, bool depthEnabled);\n    virtual void drawGlyphList(const DrawVertex * glyphs, int count, GlyphTextureHandle glyphTex);\n\n    // User defined cleanup. Nothing by default.\n    virtual ~RenderInterface() = 0;\n};\n\n// ========================================================\n// Housekeeping functions:\n// ========================================================\n\n// Flags for dd::flush()\nenum FlushFlags\n{\n    FlushPoints = 1 << 1,\n    FlushLines  = 1 << 2,\n    FlushText   = 1 << 3,\n    FlushAll    = (FlushPoints | FlushLines | FlushText)\n};\n\n// Initialize with the user-supplied renderer interface.\n// Given object must remain valid until after dd::shutdown() is called!\n// If 'renderer' is null, the Debug Draw functions become no-ops, but\n// can still be safely called.\nbool initialize(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle * outCtx,) RenderInterface * renderer);\n\n// After this is called, it is safe to dispose the dd::RenderInterface instance\n// you passed to dd::initialize(). Shutdown will also attempt to free the glyph texture.\nvoid shutdown(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));\n\n// Test if the Debug Draw library is currently initialized and has a render interface.\nbool isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));\n\n// Test if there's data in the debug draw queue and dd::flush() should be called.\nbool hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));\n\n// Manually removes all queued debug render data without drawing.\n// This is not normally called. To draw stuff, call dd::flush() instead.\nvoid clear(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));\n\n// Actually calls the dd::RenderInterface to consume the debug draw queues.\n// Objects that have expired their lifetimes get removed. Pass the current\n// application time in milliseconds to remove timed objects that have expired.\n// Passing zero removes all objects after they get drawn, regardless of lifetime.\nvoid flush(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)\n           std::int64_t currTimeMillis = 0,\n           std::uint32_t flags = FlushAll);\n\n} // namespace dd\n\n// ================== End of header file ==================\n#endif // DEBUG_DRAW_HPP\n// ================== End of header file ==================\n\n// ================================================================================================\n//\n//                                  Debug Draw Implementation\n//\n// ================================================================================================\n\n#ifdef DEBUG_DRAW_IMPLEMENTATION\n\n#ifndef DD_MALLOC\n    #include <cstdlib>\n    #define DD_MALLOC std::malloc\n    #define DD_MFREE  std::free\n#endif // DD_MALLOC\n\n#if DEBUG_DRAW_USE_STD_MATH\n    #include <math.h>\n    #include <float.h>\n#endif // DEBUG_DRAW_USE_STD_MATH\n\nnamespace dd\n{\n\n#if defined(FLT_EPSILON) && DEBUG_DRAW_USE_STD_MATH\n    static const float FloatEpsilon = FLT_EPSILON;\n#else // !FLT_EPSILON || !DEBUG_DRAW_USE_STD_MATH\n    static const float FloatEpsilon = 1e-14;\n#endif // FLT_EPSILON && DEBUG_DRAW_USE_STD_MATH\n\n#if defined(M_PI) && DEBUG_DRAW_USE_STD_MATH\n    static const float PI = static_cast<float>(M_PI);\n#else // !M_PI || !DEBUG_DRAW_USE_STD_MATH\n    static const float PI = 3.1415926535897931f;\n#endif // M_PI && DEBUG_DRAW_USE_STD_MATH\n\nstatic const float HalfPI = PI * 0.5f;\nstatic const float TAU    = PI * 2.0f;\n\ntemplate<typename T>\nstatic inline float degreesToRadians(const T degrees)\n{\n    return (static_cast<float>(degrees) * PI / 180.0f);\n}\n\ntemplate<typename T, int Size>\nstatic inline int arrayLength(const T (&)[Size])\n{\n    return Size;\n}\n\n// ========================================================\n// Built-in color constants:\n// ========================================================\n\n#ifndef DEBUG_DRAW_NO_DEFAULT_COLORS\nnamespace colors\n{\nconst ddVec3 AliceBlue         = {0.941176f, 0.972549f, 1.000000f};\nconst ddVec3 AntiqueWhite      = {0.980392f, 0.921569f, 0.843137f};\nconst ddVec3 Aquamarine        = {0.498039f, 1.000000f, 0.831373f};\nconst ddVec3 Azure             = {0.941176f, 1.000000f, 1.000000f};\nconst ddVec3 Beige             = {0.960784f, 0.960784f, 0.862745f};\nconst ddVec3 Bisque            = {1.000000f, 0.894118f, 0.768627f};\nconst ddVec3 Black             = {0.000000f, 0.000000f, 0.000000f};\nconst ddVec3 BlanchedAlmond    = {1.000000f, 0.921569f, 0.803922f};\nconst ddVec3 Blue              = {0.000000f, 0.000000f, 1.000000f};\nconst ddVec3 BlueViolet        = {0.541176f, 0.168627f, 0.886275f};\nconst ddVec3 Brown             = {0.647059f, 0.164706f, 0.164706f};\nconst ddVec3 BurlyWood         = {0.870588f, 0.721569f, 0.529412f};\nconst ddVec3 CadetBlue         = {0.372549f, 0.619608f, 0.627451f};\nconst ddVec3 Chartreuse        = {0.498039f, 1.000000f, 0.000000f};\nconst ddVec3 Chocolate         = {0.823529f, 0.411765f, 0.117647f};\nconst ddVec3 Coral             = {1.000000f, 0.498039f, 0.313726f};\nconst ddVec3 CornflowerBlue    = {0.392157f, 0.584314f, 0.929412f};\nconst ddVec3 Cornsilk          = {1.000000f, 0.972549f, 0.862745f};\nconst ddVec3 Crimson           = {0.862745f, 0.078431f, 0.235294f};\nconst ddVec3 Cyan              = {0.000000f, 1.000000f, 1.000000f};\nconst ddVec3 DarkBlue          = {0.000000f, 0.000000f, 0.545098f};\nconst ddVec3 DarkCyan          = {0.000000f, 0.545098f, 0.545098f};\nconst ddVec3 DarkGoldenRod     = {0.721569f, 0.525490f, 0.043137f};\nconst ddVec3 DarkGray          = {0.662745f, 0.662745f, 0.662745f};\nconst ddVec3 DarkGreen         = {0.000000f, 0.392157f, 0.000000f};\nconst ddVec3 DarkKhaki         = {0.741176f, 0.717647f, 0.419608f};\nconst ddVec3 DarkMagenta       = {0.545098f, 0.000000f, 0.545098f};\nconst ddVec3 DarkOliveGreen    = {0.333333f, 0.419608f, 0.184314f};\nconst ddVec3 DarkOrange        = {1.000000f, 0.549020f, 0.000000f};\nconst ddVec3 DarkOrchid        = {0.600000f, 0.196078f, 0.800000f};\nconst ddVec3 DarkRed           = {0.545098f, 0.000000f, 0.000000f};\nconst ddVec3 DarkSalmon        = {0.913725f, 0.588235f, 0.478431f};\nconst ddVec3 DarkSeaGreen      = {0.560784f, 0.737255f, 0.560784f};\nconst ddVec3 DarkSlateBlue     = {0.282353f, 0.239216f, 0.545098f};\nconst ddVec3 DarkSlateGray     = {0.184314f, 0.309804f, 0.309804f};\nconst ddVec3 DarkTurquoise     = {0.000000f, 0.807843f, 0.819608f};\nconst ddVec3 DarkViolet        = {0.580392f, 0.000000f, 0.827451f};\nconst ddVec3 DeepPink          = {1.000000f, 0.078431f, 0.576471f};\nconst ddVec3 DeepSkyBlue       = {0.000000f, 0.749020f, 1.000000f};\nconst ddVec3 DimGray           = {0.411765f, 0.411765f, 0.411765f};\nconst ddVec3 DodgerBlue        = {0.117647f, 0.564706f, 1.000000f};\nconst ddVec3 FireBrick         = {0.698039f, 0.133333f, 0.133333f};\nconst ddVec3 FloralWhite       = {1.000000f, 0.980392f, 0.941176f};\nconst ddVec3 ForestGreen       = {0.133333f, 0.545098f, 0.133333f};\nconst ddVec3 Gainsboro         = {0.862745f, 0.862745f, 0.862745f};\nconst ddVec3 GhostWhite        = {0.972549f, 0.972549f, 1.000000f};\nconst ddVec3 Gold              = {1.000000f, 0.843137f, 0.000000f};\nconst ddVec3 GoldenRod         = {0.854902f, 0.647059f, 0.125490f};\nconst ddVec3 Gray              = {0.501961f, 0.501961f, 0.501961f};\nconst ddVec3 Green             = {0.000000f, 0.501961f, 0.000000f};\nconst ddVec3 GreenYellow       = {0.678431f, 1.000000f, 0.184314f};\nconst ddVec3 HoneyDew          = {0.941176f, 1.000000f, 0.941176f};\nconst ddVec3 HotPink           = {1.000000f, 0.411765f, 0.705882f};\nconst ddVec3 IndianRed         = {0.803922f, 0.360784f, 0.360784f};\nconst ddVec3 Indigo            = {0.294118f, 0.000000f, 0.509804f};\nconst ddVec3 Ivory             = {1.000000f, 1.000000f, 0.941176f};\nconst ddVec3 Khaki             = {0.941176f, 0.901961f, 0.549020f};\nconst ddVec3 Lavender          = {0.901961f, 0.901961f, 0.980392f};\nconst ddVec3 LavenderBlush     = {1.000000f, 0.941176f, 0.960784f};\nconst ddVec3 LawnGreen         = {0.486275f, 0.988235f, 0.000000f};\nconst ddVec3 LemonChiffon      = {1.000000f, 0.980392f, 0.803922f};\nconst ddVec3 LightBlue         = {0.678431f, 0.847059f, 0.901961f};\nconst ddVec3 LightCoral        = {0.941176f, 0.501961f, 0.501961f};\nconst ddVec3 LightCyan         = {0.878431f, 1.000000f, 1.000000f};\nconst ddVec3 LightGoldenYellow = {0.980392f, 0.980392f, 0.823529f};\nconst ddVec3 LightGray         = {0.827451f, 0.827451f, 0.827451f};\nconst ddVec3 LightGreen        = {0.564706f, 0.933333f, 0.564706f};\nconst ddVec3 LightPink         = {1.000000f, 0.713726f, 0.756863f};\nconst ddVec3 LightSalmon       = {1.000000f, 0.627451f, 0.478431f};\nconst ddVec3 LightSeaGreen     = {0.125490f, 0.698039f, 0.666667f};\nconst ddVec3 LightSkyBlue      = {0.529412f, 0.807843f, 0.980392f};\nconst ddVec3 LightSlateGray    = {0.466667f, 0.533333f, 0.600000f};\nconst ddVec3 LightSteelBlue    = {0.690196f, 0.768627f, 0.870588f};\nconst ddVec3 LightYellow       = {1.000000f, 1.000000f, 0.878431f};\nconst ddVec3 Lime              = {0.000000f, 1.000000f, 0.000000f};\nconst ddVec3 LimeGreen         = {0.196078f, 0.803922f, 0.196078f};\nconst ddVec3 Linen             = {0.980392f, 0.941176f, 0.901961f};\nconst ddVec3 Magenta           = {1.000000f, 0.000000f, 1.000000f};\nconst ddVec3 Maroon            = {0.501961f, 0.000000f, 0.000000f};\nconst ddVec3 MediumAquaMarine  = {0.400000f, 0.803922f, 0.666667f};\nconst ddVec3 MediumBlue        = {0.000000f, 0.000000f, 0.803922f};\nconst ddVec3 MediumOrchid      = {0.729412f, 0.333333f, 0.827451f};\nconst ddVec3 MediumPurple      = {0.576471f, 0.439216f, 0.858824f};\nconst ddVec3 MediumSeaGreen    = {0.235294f, 0.701961f, 0.443137f};\nconst ddVec3 MediumSlateBlue   = {0.482353f, 0.407843f, 0.933333f};\nconst ddVec3 MediumSpringGreen = {0.000000f, 0.980392f, 0.603922f};\nconst ddVec3 MediumTurquoise   = {0.282353f, 0.819608f, 0.800000f};\nconst ddVec3 MediumVioletRed   = {0.780392f, 0.082353f, 0.521569f};\nconst ddVec3 MidnightBlue      = {0.098039f, 0.098039f, 0.439216f};\nconst ddVec3 MintCream         = {0.960784f, 1.000000f, 0.980392f};\nconst ddVec3 MistyRose         = {1.000000f, 0.894118f, 0.882353f};\nconst ddVec3 Moccasin          = {1.000000f, 0.894118f, 0.709804f};\nconst ddVec3 NavajoWhite       = {1.000000f, 0.870588f, 0.678431f};\nconst ddVec3 Navy              = {0.000000f, 0.000000f, 0.501961f};\nconst ddVec3 OldLace           = {0.992157f, 0.960784f, 0.901961f};\nconst ddVec3 Olive             = {0.501961f, 0.501961f, 0.000000f};\nconst ddVec3 OliveDrab         = {0.419608f, 0.556863f, 0.137255f};\nconst ddVec3 Orange            = {1.000000f, 0.647059f, 0.000000f};\nconst ddVec3 OrangeRed         = {1.000000f, 0.270588f, 0.000000f};\nconst ddVec3 Orchid            = {0.854902f, 0.439216f, 0.839216f};\nconst ddVec3 PaleGoldenRod     = {0.933333f, 0.909804f, 0.666667f};\nconst ddVec3 PaleGreen         = {0.596078f, 0.984314f, 0.596078f};\nconst ddVec3 PaleTurquoise     = {0.686275f, 0.933333f, 0.933333f};\nconst ddVec3 PaleVioletRed     = {0.858824f, 0.439216f, 0.576471f};\nconst ddVec3 PapayaWhip        = {1.000000f, 0.937255f, 0.835294f};\nconst ddVec3 PeachPuff         = {1.000000f, 0.854902f, 0.725490f};\nconst ddVec3 Peru              = {0.803922f, 0.521569f, 0.247059f};\nconst ddVec3 Pink              = {1.000000f, 0.752941f, 0.796078f};\nconst ddVec3 Plum              = {0.866667f, 0.627451f, 0.866667f};\nconst ddVec3 PowderBlue        = {0.690196f, 0.878431f, 0.901961f};\nconst ddVec3 Purple            = {0.501961f, 0.000000f, 0.501961f};\nconst ddVec3 RebeccaPurple     = {0.400000f, 0.200000f, 0.600000f};\nconst ddVec3 Red               = {1.000000f, 0.000000f, 0.000000f};\nconst ddVec3 RosyBrown         = {0.737255f, 0.560784f, 0.560784f};\nconst ddVec3 RoyalBlue         = {0.254902f, 0.411765f, 0.882353f};\nconst ddVec3 SaddleBrown       = {0.545098f, 0.270588f, 0.074510f};\nconst ddVec3 Salmon            = {0.980392f, 0.501961f, 0.447059f};\nconst ddVec3 SandyBrown        = {0.956863f, 0.643137f, 0.376471f};\nconst ddVec3 SeaGreen          = {0.180392f, 0.545098f, 0.341176f};\nconst ddVec3 SeaShell          = {1.000000f, 0.960784f, 0.933333f};\nconst ddVec3 Sienna            = {0.627451f, 0.321569f, 0.176471f};\nconst ddVec3 Silver            = {0.752941f, 0.752941f, 0.752941f};\nconst ddVec3 SkyBlue           = {0.529412f, 0.807843f, 0.921569f};\nconst ddVec3 SlateBlue         = {0.415686f, 0.352941f, 0.803922f};\nconst ddVec3 SlateGray         = {0.439216f, 0.501961f, 0.564706f};\nconst ddVec3 Snow              = {1.000000f, 0.980392f, 0.980392f};\nconst ddVec3 SpringGreen       = {0.000000f, 1.000000f, 0.498039f};\nconst ddVec3 SteelBlue         = {0.274510f, 0.509804f, 0.705882f};\nconst ddVec3 Tan               = {0.823529f, 0.705882f, 0.549020f};\nconst ddVec3 Teal              = {0.000000f, 0.501961f, 0.501961f};\nconst ddVec3 Thistle           = {0.847059f, 0.749020f, 0.847059f};\nconst ddVec3 Tomato            = {1.000000f, 0.388235f, 0.278431f};\nconst ddVec3 Turquoise         = {0.250980f, 0.878431f, 0.815686f};\nconst ddVec3 Violet            = {0.933333f, 0.509804f, 0.933333f};\nconst ddVec3 Wheat             = {0.960784f, 0.870588f, 0.701961f};\nconst ddVec3 White             = {1.000000f, 1.000000f, 1.000000f};\nconst ddVec3 WhiteSmoke        = {0.960784f, 0.960784f, 0.960784f};\nconst ddVec3 Yellow            = {1.000000f, 1.000000f, 0.000000f};\nconst ddVec3 YellowGreen       = {0.603922f, 0.803922f, 0.196078f};\n} // namespace colors\n#endif // DEBUG_DRAW_NO_DEFAULT_COLORS\n\n// ========================================================\n// Embedded bitmap font for debug text rendering:\n// ========================================================\n\nstruct FontChar\n{\n    std::uint16_t x;\n    std::uint16_t y;\n};\n\nstruct FontCharSet\n{\n    enum { MaxChars = 256 };\n    const std::uint8_t * bitmap;\n    int bitmapWidth;\n    int bitmapHeight;\n    int bitmapColorChannels;\n    int bitmapDecompressSize;\n    int charBaseHeight;\n    int charWidth;\n    int charHeight;\n    int charCount;\n    FontChar chars[MaxChars];\n};\n\n#if DEBUG_DRAW_CXX11_SUPPORTED\n    #define DD_ALIGNED_BUFFER(name) alignas(16) static const std::uint8_t name[]\n#else // !C++11\n    #if defined(__GNUC__) // Clang & GCC\n        #define DD_ALIGNED_BUFFER(name) static const std::uint8_t name[] __attribute__((aligned(16)))\n    #elif defined(_MSC_VER) // Visual Studio\n        #define DD_ALIGNED_BUFFER(name) __declspec(align(16)) static const std::uint8_t name[]\n    #else // Unknown compiler\n        #define DD_ALIGNED_BUFFER(name) static const std::uint8_t name[] /* hope for the best! */\n    #endif // Compiler id\n#endif // DEBUG_DRAW_CXX11_SUPPORTED\n\n//\n// Data generated from font 'Monoid18' by font-tool.\n// Command line: monoid-18.fnt monoid-18.png monoid-18.h Monoid18 --static --compress --structs --hex --encoding=lzw\n//\n// The Monoid font, copyright (c) 2015 Andreas Larsen and contributors,\n// is released under the MIT license. See: https://github.com/larsenwork/monoid\n//\n// The following glyph bitmap is an LZW compressed graymap.\n// ~7.55 KB of data.\n//\n// It is better to ensure it is aligned to a, say 16 bytes boundary,\n// because we cast the first few bytes to uint32s.\n//\n// font-tool: https://github.com/glampert/font-tool\n// LZW compression: https://github.com/glampert/compression-algorithms\n//\nDD_ALIGNED_BUFFER(s_fontMonoid18Bitmap) =\n\"\\x2F\\x1E\\x00\\x00\\x78\\xF1\\x00\\x00\\x00\\x00\\x06\\x14\\x38\\x90\\x60\\x41\\x83\\x07\\x11\\x26\\x54\\xB8\"\n\"\\x90\\x61\\x43\\x87\\x0F\\x21\\x46\\x94\\x38\\x91\\x62\\x45\\x8B\\x17\\x31\\x66\\xD4\\x88\\x70\\x43\\x13\\x8C\"\n\"\\x15\\x80\\x0D\\xD8\\x98\\x10\\x0D\\x98\\x84\\x4D\\x36\\x8C\\x8C\\x28\\x40\\xC1\\x01\\x95\\x2F\\x1F\\x06\\x10\"\n\"\\x10\\x00\\x26\\xC0\\x44\\xFE\\x5C\\x5A\\xA4\\xF4\\x8F\\x4E\\xCD\\x81\\x01\\xF8\\xFD\\x4B\\x70\\x30\\x40\\x3F\"\n\"\\x3F\\x3E\\x17\\x32\\xFA\\xB7\\xB4\\x5F\\xCA\\x8C\\x67\\xFC\\xD1\\x04\\xB0\\x2F\\x0D\\x52\\x82\\x74\\x96\\xF2\"\n\"\\x54\\xD9\\xC4\\x5D\\xD6\\xA5\\xBF\\x10\\x36\\x5B\\xBA\\xE3\\x60\\x81\\x7E\\xFD\\xA4\\x2E\\x3C\\xC0\\xE8\\xDB\"\n\"\\xD2\\x77\\xC1\\x2A\\x34\\xF4\\xF2\\xEF\\x52\\x42\\x7E\\x3D\\xAD\\x1E\\x74\\xB5\\x34\\x13\\xB4\\xA5\\x11\\x9E\"\n\"\\x46\\x05\\x78\\x37\\x6F\\xC0\\x25\\x4B\\xDB\\xFE\\xAB\\xB2\\x51\\x0E\\xE2\\x7E\\xFF\\xDE\\xF9\\x73\\xA6\\xF7\"\n\"\\x9F\\xBF\\xA5\\x14\\x0E\\xEE\\xFC\\xC2\\xD0\\x44\\x56\\x7F\\xEF\\xB2\\xB2\\x60\\xA8\\xCF\\xDF\\x50\\x84\\x84\"\n\"\\x0B\\x13\\x8C\\xF0\\xAF\\x5F\\xCE\\x2F\\xFF\\xC0\\x62\\x84\\x4A\\x13\\x28\\xDE\\xC2\\xD8\\xFC\\xC5\\xA5\\xE0\"\n\"\\xAF\\x5B\\x40\\x1A\\x16\\x0F\\xF8\\xF3\\x67\\x02\\x40\\x17\\x7F\\x09\\x4B\\xB0\\x06\\x30\\xE4\\x5F\\x6F\\x83\"\n\"\\xC1\\xFB\\x31\\xDC\\xF7\\x4F\\x4D\\x5A\\x2B\\xFF\\xD8\\x2D\\x9C\\xF2\\x8F\\x94\\x42\\xD4\\xA9\\x05\\x7E\\xF8\"\n\"\\x57\\x35\\xE0\\x3E\\x6E\\x19\\x8D\\x07\\xE4\\x47\\xBE\\xF0\\xB2\\xE3\\x83\\x9D\\x2B\\x1A\\x5F\\x91\\xF9\\x66\"\n\"\\x00\\xB3\\x11\\x66\\xFB\\x07\\x02\\xA0\\xB2\\x7F\\xA2\\x0D\\x12\\xE5\\x1F\\x26\\x14\\x3A\\xAC\\xBB\\x81\\x70\"\n\"\\x4B\\xEB\\xA0\\x7C\\xFE\\x01\\xCC\\x2E\\xDB\\x16\\x6A\\x86\\xC0\\x8C\\xC4\\x3B\\x10\\x80\\x01\\xFA\\x71\\xCE\"\n\"\\xA2\\x59\\xDA\\x9A\\xC5\\xC3\\x7F\\xBE\\x01\\x46\\x23\\x09\\x11\\x4A\\xE4\\x1F\\x6F\\x9A\\xE8\\x86\\x2E\\x00\"\n\"\\xE4\\x6B\\xAD\\xA2\\xC6\\x34\\x00\\x08\\x3F\\x83\\x34\\xF8\\x67\\x32\\x80\\x6A\\xBC\\xB1\\x20\\x08\\xFE\\xE1\"\n\"\\x47\\x21\\x34\\xFE\\xF9\\x00\\xA0\\x06\\xAC\\x00\\xC3\\x0A\\x67\\x04\\x43\\x88\\xB9\\xD8\\x1E\\x74\\xE8\\x3B\"\n\"\\x8C\\xA6\\xC3\\x0C\\x00\\x66\\xB4\\xB2\\x28\\x00\\xCB\\xBC\\x5A\\x2A\\xC9\\x81\\x5A\\x3A\\xC0\\xCB\\x03\\x14\"\n\"\\x10\\xC0\\x3B\\x08\\x0B\\xDA\\x26\\xAB\\x76\\x00\\x30\\xB1\\x1F\\x91\\x2A\\x92\\x61\\xC5\\xFB\\xB6\\x24\\x48\"\n\"\\x97\\x7F\\x66\\x10\\xE8\\x9E\\x06\\x0F\\xDA\\xE5\\x1F\\xB2\\x10\\x82\\xCA\\x00\\x00\\xD2\\xC8\\x32\\xCE\\x82\"\n\"\\xD2\\xF9\\x27\\xC6\\x31\\x9D\\x24\\xD3\\xA2\\xC3\\xFC\\x51\\xE3\\xB1\\xE8\\x30\\x12\\xC0\\x0F\\x7F\\x1A\\x20\"\n\"\\xA0\\x01\\x7E\\xFE\\x10\\x93\\xA0\\x2B\\xB3\\xFC\\xE7\\xA8\\x26\\x13\\x32\\x81\\x08\\xE2\\xD4\\xFC\\xD3\\x22\"\n\"\\x0C\\xFF\\xA9\\x03\\x00\\x34\\xDE\\x7B\\xCE\\xC1\\x80\\x0E\\x78\\xB5\\xA0\\x0C\\xFE\\x41\\xB3\\xCF\\xE3\\x3C\"\n\"\\xA8\\xAC\\x89\\x06\\x14\\xF8\\x63\\xD0\\x81\\xDC\\xD4\\x11\\xD4\\x83\\x36\\x88\\x6B\\x30\\xF2\\x04\\xF8\\x8D\"\n\"\\xA0\\x06\\x32\\x99\\x45\\xD5\\x80\\x76\\x90\\xC5\\xA0\\x40\\xB3\\x7A\\x46\\x41\\x8B\\x66\\x7C\\x72\\x20\\x60\"\n\"\\x3C\\xEC\\x36\\x98\\x09\\x4F\\x53\\xF4\\x20\\x4B\\x58\\x33\\xF5\\xA2\\x1D\\xBC\\xF2\\xC7\\x8A\\x8D\\x96\\xF9\"\n\"\\xEF\\x56\\x00\\xCC\\xD8\\x33\\x20\\x57\\x7E\\x15\\x48\\x3F\\xFE\\x16\\xD2\\x96\\x20\\x7B\\x2A\\xAB\\x03\\x84\"\n\"\\x7E\\x30\\x31\\x21\\x98\\xA5\\x00\\x0C\\x08\\xA8\\xAC\\x20\\x05\\xA0\\x92\\x5F\\x47\\xF1\\x0A\\x2F\\x01\\x08\"\n\"\\x90\\x2D\\x49\\x7D\\x21\\x92\\x49\\x00\\x01\\x0E\\xC0\\x14\\x80\\x8B\\x35\\x35\\x88\\x5C\\x17\\x0D\\xB2\\x98\"\n\"\\xE3\\x91\\x3B\\x26\\x08\\x24\\xAF\\xFA\\x31\\xED\\xA2\\xE4\\x34\\x2C\\x08\\x2A\\x78\\xF7\\x0B\\x28\\x9B\\x7A\"\n\"\\x01\\x62\\xB9\\x21\\x8A\\x05\\x02\\x23\\xB1\\x4E\\x4D\\x71\\x2A\\xA0\\x19\\xFE\\x29\\x25\\x02\\x75\\x60\\x03\"\n\"\\x68\\xE6\\x6B\\x19\\xAD\\x80\\x07\\xD6\\x44\\x92\\x83\\xE6\\x87\\xD2\\x3B\\xD6\\xA2\\xC6\\x3A\\xD5\\xF2\\xDA\"\n\"\\x80\\x1A\\x5E\\x13\\x21\\xAA\\xAB\\x7E\\x7A\\xAA\\x45\\x2A\\x50\\xD1\\xC7\\x8C\\xB4\\x89\\xD9\\xA0\\x97\\xE3\"\n\"\\xAD\\x13\\x00\\x1E\\x9F\\x6E\\xB7\\x60\\x44\\x15\\x52\\x00\\x0C\\x84\\xF1\\x25\\xA8\\x31\\x21\\x03\\x98\\x6E\"\n\"\\x16\\x40\\xB0\\x23\\xA8\\xEC\\x12\\x00\\x12\\x70\\xB2\\x19\\x29\\x6A\\x62\\x16\\x7F\\xC0\\x68\\x02\\x0C\\x7F\"\n\"\\x80\\xF1\\x88\\x22\\x2A\\xBE\\x81\\x46\\x72\\xC8\\x24\\x87\\xC6\\x9B\\xAB\\x01\\xC8\\x5A\\x01\\xC3\\x67\\x31\"\n\"\\x89\\x20\\xC8\\x2B\\x0F\\xDD\\x72\\xCC\\xD5\\x23\\xAF\\x6C\\x21\\x31\\x0A\\xF6\\xA0\\x97\\x55\\xA8\\x8C\\x07\"\n\"\\x1E\\x82\\xA2\\x99\\x56\\x5B\\x19\\xC2\\x99\\xA0\\xE4\\x96\\x6A\\x79\\x20\\xA7\\xD9\\x8C\\x00\\x4B\\x79\\x05\"\n\"\\x02\\x2A\\xBB\\x80\\xF4\\xF9\\x87\\x08\\x2A\\xBC\\x5E\\x28\\x80\\xAA\\x97\\x22\\x3D\\xA2\\xF5\\x12\\x6A\\x18\"\n\"\\xA7\\x4A\\xBC\\x8A\\x45\\x23\\xD4\\x56\\x98\\x2F\\xA3\\x42\\x8D\\x25\\xE8\\x8C\\x7F\\x20\\x00\\x60\\xAF\\xA5\"\n\"\\xDC\\x09\\x86\\x66\\x3D\\xF9\\xAC\\x5D\\x5C\\x82\\x50\\x25\\x42\\x2C\\x45\\x0C\\x8A\\xA0\\x85\\xE0\\x79\\x20\"\n\"\\xA2\\x81\\x4D\\xF9\\x39\\x2F\\xA0\\x1A\\xAD\\xB6\\xA8\\x85\\x52\\xFC\\xC1\\x83\\x16\\xF0\\xA0\\x1F\\xA5\\x98\"\n\"\\x5F\\x41\\x82\\x92\\xA5\\xF5\\x19\\xCC\\x76\\x99\\xAB\\x4C\\x02\\x14\\xC0\\x9A\\x0A\\x54\\x80\\x1D\\x86\\xCA\"\n\"\\x08\\x6A\\x68\\xB5\\xC0\\x88\\xA0\\xCB\\x17\\x06\\x69\\x0C\\xE0\\x00\\xC0\\x03\\x40\\xA8\\x01\\x00\\x0D\\x50\"\n\"\\x16\\x41\\x78\\x34\\xB6\\x9B\\x69\\x30\\x20\\xED\\xEA\\x4E\\x70\\xFE\\x41\\x9C\\x8A\\xE8\\xE7\\x50\\x00\\x01\"\n\"\\x12\\x6B\\x9C\\xE7\\x90\\xA8\\x01\\x00\\x7A\\x06\\xD1\\xC7\\x3B\\x80\\x08\\x44\\x7F\\xB0\\xE7\\x20\\x0D\\xDC\"\n\"\\x07\\xA5\\x00\\x50\\x23\\x34\\x00\\xA4\\x0B\\x66\\xB3\\x12\\x6A\\x4C\\xF4\\xB6\\x8B\\x30\\x48\\x56\\xD0\\xE2\"\n\"\\x8E\\x43\\x04\\x04\\x2E\\xF5\\x29\\x84\\x02\\xCA\\x01\\x08\\x73\\x84\\x25\\x11\\x2A\\x54\\x46\\x86\\x00\\x28\"\n\"\\x40\\xEE\\x24\\x26\\x95\\x06\\x56\\xCC\\x28\\x08\\x69\\x80\\x83\\xC4\\x53\\x8A\\xC0\\xFD\\x03\\x84\\x14\\x51\"\n\"\\x63\\x55\\xAE\\xE3\\x0F\\x73\\x61\\x64\\x3B\\x16\\x1A\\xC8\\x74\\x00\\x51\\xB2\\x92\\x09\\x04\\x3A\\x10\\x59\"\n\"\\x23\\x40\\x22\\x20\\xAB\\x13\\x56\\xE4\\x15\\xE4\\x6B\\x96\\x57\\x0E\\x58\\x91\\x6C\\xB1\\x10\\x22\\x28\\x69\"\n\"\\x48\\xF1\\x26\\x97\\xB0\\x89\\xD4\\xC8\\x1F\\x6D\\xF9\\xCC\\x52\\x86\\xA0\\x12\\xD2\\xA8\\x4C\\x20\\x2D\\xF0\"\n\"\\x0C\\x68\\x96\\x82\\xBA\\x81\\x68\\xC6\\x90\\x94\\xF4\\x09\\x0F\\xBA\\x92\\x15\\x40\\x5C\\x47\\x93\\x00\\x00\"\n\"\\x81\\x15\\x9A\\x90\\x4B\\x5D\\xE6\\x72\\x5D\\x67\\x4B\\x12\\x55\\xC0\\x33\\x90\\x06\\x54\\xF0\\x1F\\xEE\\xA8\"\n\"\\x62\\x44\\x28\\xF0\\x18\\xAF\\x78\\xC3\\x67\\x1B\\x99\\xCB\\x22\\x0C\\xA2\\x80\\x4C\\x24\\xE6\\x33\\xDF\\xE8\"\n\"\\x5E\\x40\\xCC\\x82\\x96\\x56\\x06\\xB3\\x20\\x04\\xF0\\x12\\x42\\xF6\\xC0\\xBC\\xE6\\x71\\x53\\x22\\xDF\\xD4\"\n\"\\x88\\x02\\xFC\\x51\\x97\\x9A\\x1C\\x8C\\x94\\x10\\xD9\\x89\\x2B\\x09\\x72\\x48\\x72\\xAA\\xA6\\x05\\x26\\xB0\"\n\"\\xE7\\x3D\\xED\\x19\\xC9\\x79\\xEE\\x13\\x20\\x96\\xF4\\xC9\\x17\\x3C\\x37\\x91\\x0A\\xCC\\x82\\x4D\\x0F\\x91\"\n\"\\x27\\x3F\\x11\\x9A\\x50\\x85\\xF2\\x13\\x98\\x0B\\x75\\xE8\\x43\\x21\\x1A\\x51\\x89\\x4E\\x94\\xA2\\x15\\xB5\"\n\"\\xE8\\x45\\x31\\x9A\\x51\\x8D\\x6E\\x94\\xA3\\x1D\\xF5\\xE8\\x47\\x41\\x1A\\x52\\x91\\x8E\\x94\\xA4\\x25\\x35\"\n\"\\xE9\\x49\\x51\\x9A\\x52\\x95\\xAE\\x14\\xA1\\x8C\\x00\\xC3\\xFD\\x20\\x42\\x03\\x46\\xE8\\x73\\x20\\x44\\xB0\"\n\"\\xE9\\x4D\\x15\\xB2\\x81\\x9B\\xDA\\xB4\\x99\\x03\\xA1\\x41\\xDD\\x20\\x12\\x50\\x96\\xA2\\x94\\x53\\xFF\\x80\"\n\"\\x66\\x43\\x2A\\xA0\\x4C\\xF8\\x15\\x64\\x79\\xE9\\xCA\\x21\\x00\\xB8\\xB6\\x94\\xA5\\x16\\x64\\x3A\\x47\\x75\"\n\"\\x48\\x04\\x82\\x42\\xC4\\xA1\\x1E\\x04\\x62\\x83\\xAC\\x68\\x04\\x16\\x07\\xBC\\x85\\x60\\xE3\\x1F\\xC0\\x30\"\n\"\\x41\\x4E\\x0A\\x42\\x03\\xB5\\xFE\\x2F\\x79\\x50\\x21\\x82\\x5A\\x69\\x70\\xCD\\x81\\xF0\\xC0\\x32\\x98\\x70\"\n\"\\x08\\x03\\x1E\\x03\\x0C\\xB4\\x9E\\xB4\\xA1\\x08\\x69\\x58\\xB5\\x8E\\x39\\x10\\xF7\\x30\\x40\\xA1\\x6E\\x82\"\n\"\\x27\\x50\\x54\\xB8\\x10\\xE3\\x3C\\xF5\\x65\\x0C\\x61\\x40\\x50\\x16\\xC3\\x10\\x06\\x59\\x35\\xA5\\x87\\xC4\"\n\"\\x0D\\x34\\x4C\\xA1\\x4C\\x98\\x1A\\x64\\x8C\\xEA\\x44\\x28\\x86\\xE0\\xC9\\xC3\\xA9\\x2E\\x84\\x70\\xBE\\x7C\"\n\"\\xAA\\x40\\xBA\\xE8\\x0F\\xC2\\x2A\\x84\\x7A\\xD6\\x63\\xE9\\x21\\x4B\\xA6\\x86\\x37\\x1D\\xE4\\x88\\x7B\\x3C\"\n\"\\xC8\\x25\\x42\\x3B\\x90\\x04\\xB0\\x03\\xA8\\x06\\x39\\x28\\x0F\\xB5\\x9A\\x90\\xD2\\xBA\\x2C\\x79\\x03\\xE9\"\n\"\\xAC\\x42\\x0A\\xE0\\x8F\\x5A\\x56\\x36\\xB7\\x00\\x00\\x8A\\xEE\\xEC\\xF6\\x8F\\xD1\\x1A\\x64\\x00\\xD3\\xB1\"\n\"\\xEB\\x43\\x22\\xF0\\x98\\xE0\\xC6\\x73\\xBB\\x06\\xD9\\x47\\x6E\\x87\\xEB\\xBD\\xE2\\xFE\\x71\\xB9\\x9F\\xD3\"\n\"\\x9E\\x42\\x86\\x10\\x8C\\x6F\\x2D\\x24\\xBD\\xEB\\x45\\xE8\\x6F\\x01\\x62\\x16\\xE8\\x0E\\x64\\x00\\xB3\\x60\"\n\"\\x84\\xF2\\xD6\\xF1\\x0F\\x69\\x35\\x04\\x04\\x96\\x89\\xAC\\x5D\\x98\\x94\\x10\\x1E\\x81\\xB7\\xAD\\xE3\\x15\"\n\"\\x88\\x80\\x7A\\x4B\\x90\\x76\\x05\\xD6\\x65\\x4B\\x71\\xE5\\xF7\\xAA\\xC4\\x4F\\xF8\\x02\\x60\\x27\\xDD\\x9D\"\n\"\\x48\\xA1\\xC2\\x78\\x10\\x53\\x0E\\x48\\x79\\xFC\\xF0\\x07\\x83\\x07\\x22\\x9F\\x4F\\x31\\x24\\xBC\\x03\\x29\"\n\"\\x71\\x9F\\x9C\\x68\\x10\\x65\\x18\\x98\\x6A\\xAE\\x6C\\x71\\x42\\xE1\\x8B\\x2E\\x7F\\x14\\x94\\x6C\\xB5\\x7A\"\n\"\\x2A\\x11\\xC6\\xD2\\x10\\x13\\xFD\\x23\\x18\\x8B\\x1C\\x08\\x23\\xBA\\x82\\xC4\\x86\\x9C\\x38\\x20\\x44\\x36\"\n\"\\x88\\x0E\\x52\\x5C\\x10\\x65\\x24\\x36\\x21\\x2D\\xA8\\x43\\x1D\\x7C\\x6C\\x10\\x27\\x43\\x39\\xA1\\xDC\\xF8\"\n\"\\xAF\\x42\\xC4\\x23\\xD6\\x8D\\x50\\x09\\x64\\x05\\x79\\x0D\\x9D\\x1C\\x32\\x80\\xAC\\x4C\\xD7\\x60\\x58\\xF2\"\n\"\\x23\\x69\\x0B\\x7C\\xDA\\x81\\xD0\\x2A\\xC1\\x03\\x51\\x86\\xFE\\xB6\\xEA\\x10\\x74\\x44\\x58\\x25\\xBD\\xF0\"\n\"\\x54\\xC8\\x1E\\xD3\\x66\\x84\\x14\\xCA\\x1B\\x34\\xD8\\xEB\\x40\\x36\\x50\\x87\\x1C\\x0F\\x39\\xCD\\x0F\\x19\"\n\"\\xA3\\x9E\\x03\\xA2\\x8C\\xF2\\xC6\\x99\\x28\\xFC\\x60\\xF2\\x46\\x0A\\x50\\xC1\\x05\\x06\\x85\\x84\\x0D\\x41\"\n\"\\x2C\\x43\\x82\\x40\\x67\\x85\\x18\\x19\\x4E\\x6A\\x16\\xC8\\xF7\\x10\\x0D\\x10\\xF7\\x78\\x9A\\xD1\\x00\\xD0\"\n\"\\x87\\x85\\x2D\\xF2\\xD8\\xA2\\x1D\\x04\\x04\\x4B\\xA1\\xAC\\x77\\x3C\\x9B\\x90\\xE4\\x12\\x98\\xB1\\x06\\x4E\"\n\"\\xF4\\x3F\\xE4\\x4A\\x10\\x3D\\xA9\\xB2\\xD4\\xF3\\xCC\\xEE\\x3F\\x5C\\x8B\\x10\\x0D\\xD4\\xF5\\x66\\xA8\\x1E\"\n\"\\x08\\x7C\\x39\\xCD\\x69\\xFA\\xF6\\xE3\\xD1\\x04\\x41\\x32\\x99\\x2F\\xE2\\x05\\x20\\xDA\\x27\\x21\\xD2\\x7E\"\n\"\\x07\\xB5\\x53\\x3A\\xEC\\x7F\\x5C\\x57\\x21\\xBF\\x0E\\xF6\\xB0\\xBC\\x63\\x6C\\x13\\x17\\xBA\\x21\\x8D\\x81\"\n\"\\xF6\\xB2\\x67\\xBC\\x10\\x05\\x80\\x00\\x04\\x9B\\x45\\xB1\\xA6\\xCF\\xE6\\x60\\x75\\xB3\\xDB\\xDD\\x19\\x31\"\n\"\\x01\\x23\\x00\\x31\\x92\\x56\\x1B\\xF5\\xAE\\x8F\\x09\\x30\\x75\\xFB\\x11\\x5A\\x7E\\x9C\\xDB\\xB4\\xC2\\xB5\"\n\"\\x75\\x6A\\x57\\x9B\\x10\\xEA\\xFD\\xDB\\x83\\x4B\\x19\\xF1\\xD6\\xE4\\xAD\\x90\\x17\\x4B\\xDC\\xE1\\x2A\\x99\"\n\"\\xCE\\x79\\x2F\\xC2\\x80\\xA5\\xFC\\x01\\x22\\x09\\x08\\x4A\\x07\\x11\\x62\\x58\\x86\\x00\\x85\\x76\\x8A\\x2D\"\n\"\\x70\\x43\\x32\\xF6\\x0F\\x6C\\x27\\xA4\\x78\\x1C\\x17\\x6E\\xC4\\x13\\xB2\\x01\\x2B\\xF8\\xC3\\x95\\x32\\xA7\"\n\"\\x39\\x69\\x61\\x9E\\x91\\x83\\xDD\\x59\\x23\\x7D\\x68\\x2E\\x36\\xD9\\x51\\x6F\\x81\\x34\\xA0\\x09\\x8F\\xA9\"\n\"\\xA3\\x42\\x0A\\x35\\x0B\\x10\\x44\\xCC\\x20\\x34\\x68\\x41\\x3D\\x01\\x58\\x6B\\x01\\xB6\\x20\\xAE\\x1A\\x7E\"\n\"\\x8C\\x1C\\x1B\\xE2\\xBB\\xA0\\x31\\x3D\\xDE\\x18\\x07\\xF7\\xD7\\xBB\\x2E\\xEE\\x88\\x34\\x32\\xC9\\x13\\x2D\"\n\"\\x2A\\xD6\\x19\\xF2\\x6B\\xE9\\x86\\x4C\\x50\\x4F\\x8D\\xEA\\xDA\\x7D\\xBB\\x6D\\x88\\x24\\xD5\\xEB\\x15\\x01\"\n\"\\x1A\\x3C\\xEF\\x9E\\xD0\\x03\\x90\\x3A\\xA1\\x8C\\x50\\x03\\x88\\x11\\xC2\\x83\\x4C\\x44\\x39\\x20\\x3B\\xB5\"\n\"\\x69\\x4E\\x0D\\xDF\\x53\\x81\\xF0\\xA0\\x8C\\x10\\xA9\\x4E\\x46\\x98\\xE3\\x2E\\xF4\\x12\\xAC\\xD7\\x95\\xA7\"\n\"\\x68\\x63\\x2A\\x4D\\xF1\\xCC\\x5B\\x9E\\xF3\\x0F\\xF5\\x2A\\x42\\x3E\\xDF\\x79\\xD1\\x8F\\x9E\\xF4\\xA5\\x37\"\n\"\\xFD\\xE9\\x51\\x9F\\x7A\\xD5\\xAF\\x9E\\xF5\\xAD\\x77\\xFD\\xEB\\x61\\x1F\\x7B\\xD9\\xCF\\x9E\\xF6\\xB5\\x8F\"\n\"\\x08\\x01\\xB8\\x9E\\x10\\x8E\\x35\\x04\\xF7\\x2F\\xC9\\xFD\\x45\\x03\\x80\\xFB\\xD0\\x97\\xD4\\x77\\xDF\\x5E\"\n\"\\xDD\\x2F\\x51\\x8D\\xE3\\xA5\\x3C\\x83\\xC6\\x05\\x29\\x45\\x56\\xF4\\x9A\\x90\\xB9\\x2D\\xC5\\x1B\\x42\\xBF\"\n\"\\x75\\xD5\\x78\\x5D\\x10\\xDC\\x00\\x7E\\x2A\\x9D\\x42\\x35\\xAB\\x4C\\xD3\\x57\\x82\\x5C\\xDC\\x2D\\x75\\x27\"\n\"\\xDE\\x32\\x73\\x5D\\x90\\x06\\x74\\x43\\x9B\\x19\\x15\\x0F\\x9C\\x6F\\xA5\\xC6\\x05\\xF2\\x2F\\x32\\xFF\\x80\"\n\"\\x3F\\x41\\xFC\\xE3\\x0F\\x68\\x58\\xA6\\xD9\\x01\\xB9\\x21\\x34\\x40\\x83\\x66\\x7A\\xE1\\x33\\x82\\x08\\x95\"\n\"\\x42\\x8D\\x05\\x6A\\xC5\\x3B\\x20\\x23\\x88\\xCC\\xAF\\x85\\x26\\x66\\x81\\x7E\\x08\\x88\\x12\\xE3\\xE1\\x8E\"\n\"\\xED\\x1B\\x82\\x61\\x16\\x02\\xB0\\x9D\\x08\\xE2\\x3A\\x2A\\x83\\xEF\\x10\\xAA\\x46\\xEE\\xAF\\xE0\\x78\\x68\"\n\"\\x81\\xF4\\x64\\x31\\x02\\x80\\x68\\xD2\\x0F\\x00\\xBA\\xA8\\xFD\\xF4\\x43\\x6D\\xA8\\x2A\\x37\\x00\\x62\\x11\"\n\"\\x1A\\x50\\xFB\\xD2\\xED\\x20\\x0A\\x25\\xFB\\x10\\x28\\xB7\\xD0\\x41\\x85\\xE4\\x89\\x01\\x84\\x83\\xFB\\x02\"\n\"\\x42\\x3E\\x62\\xED\\x27\\x7E\\xA1\\x32\\xBE\\xC1\\xD6\\x12\\x0A\\x04\\xD1\\x4C\\xFE\\x68\\x4B\\x85\\xF4\\xA4\"\n\"\\xBB\\x80\\xE6\\xBF\\x92\\x63\\x7D\\x6A\\xC4\\xB3\\x92\\x2B\\x04\\x0D\\x22\\x01\\x80\\x2D\\xE4\\x56\\x0D\\xEC\"\n\"\\x4E\\x03\\xCE\\xE4\\x49\\x3F\\xB4\\xC8\\x3B\\xE6\\x0B\\x20\\xA6\\x43\\x5A\\x16\\x4B\\xA3\\x94\\x70\\xD3\\x1E\"\n\"\\xB0\\x88\\xD4\\xA9\\x8B\\xE0\\x0D\\x20\\x60\\x24\\x20\\x40\\xCB\\x20\\xC4\\x83\\x88\\xCC\\x83\\xC4\\x24\\xCF\"\n\"\\x20\\xE6\\x4C\\x4A\\xBC\\x30\\x7E\\x78\\x6E\\x04\\x15\\x62\\x8C\\x18\\x0E\\x21\\x82\\x03\\x0B\\x01\\x42\\x0D\"\n\"\\x94\\xC5\\xC8\\x16\\xA1\\x5B\\x3C\\x04\\x1A\\x52\\x50\\x0D\\x98\\x4F\\x20\\xAA\\xE0\\x19\\x34\\x10\\x00\\x62\"\n\"\\x21\\x18\\xF4\\xA9\\x14\\xA0\\xC1\\x05\\x69\\xC4\\xFE\\x96\\x70\\x30\\x26\\x8D\\x3C\\xC8\\x6E\\x7D\\x40\\x4D\"\n\"\\x20\\xBE\\xCB\\x20\\x7C\\x90\\x49\\x78\\xA4\\x10\\x09\\x65\\xD1\\x70\\x84\\x35\\x4C\\x80\\x06\\xB8\\x8F\\x1F\"\n\"\\x36\\x63\\x80\\x14\\x6F\\x20\\x6A\\x84\\x3D\\xD6\\x28\\x01\\x94\\xEB\\x21\\xFA\\x20\\x0E\\xC5\\x2B\\x87\\xCE\"\n\"\\xA1\\x53\\x8E\\x4E\\x20\\xF8\\x00\\xCC\\x02\\x02\\x1D\\x6A\\x70\\x20\\x80\\x24\\x61\\x98\\x43\\x6B\\x84\\xCD\"\n\"\\x46\\x42\\x51\\x10\\x7D\\xAB\\x27\\x78\\x04\\x10\\xC4\\x4F\\x20\\x80\\xA4\\x6E\\x56\\x63\\x81\\x8E\\xE8\\x80\"\n\"\\x60\\xE1\\x1F\\x42\\x89\\x8B\\x66\\xAB\\x20\\xDE\\x6E\\xBF\\xBC\\xEB\\x1B\\x94\\x89\\xDF\\x0E\\x62\\x2E\\xEA\"\n\"\\x66\\x8D\\xF4\\xA3\\x1D\\x88\\xE0\\xF7\\x0E\\x22\\x38\\xF4\\xA8\\x1A\\x0D\\xC2\\x9B\\x0E\\xC0\\x52\\xCE\\x82\"\n\"\\x74\\x92\\x63\\xAA\\x30\\xA4\\x0C\\x01\\xA0\\x6C\\xC8\\x63\\x3A\\x3C\\xF1\\x13\\x11\\x71\\x20\\x98\\xE0\\x72\"\n\"\\x00\\xC2\\xCA\\x0C\\xA2\\x8B\\x7A\\x42\\x14\\xFA\\x41\\x01\\xF4\\x21\\xC3\\x00\\xE2\\x30\\x6C\\x43\\xE4\\x0C\"\n\"\\x02\\x01\\xFF\\x61\\x16\\xBA\\x82\\x20\\x07\\x02\\x11\\x82\\x04\\x21\\xDA\\xA5\\x51\\x04\\x4D\\x31\\xF0\\xAC\"\n\"\\x32\\xAC\\x80\\x6F\\xB4\\x6C\\x20\\x92\\xF1\\x55\\xD6\\x08\\x1F\\x3C\\xC3\\xB6\\x0C\\x62\\x2F\\x28\\xF0\\xF8\"\n\"\\x3C\\xAD\\x31\\xC6\\x30\\x78\\xF8\\x81\\x76\\x02\\xF2\\x20\\x34\\x2E\\x2A\\x1A\\xC3\\xF8\\x42\\x66\\xC2\\x12\"\n\"\\x42\\x3C\\xD0\\xE0\\x8C\\x8E\\x62\\x1F\\xCA\\x90\\x47\\xFA\\xE1\\x7E\\x08\\x80\\x68\\xAE\\x6C\\x20\\x78\\xA4\"\n\"\\x7A\\x46\\x03\\x16\\xCD\\xF0\\xC3\\x6A\\xA6\\x39\\x0E\\xA2\\x0E\\x80\\x41\\x2A\\x96\\xE4\\x20\\x46\\x4D\\x3D\"\n\"\\x58\\x08\\x63\\x1A\\x80\\x1B\\xE0\\x6E\\x1A\\xB5\\x72\\xDC\\xD4\\x2C\\x38\\x86\\x87\\x2C\\x4B\\x03\\x20\\x92\"\n\"\\x51\\x8A\\x4C\\x0C\\x32\\x70\\x68\\x8B\\x32\\xC2\\x07\\xC1\\x60\\x52\\xFE\\x84\\x1F\\xCE\\x4C\\x20\\xEC\\x0C\"\n\"\\x44\\xB2\\xC2\\x0F\\x09\\x82\\x41\\x00\\xE1\\x00\\x36\\x60\\x3A\\x56\\xAE\\x20\\xB2\\x27\\x27\\xFF\\xA8\\x65\"\n\"\\xF2\\xC1\\xC0\\xF6\\xA1\\xFF\\x00\\x00\\x1F\\x5A\\xA6\\x87\\x90\\x8B\\x37\\x14\\x42\\x0C\\x09\\x4D\\xCD\\xF6\"\n\"\\x22\\xD4\\x00\\x60\\x2E\\x22\\x4B\\x1B\\xF2\\x11\\x21\\xA8\\x44\\x19\\x17\\x42\\x1F\\x1A\\xB3\\x22\\xF6\\x21\"\n\"\\x18\\xFA\\xA1\\x3B\\x80\\x02\\xD5\\x32\\x01\\x65\\x0E\\x42\\x3C\\x58\\xD1\\x2B\\x13\\x62\\x2F\\x6A\\x31\\xD6\"\n\"\\x56\\xCC\\xD3\\x7E\\x93\\xA9\\x28\\x0D\\x0C\\xC0\\xA0\\x0E\\xFC\\x21\\x18\\x84\\xCA\\x24\\xBD\\x06\\x68\\x4A\"\n\"\\x8E\\x0D\\x4F\\x4B\\x3C\\x8C\\x92\\x20\\x34\\x6E\\x32\\xCC\\x22\\x2E\\x0F\\xA2\\x31\\x9A\\x91\\x9B\\xA6\\x83\"\n\"\\x2B\\xAD\\x31\\x21\\x98\\x63\\x08\\x3F\\x8D\\x8E\\xEC\\xA5\\x2D\\x85\\x27\\xDC\\x04\\xA2\\x2C\\x17\\x22\\x38\"\n\"\\x37\\xA5\\x1D\\xB3\\x44\\xCD\\xEE\\xC1\\x6B\\x18\\xA4\\xF1\\x9C\\x13\\xE9\\xE6\\x52\\x21\\x98\\x71\\x00\\x62\"\n\"\\x20\\x10\\x55\\xD1\\xCC\\xF6\\x29\\x28\\x62\\x43\\x22\\x17\\x62\\xCE\\x52\\xF0\\x3E\\x2C\\x28\\xD1\\xBC\\xA6\"\n\"\\x3E\\xBC\\xC3\\x8F\\xD4\\x53\\x21\\xD0\\x93\\x20\\x4C\\x00\\x04\\xEC\\x09\\x04\\x5A\\xA0\\x80\\x44\\xD3\\x01\"\n\"\\x9D\\xA7\\x89\\x30\\x32\\xFE\\x12\\x42\\x23\\x19\\x62\\x3B\\xC0\\x40\\x06\\x71\\x50\\xB0\\x8C\\xE7\\x6F\\x16\"\n\"\\xE2\\xDE\\xF2\\x4D\\x23\\xA2\\x04\\x20\\x90\\x4C\\xDC\\x6C\\xE6\\x20\\x0E\\xE3\\xCA\\xF2\\xA1\\x2D\\xDD\\xE3\"\n\"\\x12\\x7D\\xD2\\x3A\\x9D\\x72\\xE4\\xF8\\xC1\\x3A\\xED\\x42\\xEC\\x06\\xA3\\x39\\x7D\\x12\\x4F\\x1C\\xC2\\xC8\"\n\"\\xF2\\xA6\\x2D\\x7F\\xD4\\x8B\\x0E\\x82\\x39\\xB2\\x23\\x7B\\x2C\\x13\\x15\\x97\\x82\\x47\\x19\\x42\\x4F\\xEC\"\n\"\\x83\\x41\\x06\\x54\\x66\\xF6\\xB0\\x20\\x34\\x2E\\x65\\x00\\x02\\x2B\\xA2\\x13\\x56\\x24\\x63\\x21\\xF4\\xE3\"\n\"\\x80\\x98\\x00\\x14\\x43\\x46\\x20\\xFC\\xE0\\x1C\\xFF\\xD0\\xB9\\x04\\x02\\x2B\\x02\\x33\\x20\\x48\\x12\\x3C\"\n\"\\xE7\\xF3\\x20\\x4C\\x24\\x7D\\x16\\x22\\x18\\xAF\\x88\\x28\\xA6\\x03\\x84\\xDA\\x85\\x85\\x76\\x0E\\x32\\x27\"\n\"\\x22\\xCB\\x66\\xE1\\x31\\x16\\x32\\x20\\x90\\x4C\\x47\\x0B\\x42\\x40\\xFE\\xC1\\x14\\x54\\x04\\x48\\xE3\\xAD\"\n\"\\x27\\x0B\\x02\\x5D\\x78\\xCC\\x2F\\xCA\\x4E\\x3D\\xDE\\xC2\\x14\\x62\\xC9\\xFA\\xAE\\xB1\\x88\\x26\\x35\\x96\"\n\"\\x0C\\xF3\\xD8\\x10\\x23\\x88\\xFC\\xA1\\x86\\x74\\xF2\\x34\\x2A\\xC3\\x53\\xC5\\x6D\\x3A\\xEC\\x52\\x20\\xA8\"\n\"\\x47\\x47\\x38\\xC9\\x52\\x03\\x82\\xEC\\x2A\\xF4\\x21\\x9A\\xA0\\x5A\\x9A\\xAF\\x20\\xC8\\xE5\\x18\\x0D\\xC2\"\n\"\\x25\\x8B\\x29\\x17\\xCF\\x33\\x3B\\x11\\xA2\\x09\\xB0\\x24\\x80\\x10\\xA2\\x78\\xB2\\xC2\\x1D\\xA6\\x74\\xFC\"\n\"\\x2C\\x4C\\x58\\xC9\\x47\\x57\\xCD\\xB0\\x6A\\x40\\x55\\x04\\xBD\\xAB\\x53\\x28\\x49\\x1F\\xB4\\xD2\\x07\\xFF\"\n\"\\xC1\\x30\\xF7\\x62\\x4D\\x07\\x62\\xEF\\x5E\\xA2\\x25\\x1A\\x82\\x55\\x09\\x02\\x63\\xFE\\x2C\\x23\\xCC\\x29\"\n\"\\x21\\x82\\x6F\\x5C\\x75\\x8E\\x1F\\x37\\xAA\\x4C\\xDD\\xD4\\xF6\\xD8\\xF5\\x21\\x64\\xE1\\x31\\xEA\\xB3\\x5D\"\n\"\\xE5\\x15\\x22\\x1E\\xE3\\x19\\x8A\\x75\\x5E\\xF1\\x95\\x20\\x0E\\x60\\xF8\\xF2\\xB5\\x5F\\xFD\\xF5\\x5F\\x01\"\n\"\\x36\\x60\\x05\\x76\\x60\\x09\\xB6\\x60\\x0D\\xF6\\x60\\x11\\x36\\x61\\x15\\x76\\x61\\x19\\xB6\\x61\\x01\\x62\"\n\"\\x26\\x18\\x82\\x5F\\x1D\\x76\\xA2\\xB6\\x91\\xAA\\x9C\\x54\\x50\\x2B\\xC3\\x5B\\x01\\xA2\\x50\\xD6\\x75\\xA2\"\n\"\\x74\\xAA\\x61\\x0F\\x09\\x29\\xA9\\xC6\\x56\\x7F\\xE2\\x31\\x08\\xB5\\xA2\\x9C\\xC6\\x03\\xF1\\x35\\x64\\x7F\"\n\"\\xAE\\xBF\\xDA\\x61\\x56\\x09\\x82\\x14\\x54\\x6E\\xA3\\x76\\x48\\x61\\x59\\x16\\xA1\\x14\\x41\\x1D\\x05\\x82\"\n\"\\x06\\xAC\\x89\\x20\\x24\\x91\\xC6\\x2A\\x91\\x46\\x49\\x24\\x20\\x86\\x76\\x20\\xD2\\x8B\\x43\\x3E\\xD2\\x43\"\n\"\\xDC\\xCB\\x20\\xD4\\xE0\\x1B\\xDE\\xE1\\x1B\\x22\\x87\\x51\\x01\\xA2\\x19\\x42\\x09\\x10\\x9C\\xF6\\x1D\\xAA\"\n\"\\xB2\\xA6\\x9C\\x56\\x16\\x0E\\xE0\\x17\\xA4\\x16\\x00\\x9A\\x81\\xF1\\xDC\\xE1\\x1D\\xB8\\x36\\x54\\x9E\\x01\"\n\"\\x1A\\xBE\\xE1\\x44\\x0F\\xA2\\x19\\x6C\\x0A\\x6A\\x4D\\x01\\x66\\x97\\x03\\x39\\xA1\\x36\\xAE\\xBA\\xE1\\x1D\"\n\"\\xC2\\xF2\\x4C\\xCD\\x32\\x20\\x12\\x20\\x18\\xA0\\x01\\xC4\\x8E\\x76\\x16\\x44\\x04\\x21\\xB8\\x65\\x16\\x96\"\n\"\\xD6\\x20\\x1A\\x34\\x20\\x1A\\x23\\xC1\\x82\\xF1\\xE8\\x70\\xC3\\x26\\x45\\x51\\x20\\x28\\x26\\x9C\\xAA\\x86\"\n\"\\x4F\\x01\\xA0\\x50\\xB2\\x84\\x72\\xF9\\x01\\x51\\x1D\\x66\\x75\\xA0\\xB5\\x88\\xDA\\xEE\\x48\\xB3\\x64\\x49\"\n\"\\x13\\x08\\x61\\xBA\\xAE\\x6A\\x32\\x34\\x6F\\x41\\xA5\\xBA\\xDC\\xB1\\xE1\\xFA\\x67\\x25\\x73\\x4E\\xC9\\x7E\"\n\"\\xE5\\x14\\x07\\x02\\x68\\xF0\\xD0\\x47\\x51\\xF7\\x71\\x09\\xC2\\x52\\x0E\\x40\\x11\\xFC\\x61\\x03\\x1A\\xE0\"\n\"\\x77\\xED\\x11\\x20\\xBA\\xA8\\xFA\\x00\\x22\\x00\\xB4\\xF5\\x59\\xA9\\x83\\x36\\x1A\\xCD\\x78\\x00\\xA0\\x33\"\n\"\\x84\\xB1\\xFB\\xC0\\x82\\x00\\xCC\\x04\\x1C\\xFF\\xC1\\x23\\x08\\x40\\x2D\\x2D\\x6C\\x3A\\xD6\\xE5\\x00\\xD4\"\n\"\\xB2\\x1C\\xEF\\xB2\\x27\\x02\\xA5\\x35\\x0A\\xE0\\x88\\x72\\xE8\\x66\\x03\\x80\\x41\\xB0\\x35\\x20\\x30\\x46\"\n\"\\x52\\xBC\\xA6\\x1F\\x2F\\x85\\x85\\x82\\xF3\\x00\\x4C\\xC1\\x73\\x64\\x57\\x20\\x7C\\x50\\x47\\xBA\\x28\\x7D\"\n\"\\x9F\\xA4\\x81\\x1A\\x2B\\x21\\x6A\\x64\\x0E\\x1A\\x62\\x3A\\xC4\\x0E\\x3A\\xFD\\xEF\\x79\\xC9\\x17\\x20\\x34\"\n\"\\x0E\\x11\\x6B\\xC4\\x42\\x0E\\x91\\xB6\\x34\\x44\\x3C\\xC4\\xC5\\x4F\\xCC\\xA8\\x1F\\x8E\\x0A\\x11\\xBC\\x26\"\n\"\\x64\\x97\\x88\\x68\\x5C\\x91\\xB8\\xD4\\x6C\\x8D\\x82\\x13\\xC9\\x20\\xE5\\x7B\\x42\\x34\\x46\\x03\\x62\\x3B\"\n\"\\xBE\\x76\\x7F\\x35\\x48\\xD9\\x6A\\xC4\\x1D\\x36\\x40\\xCD\\xF6\\x81\\x48\\x01\\x62\\x2E\\x0A\\x06\\x40\\xBD\"\n\"\\x4B\\x58\\xB2\\xA1\\xFD\\xEE\\x52\\x4E\\xD3\\x81\\x66\\xBE\\xA3\\x36\\x38\\x58\\x6A\\x3A\\x2D\\x5C\\xBC\\x83\"\n\"\\x11\\x8A\\xF0\\x74\\x7F\\x18\\x6E\\x8E\\xEF\\x4F\\x42\\xA1\\x32\\x08\\xAB\\x0F\\xEA\\x65\\x2F\\xA4\\x84\\x37\"\n\"\\x8B\\x08\\x42\\xF8\\x77\\xBC\\xDA\\x45\\x4B\\x66\\x01\\xF0\\xF2\\x10\\xE7\\x54\\x09\\x82\\x1D\\x58\\x20\\x16\"\n\"\\x34\\x3C\\x79\\x2D\\x8C\\x21\\x97\\x8A\\x23\\xB8\\x0D\\x83\\x78\\x8A\\x15\\x82\\xFC\\x68\\x2D\\x5F\\x58\\x48\"\n\"\\x84\\x2F\\x13\\x94\\x00\\x60\\x19\\x70\\x58\\x20\\x94\\x60\\x66\\x4D\\x4D\\x2B\\x51\\x58\\x43\\x17\\xC2\\x0A\"\n\"\\x82\\x01\\x95\\x70\\x4D\\x8D\\x71\\xAE\\x6E\\x7C\\xD8\\xB7\\x1E\\x8E\\x8C\\x65\\x24\\xC5\\x10\\x19\\x77\\x19\"\n\"\\xF9\\xD3\\xD0\\xD8\\xC8\\x42\\xD6\\x33\\x12\\xEE\\x4D\\xF1\\x16\\x00\\xC4\\x83\\x0A\\xCE\\xA8\\x09\\xD2\\xA1\"\n\"\\x3B\\xF2\\xA1\\x0C\\x83\\x63\\x32\\x68\\x25\\x7D\\xBB\\x73\\x94\\x87\\xF1\\x21\\x04\\x40\\x06\\x17\\xF2\\xA0\"\n\"\\xEA\\x37\\x83\\x68\\x4B\\x58\\x16\\x19\\x8E\\x0D\\x94\\x74\\xF6\\xB8\\x94\\xAD\\x11\\x92\\x29\\xE9\\x27\\x01\"\n\"\\xE0\\x8E\\x8D\\xD8\\x2D\\xDD\\x38\\x21\\x82\\x23\\x0D\\x68\\xE0\\x1F\\x0E\\x60\\x12\\xF8\\x21\\x63\\x3A\\xD6\"\n\"\\x34\\x01\\x20\\x0E\\x54\\x13\\x81\\x88\\xA8\\x8A\\x55\\x16\\x00\\xD0\\x01\\x16\\x0F\\xEA\\x6E\\x02\\x82\\x95\"\n\"\\x6B\\x18\\x8C\\xEB\\xE5\\x83\\xEC\\x85\\x87\\xCD\\xF8\\x88\\x51\\xC3\\x96\\xCD\\xB3\\x72\\x5F\\x32\\x54\\x91\"\n\"\\xF8\\x20\\xF4\\x01\\x18\\x32\\xC1\\x47\\x64\\x00\\x71\\x54\\xD2\\x20\\xE6\\xC2\\x0A\\xB6\\x41\\x2B\\x81\\x82\"\n\"\\x49\\x68\\x38\\xDE\\x9A\\x95\\x21\\x8E\\xE6\\x52\\x17\\x22\\x39\\x5C\\x0E\\x00\\x90\\x0C\\x1C\\x55\\x08\\x43\"\n\"\\x4E\\x16\\x00\\x10\\x70\\xC4\\x8A\\x62\\xA0\\x47\\x99\\x62\\x26\\x49\\x46\\x2E\\xF8\\x96\\xF1\\x42\\x3C\\xEA\"\n\"\\x98\\x9C\\x2B\\x19\\x00\\xF4\\x64\\x45\\xCC\\x62\\x29\\xEE\\x99\\x4B\\x97\\x42\\x94\\xA7\\x02\\x06\\x01\\x80\"\n\"\\x5C\\x34\\x68\\x2E\\xD0\\xAE\\x21\\xC2\\x14\\xA1\\x0F\\x0A\\x1F\\x01\\x43\\x75\\xA9\\x97\\x3C\\xA8\\x67\\x5D\"\n\"\\x93\\xCB\\xA3\\xC9\\xA5\\x63\\x67\\x99\\x97\\x6B\\xF9\\x69\\x48\\x0E\\x89\\x5B\\xC1\\x4C\\xDD\\x79\\xBC\\x0E\"\n\"\\x09\\xC2\\xD4\\x66\\xCE\\x22\\x7A\\x20\\x2A\\x3A\\xA3\\x91\\x71\\x29\\x66\\xA1\\x1D\\x5E\\x77\\x20\\x2E\\xDA\"\n\"\\x1D\\x4C\\xE1\\x1B\\xB2\\x96\\x78\\xA0\\x61\\x16\\x9A\\x7A\\x29\\x12\\xB2\\x8C\\x1B\\x62\\x89\\xFF\\x61\\xFF\"\n\"\\x92\\xBA\\x3C\\x3A\\x75\\x29\\x26\\x79\\x20\\xE8\\x34\\x13\\x54\\x24\\x5E\\xE3\\xA9\\x9B\\x69\\xF9\\x9B\\xBD\"\n\"\\x66\\xCE\\xBE\\x61\\x16\\xBC\\xB7\\xAC\\xB1\\x29\\xCF\\x14\\x82\\x5E\\x3A\\x98\\x92\\x52\\x8B\\x4D\\x1A\\x63\"\n\"\\x83\\x01\\x42\\x3C\\x76\\x39\\x06\\xB5\\x84\\x07\\x2A\\x76\\x20\\x28\\x28\\x2B\\xA8\\x77\\x58\\x09\\xAF\\x3C\"\n\"\\x2E\\x16\\x13\\x98\\x02\\x04\\x52\\xD1\\xB7\\xD4\\x40\\xB6\\xC8\\x28\\x21\\x1C\\xFB\\x44\\xB4\\x18\\x0F\\xB7\"\n\"\\x6B\\x46\\x1A\\xCA\\xC8\\x1A\\xE0\\xE2\\x28\\x57\\xFC\\xE6\\x62\\xAF\\x99\\xD1\\x85\\x2F\\x16\\x26\\x64\\xE2\"\n\"\\x21\\xBC\\x49\\x62\\x83\\x0F\\x62\\x54\\xE2\\x62\\x1A\\xF9\\xD8\\x00\\x98\\x00\\x24\\x96\\x90\\x82\\x97\\x9C\"\n\"\\xBC\\xE4\\x99\\x11\\xE2\\x35\\x02\\x95\\x60\\x6D\\x07\\x29\\x57\\xAA\\x1B\\x82\\xA1\\x2F\\x96\\x42\\x59\\x0B\"\n\"\\x36\\xB7\\x7F\\x6E\\xA5\\x46\\xD7\\x1F\\x5E\\x35\\x60\\x8B\\x82\\x4F\\x93\\x3B\\xF5\\x20\\x46\\x01\\x26\\xB6\"\n\"\\x9F\\x94\\xD5\\x9F\\x9E\\x7B\\xBA\\xA9\\xBB\\xBA\\xAD\\xFB\\xBA\\xB1\\x3B\\xBB\\xB5\\x7B\\xBB\\xB9\\xBB\\xBB\"\n\"\\xBD\\x1B\\xA5\\x84\\xEF\\xBB\\x33\\xEA\\xAF\\x33\\x62\\xFA\\xB6\\xFA\\x22\\xC8\\x1B\\x22\\xD2\\xDB\\xBA\\x75\"\n\"\\x9B\\x21\\xF6\\xCD\\x43\\xDC\\xA1\\x35\\x2F\\xA2\\xBD\\xDD\\xDA\\xBB\\xE9\\x9B\\xE2\\xE4\\xF4\\x25\\xEE\\xDB\"\n\"\\xAA\\xED\\x7B\\xB8\\x49\\x0C\\x27\\x90\\x62\\xBF\\x6F\\x97\\xBB\\xF9\\x41\\x0D\\x88\\xC0\\x6D\\xE1\\x36\\x20\"\n\"\\xB8\\x82\\x6C\\xBB\\xF6\\x6B\\xE1\\xA4\\x21\\x78\\x40\\x72\\xBE\\x21\\x13\\xC2\\x55\\x6B\\x43\\xA4\\x02\\xF4\"\n\"\\x41\\x83\\x36\\xC0\\x14\\x24\\xB0\\x67\\x7D\\xEB\\x0B\\x4C\\xC0\\x1D\\xBE\\xA1\\x6C\\x0F\\x22\\x02\\xA0\\x16\"\n\"\\x6A\\xA1\\xA1\\xB0\\xFF\\x95\\xFC\\x98\\x02\\xE2\\x14\\xA8\\x9B\\x1A\\x60\\x77\\x7B\\xF7\\x77\\x2B\\xE5\\x20\"\n\"\\x6E\\xC8\\x33\\x12\\x1C\\xC2\\x36\\xD7\\x20\\x80\\x26\\x4B\\x48\\x76\\x59\\x9D\\xEA\\x36\\x3B\\xE5\\xB8\\xDB\"\n\"\\x55\\x7B\\x01\\x80\\x7B\\xC9\\xF1\\x28\\xFF\\xE1\\x37\\x36\\xE0\\x31\\xC4\\x45\\x72\\x3B\\x85\\x4F\\x07\\xC0\"\n\"\\xC3\\xE6\\x47\\x00\\x62\\x41\\x3F\\x7F\\x94\\x08\\x9A\\xF7\\xBC\\x4D\\xED\\x1F\\x02\\x2A\\xB6\\x97\\xF5\\x17\"\n\"\\x82\\x6F\\x7A\\x0D\\x51\\x2A\\x02\\x85\\x72\\xFB\\xF5\\x46\\xF3\\x5A\\x18\\x17\\xB8\\xC8\\xE2\\x70\\x08\\x4C\"\n\"\\x61\\x9A\\x0E\\x35\\x13\\x32\\xC1\\x14\\xDA\\x3A\\x3C\\xD6\\x12\\x43\\x10\\x91\\x80\\x6D\\x88\\xCD\\xBB\\x70\"\n\"\\x8D\\x93\\x24\\x81\\x1D\\xEB\\x79\\xFB\\xB5\\x87\\x71\\xA6\\x89\\xEA\\xA6\\x46\\x34\\xA8\\x66\\xDF\\x11\\xCC\"\n\"\\x02\\x80\\x26\\xA2\\x19\\x73\\x64\\x38\\x20\\xEA\\x79\\x20\\xE6\\xA2\\xAA\\x5B\\x79\\x3C\\x3D\\x6D\\xB1\\x71\"\n\"\\xDB\\xAC\\xBD\\x67\\x0F\\x7D\\x30\\x85\\x8B\\x4B\\xC7\\x83\\xFC\\xD3\\xBB\\x58\\x18\\x81\\x24\\x44\\xBD\\xAB\"\n\"\\x65\\x16\\x39\\x11\\x77\\x86\\xD0\\xF3\\x75\\xA6\\x9D\\xD1\\x89\\x2A\\x9D\\x96\\xDF\\xED\\xC4\\xA1\\xB6\\x0C\"\n\"\\xEB\\xB7\\x90\\x09\\x82\\x39\\x88\\x9C\\x1F\\x0E\\x59\\x00\\xDD\\x02\\x6A\\x61\\x7D\\x65\\x3D\\xDD\\x68\\x55\"\n\"\\xD3\\x8B\\x25\\x9A\\x73\\x55\\xFD\\xD3\\xEB\\xC6\\x9A\\x4D\\x3D\\x80\\x5D\\xB9\\x5E\\x6A\\xC4\\x1B\\x9C\\xDB\"\n\"\\xB9\\x04\\xDC\\xF5\\x64\\x1D\\xB5\\xC4\\x54\\x61\\x08\\x5D\\xD9\\xB4\\x79\\x21\\xA8\\x19\\x20\\xA0\\x7D\\xD6\"\n\"\\x7F\\x9C\\xAA\\xA6\\x1D\\x73\\xBE\\xC7\\x7B\\x15\\xDD\\x60\\xB7\\x5D\\x20\\x18\\x04\\x13\\x1A\\xC0\\xB1\\x45\"\n\"\\xFD\\xB4\\x82\\x72\\x9F\\xFF\\xA1\\x9F\\xFF\\xD9\\x20\\xEE\\x7D\\x21\\x2A\\x93\\x0E\\xFB\\x61\\xA0\\xC3\\x3D\"\n\"\\x97\\x8B\\x7D\\x5E\\xDF\\x3D\\x20\\x36\\xCC\\xA8\\x6F\\x6E\\xD9\\x9F\\xC3\\x32\\x5E\\x15\\xA5\\x2F\\x64\\x3A\"\n\"\\xD6\\xC7\\x2C\\x7A\\x57\\x3A\\xB4\\xA7\\xA5\\x8F\\x6C\\xD5\\x0E\\x40\\xE2\\xDD\\xFD\\xD8\\x97\\x05\\x10\\x32\"\n\"\\x81\\x07\\x1A\\xE0\\xDB\\xC7\\x2B\\x19\\x0F\\xD5\\x14\\xFE\\xD8\\xC2\\xB0\\xFA\\x70\\xB8\\xFC\\x86\\x2E\\xD0\"\n\"\\x7C\\xB2\\x77\\x29\\xD0\\xD6\\xAB\\xCD\\xB9\\x98\\x66\\x41\\xB0\\x0D\\x56\\xFC\\xD6\\x5B\\x20\\xF2\\xB3\\xDE\"\n\"\\x19\\x42\\x0D\\x7E\\x67\\x06\\x01\\x00\\xB1\\x5D\\x67\\xBD\\xC3\\x2A\\x2B\\xB2\\xB7\\xB1\\xB5\\x44\\x3E\\x85\"\n\"\\x89\\x98\\xDA\\x01\\xC3\\x43\\x5B\\x61\\x07\\xA0\\x78\\x88\\x9C\\x21\\xFA\\x11\\x62\\x75\\xAF\\xC2\\xEF\\xD1\"\n\"\\xB5\\x19\\xC2\\x9B\\xAC\\x5E\\xEB\\xAB\\x1B\\x72\\xA4\\xDA\\x32\\xF0\\x5A\\xBC\\x19\\x8D\\xD4\\xB9\\xCD\\xEC\"\n\"\\x47\\xAF\\x5C\\xC1\\x5C\\xED\\xDD\\xFE\\xED\\xE1\\x3E\\xEE\\xE5\\x7E\\xEE\\xE9\\xBE\\xEE\\xED\\xFE\\xEE\\xF1\"\n\"\\x3E\\xEF\\xF5\\x7E\\xEF\\xF9\\xBE\\xEF\\xFD\\xFE\\xEF\\x01\\x3F\\xF0\\x05\\x7F\\xF0\\x09\\xBF\\xF0\\x0D\\xFF\"\n\"\\xF0\\x11\\x3F\\xF1\\x15\\x7F\\xF1\\x19\\xBF\\xF1\\x1D\\xFF\\xF1\\x21\\x3F\\xF2\\x25\\x7F\\xF2\\x29\\xBF\\xF2\"\n\"\\x2D\\xFF\\xF2\\x31\\x3F\\xF3\\x35\\x7F\\xF3\\x39\\xBF\\xF3\\x3D\\xFF\\xF3\\x41\\x3F\\xF4\\x45\\x7F\\xF4\\x37\"\n\"\\x4A\\xF8\\x68\\x9B\\xAB\\x7A\\x6F\\x24\\x20\\xA6\\xED\\x1D\\x8A\\x7F\\x4C\\xD7\\x6F\\x4E\\x53\\x20\\x1A\\x23\"\n\"\\x21\\x83\\x51\\xAB\\x02\\x80\\x34\\x6C\\x8B\\x22\\xAF\\x06\\x2A\\xAA\\x48\\xD1\\x0A\\xE2\\xD0\\x68\\xDA\\x91\"\n\"\\xAF\\x85\\xD4\\xB3\\x24\\xA8\\x01\\x02\\x76\\xB2\\xC4\\x15\\xC9\\xEF\\x2D\\x78\\xC0\\x10\\x65\\xC1\\x33\\xB4\"\n\"\\x9C\\xB6\\xB2\\x82\\xF9\\x9D\\x1F\\xFA\\xE3\\x2D\\xBF\\xD3\\xD8\\xCD\\xAB\\x5A\\x1B\\x8C\\x7F\\xE7\\xF7\\x67\"\n\"\\x01\\x0B\\x70\\x29\\x42\\xB0\\x31\\x82\\xEB\\x88\\x9A\\x6F\\x28\\x69\\xAC\\x28\\x15\\x2C\\x76\\x93\\x6C\\x17\"\n\"\\x84\\x0C\\x55\\x03\\x59\\xF8\\x6D\\x3D\\x86\\xC1\\xDF\\x2D\\x80\\xC8\\xF8\\x6F\\xE8\\x1B\\x50\\xFE\\x08\\x33\"\n\"\\x34\\x28\\x80\\x28\\x2B\\x9C\\x01\\x08\\x28\\x30\\x60\\x03\\x7F\\xFF\\xFC\\x99\\x82\\xF6\\xEF\\x1F\\xA6\\x81\"\n\"\\x0E\\xF9\\xFD\\x7B\\xF7\\x6E\\xE1\\x3F\\x80\\x0E\\x09\\x1A\\x44\\xA8\\xF0\\x1F\\xA9\\x8B\\x00\\xCE\\xFC\\xEB\"\n\"\\x77\\xF1\\x8C\\xBF\\x00\\x0E\\x41\\xF2\\x73\\xA8\\xE3\\xA0\\xC9\\x8B\\xFC\\xE8\\x78\\x8C\\xE9\\x31\\xDD\\xBF\"\n\"\\x19\\x17\\x0B\\xF8\\x13\\x39\\x50\\xC9\\xBF\\x4B\\x1E\\x13\\xFD\\x5B\\x24\\xB0\\x40\\x3F\\x7F\\x09\\x2E\\x2E\"\n\"\\x2B\\x39\\xF2\\x1F\\x08\\x87\\x5E\\x6A\\x5E\\xD4\\xA6\\x73\\x20\\xC9\\x96\\x54\\x95\\xCA\\x7C\\x29\\x33\\x60\"\n\"\\x82\\x83\\x2D\\xB6\\x0E\\xD4\\x1A\\x10\\xC4\\xBE\\x9E\\x1E\\xB5\\x31\\x14\\x08\\xA2\\xDF\\x3F\\x16\\x31\\xC5\"\n\"\\x02\\x20\\x6B\\x36\\xEA\\xBF\\x52\\x6A\\xD9\\xBA\\x3D\\xB9\\xF0\\xCB\\x49\\xAC\\x02\\x41\\xFE\\x1B\\x32\\x10\"\n\"\\x1F\\x4B\\x8F\\x70\\xC1\\x7A\\xA4\\x52\\x31\\xA6\\xA8\\xC0\\x83\\xFF\\x31\\xF0\\x38\\x80\\x9F\\xD1\\x80\\x94\"\n\"\\xFE\\xFD\\xF1\\x28\\xC7\\xEF\\x5F\\x7F\\x03\\x1C\\x7E\\xC0\\xEC\\x30\\x00\\xBF\\x6E\\x23\\x39\\x07\\xAC\\xBA\"\n\"\\xF5\\xB0\\x47\\x9E\\x55\\x10\\x0B\\x3C\\x1C\\x40\\x9F\\x3F\\x03\\x0E\\x4B\\x2C\\x1E\\x18\\xDA\\xB4\\x61\\x98\"\n\"\\x02\\x67\\xD7\\x76\\x08\\xE2\\x1F\\x37\\xD0\\xFF\\x78\\x53\\x5D\\xD8\\xCF\\xEA\\x47\\xD4\\x80\\xA7\\x0E\\x59\"\n\"\\x88\\x3A\\x20\\x6B\\xD8\\x01\\x27\\xFB\\x8B\\xEC\\x91\\xC1\\xBF\\x94\\x01\\x57\\xC6\\x92\\xF9\\x34\\x3C\\xF7\"\n\"\\xE5\\x1E\\x55\\xF7\\x65\\x0E\\x60\\x40\\x3F\\xE4\\x01\\x35\\x88\\x4E\\x7F\\x5A\\xFD\\x43\\xDF\\x32\\xE5\\xFC\"\n\"\\xFB\\x60\\x1D\\x00\\xEB\\x38\\x4C\\x1D\\x22\\xF2\\x9F\\x43\\xBD\\x54\\xE6\\x92\\x7D\\x01\\xF9\\xD7\\xD4\\x40\"\n\"\\x40\\x29\\x38\\x10\\x81\\x47\\x51\\xD5\\x0F\\x18\\xF1\\xA5\\xE6\\x5C\\x3F\\x80\\xFC\\xF3\\x1A\\x00\\xF9\\xB8\"\n\"\\xC3\\xC8\\x74\\xFC\\x1D\\xB8\\x1F\\x00\\x8D\\x85\\xE8\\x50\\x25\\xFF\\x30\\x11\\x50\\x3E\\xD9\\x6D\\x95\\xCF\"\n\"\\x3F\\x11\\x34\\xA6\\xE1\\x69\\x02\\x45\\x70\\x40\\x40\\x5E\\x4C\\x87\\x0E\\x67\\x5D\\x40\\x25\\x9F\\x8F\\x6F\"\n\"\\x95\\xE8\\xD0\\x0C\\x73\\xC1\\xC6\\xDA\\x24\\x02\\x0A\\xB4\\xCC\\x54\\x03\\xF1\\x58\\x42\\x6F\\x0E\\x1D\\xD9\"\n\"\\x60\\x40\\x4A\\x7A\\xD4\\xE4\\x49\\xFD\\x08\\x90\\x4D\\x81\\xCD\\xA9\\x77\\x46\\x3F\\x07\\xE4\\x23\\x12\\x4F\"\n\"\\x43\\x50\\xF1\\x61\\x75\\xB0\\xC1\\xB7\\xA4\\x47\\x38\\xF9\\x03\\x80\\x19\\x44\\xC6\\xB4\\xD2\\x42\\xDE\\x9D\"\n\"\\xF7\\x4F\\x05\\x00\\x84\\xC6\\x4E\\x40\\xAE\\x4C\\x07\\x94\\x06\\x03\\xED\\xB2\\x65\\x67\\xF4\\xA1\\x07\\x24\"\n\"\\x58\\xEC\\xFD\\x03\\x06\\x7D\\x4F\\x0E\\x74\\xE2\\x9F\\x03\\x29\\x33\\x1D\\x48\\x52\\xC6\\x16\\xA2\\xA3\\x0E\"\n\"\\x45\\x4A\\x28\\x92\\x15\\xE2\\xC9\\xD1\\xA0\\x7D\\x01\\xC0\\x13\\x20\\xEC\\x88\\x64\\x86\\x99\\x41\\x22\\x46\"\n\"\\x93\\x4D\\x60\\xE1\\xF7\\x8D\\x3F\\x9E\\x21\\x86\\x56\\x8F\\x9A\\xFD\\x87\\x46\\x61\\x49\\xD1\\x37\\x64\\x1A\"\n\"\\x03\\xE9\\x43\\xE7\\x55\\x84\\x7E\\x58\\x29\\x62\\x3B\\x50\\xF4\\x4D\\x26\\x3C\\xAC\\x76\\xE0\\x70\\x6A\\x02\"\n\"\\x90\\xE9\\x52\\x94\\x52\\xA7\\x6C\\x48\\x17\\x39\\xAB\\x17\\xA5\\xAA\\x29\\xF3\\x0F\\x05\\x15\\x76\\xA9\\x94\"\n\"\\x3E\\x0B\\xBD\\x56\\x68\\x58\\xA8\\x6E\\xA5\\x98\\x45\\x88\\xB9\\x88\\x22\\x6C\\xAD\\x2C\\xA4\\x9D\\x47\\x2C\"\n\"\\xFC\\xF3\\x67\\xB6\\xF9\\x35\\xAB\\xE7\\x4D\\xFD\\x9C\\x0B\\x9F\\x4F\\xF3\\xF1\\x9B\\x15\\xB9\\x03\\x6D\\x10\"\n\"\\x0C\\x45\\x21\\x7D\\x66\\xD8\\x1F\\x01\\x10\\xD0\\x80\\x1A\\x0B\\xA5\\xE8\\xD0\\x2B\\xFF\\xD8\\x66\\xAD\\xC1\"\n\"\\x08\\x2B\\xCC\\xF0\\x45\\x0F\\x47\\x9C\\xDC\\xB5\\x4A\\x51\\x90\\x9B\\xB8\\x5C\\x02\\xB0\\xC4\\xB4\\x20\\x1B\"\n\"\\x28\\xE2\\x7A\\x45\\xB9\\x0B\\x56\\xC7\\xBF\\xC0\\x06\\x01\\x45\\xE1\\xC5\\x04\\xDF\\x6B\\xFC\\xD4\\xA1\\xCF\"\n\"\\x1C\\x1B\\x16\\x77\\x16\\x56\\xB6\\xE6\\xF5\\xE3\\xA7\\xFE\\x8A\\x48\\x80\\x09\\xDD\\xFC\\xD3\\x4E\\x4C\\x65\"\n\"\\x0D\\xFC\\x4F\\x90\\x4A\\x6A\\x0A\\x2D\\x00\\x48\\x0F\\xBC\\xB4\\x79\\x12\\xFF\\x1A\\x50\\x63\\x4E\\x7E\\x8C\"\n\"\\x1E\\x08\\x0D\\x70\\xCB\\xE8\\x7E\\x24\\x8A\\xB8\\xCF\\xAE\\x88\\x65\\x6B\\xC5\\x36\\xF4\\x7A\\x44\\x1A\\x1A\"\n\"\\x11\\xBC\\xD8\\x4A\\x71\\x67\\x02\\xC0\\x73\\x40\\xDA\\x7C\\x48\\x92\\x47\\x38\\x2E\\x2A\\xAC\\xC9\\x00\\xD0\"\n\"\\xF4\\xE8\\x43\\xEE\\xCC\\x12\\xCC\\x2C\\x07\\xC5\\x54\\xAD\\xC6\\x86\\x01\\x2E\\x78\\x1D\\x11\\x14\\x2E\\xE9\"\n\"\\xA6\\x24\\x1F\\xE0\\x8F\\xD1\\xA6\\x76\\x0B\\xEC\\xA2\\x70\\xC7\\x14\\x1A\\xB3\\x60\\x61\\x2E\\x10\\x6E\\x46\"\n\"\\xC7\\x70\\x5C\\x4C\\xA4\\xA5\\x51\\x85\\x48\\x53\\xF4\\xD3\\xC0\\x3E\\xA8\\xB2\\xED\\x53\\xE4\\x2C\\xD7\\xC9\"\n\"\\xB8\\x43\\xA2\\x04\\x1B\\xED\\xDE\\x00\\xAC\\xD4\\xF0\\x43\\x63\\x03\\x70\\xA2\\x8C\\x90\\x62\\x65\\x15\\x48\"\n\"\\xFA\\xB9\\xC4\\xFB\\x56\\x86\\xFF\\xF5\\x78\\xA1\\x01\\xCE\\x50\\x66\\xE5\\xFD\\xD6\\x27\\xA2\\xAA\\x26\\x77\"\n\"\\x1E\\x10\\x4D\\x79\\x65\\xF3\\xCF\\x0E\\x31\\x61\\xF3\\x0C\\x30\\x00\\x75\\x5C\\xC7\\x3F\\x4E\\xC6\\x94\\xCE\"\n\"\\xE9\\x8E\\x79\\x64\\x2B\\xF9\\x03\\x61\\x53\\x3B\\x88\\xB7\\x77\\xEC\\x87\\xD7\\x2E\\xFB\\x2A\\x90\\xAD\\x82\"\n\"\\x05\\xD0\\x8F\\x6F\\xEA\\x9C\\x0A\\xDB\\xFD\\x17\\xE1\\xC3\\x39\\x7E\\x21\\x4D\\x3B\\x00\\x21\\x40\\xCB\\x79\"\n\"\\x0D\\x31\\x8A\\x81\\x9D\\x88\\xAA\\x17\\x9D\\x9C\\x75\\x6A\\x73\\x00\\xE8\\xC5\\x5E\\x02\\xF2\\xAD\\x78\\xC9\"\n\"\\xC4\\x56\\x2D\\x60\\x46\\xB0\\xA2\\xD3\\x91\\x81\\x44\\x4E\\x82\\x7A\\x33\\x19\\x50\\x7A\\x36\\x2E\\x48\\xB5\"\n\"\\xE5\\x22\\x1D\\x33\\xDA\\xFB\\xE0\\x75\\xAE\\xE8\\x21\\x66\\x85\\x0E\\x71\\x21\\xF4\\x3E\\x22\\x9D\\xE7\\xF9\"\n\"\\x6C\\x84\\x60\\x21\\x8A\\xA0\\xAC\\x53\\xBD\\x6F\\xF9\\x0D\\x00\\xBB\\xF8\\x07\\x5F\\x96\\x62\\xA7\\x80\\x0C\"\n\"\\xB1\\x76\\x09\\x30\\x88\\xA7\\x64\\x52\\x16\\x30\\x08\\x44\\x01\\xDC\\x20\\x22\\xE7\\xFE\\x15\\x10\\xF5\\x34\"\n\"\\xE1\\x20\\x19\\x3B\\xA1\\x40\\x56\\x90\\x1B\\x87\\x64\\xAF\\x14\\x04\\x10\\x5B\\x04\\xF0\\x62\\x28\\xD8\\x64\"\n\"\\xAF\\x21\\x01\\xD9\\x80\\x19\\x73\\xF8\\xAD\\x03\\xD6\\x50\\x87\\x5B\\x01\\xCC\\x37\\x24\\x62\\xC7\\x77\\x4C\"\n\"\\xED\\x8C\\x31\\xC1\\x0F\\x03\\x03\\xE2\\x32\\x58\\x09\\x69\\x64\\x00\\x50\\x0C\\x0B\\x65\\x42\\x41\\x0C\\xCA\"\n\"\\x84\\x58\\x07\\x31\\x85\\xC0\\x8A\\x86\\x98\\xEA\\xC1\\xE7\\x1D\\xD0\\x98\\x85\\x29\\xDC\\xB1\\x10\\xC1\\x24\"\n\"\\x10\\x00\\x84\\x91\\xDD\\x40\\x0A\\x92\\xB4\\xB4\\xE8\\x11\\x2C\\x11\\xC8\\x48\\x42\\x16\\x62\\x97\\x38\\xF2\"\n\"\\x04\\x8E\\x39\\x0C\\xC8\\x3E\\xFC\\x71\\x47\\x89\\xE4\\x31\\x79\\x9F\\x54\\x4E\\xDE\\x58\\x69\\xBC\\x8B\\xD0\"\n\"\\x26\\x65\\x01\\x39\\x51\\x11\\x07\\xC2\\x36\\x06\\xB2\\x0D\\x66\\x32\\x09\\xCD\\x0B\\x63\\x52\\x01\\x60\\x50\"\n\"\\xC4\\x1F\\x50\\x44\\x8C\\xD8\\x54\\xC6\\x96\\x81\\x79\\x63\\x03\\x4E\\xBC\\xA5\\xC8\\x6E\\x19\\x90\\x03\\x0C\"\n\"\\x6E\\x21\\xEF\\x68\\xC2\\x56\\x9A\\x69\\x1D\\x6C\\x26\\x93\\x9B\\xE7\\x99\\x8E\\xF9\\x70\\x58\\xB5\\x8B\\x40\"\n\"\\x6D\\x60\\xB1\\xBC\\x1D\\x3B\\xDB\\xE9\\x4E\\x99\\x08\\xE0\\x00\\x04\\x78\\x67\\x4C\\x04\\x40\\x80\\x7B\\xD2\"\n\"\\xD3\\x23\\x14\\xB4\\x26\\x3D\\xE3\\x69\\xA3\\x7C\\x02\\x34\\xA0\\x02\\x1D\\x28\\x41\\x0B\\xFA\\xCE\\x8E\\xFD\"\n\"\\xE3\\x1B\\xA6\\x78\\x86\\x41\\x1B\\xEA\\xD0\\x87\\x42\\x34\\xA2\\x12\\xBD\\x88\\x09\\xDA\\x71\\xC3\\x89\\x62\"\n\"\\x34\\xA3\\x1A\\xDD\\x28\\x47\\x05\\x42\\x80\\x03\\x08\\xA0\\xA3\\x22\\x1D\\x29\\x49\\x4B\\x6A\\xD2\\x93\\xA2\"\n\"\\x34\\xA5\\x2A\\x5D\\x29\\x4B\\x5B\\xEA\\xD2\\x97\\xC2\\x34\\xA6\\x32\\x9D\\x29\\x4D\\x6B\\x6A\\xD3\\x9B\\xE2\"\n\"\\x34\\xA7\\x3A\\xDD\\x29\\x4F\\x7B\\xEA\\xD3\\x9F\\x02\\x35\\xA8\\x42\\x1D\\xEA\\x46\\xED\\x49\\x80\\x90\\xCE\"\n\"\\xF4\\x9E\\x47\\x25\\x6A\\x41\\x3F\\x46\\xC1\\x55\\xA1\\x73\\x96\\xEB\\x64\\xE5\\x27\\xF9\\xF9\\x31\\x92\\x5D\"\n\"\\x84\\x07\\xDF\\x48\\x1A\\x3F\\x9F\\x26\\xD5\\x45\\xA5\\x93\\x22\\xEB\\x04\\x8C\\x74\\x82\\x21\\xCE\\xAD\\x58\"\n\"\\xE1\\x99\\x2F\\x33\\xA2\\x74\\xA0\\x71\\xD6\\xAD\\x44\\xA7\\x90\\x40\\x15\\x97\\x25\\x9A\\xE8\\x11\\x7D\\xBC\"\n\"\\x72\\x22\\x1F\\xC2\\xEB\\x44\\x22\\xF2\\x0F\\xAB\\x4A\\xEA\\x43\\x67\\xFB\\x87\\x3B\\x4C\\x31\\x0B\\x68\\xF8\"\n\"\\xA3\\x97\\x0F\\x89\\xC8\\x2B\\xA7\\xCA\\x1F\\xC6\\xDE\\x71\\xAC\\x90\\x65\\x62\\x3F\\x20\\x74\\x91\\x00\\xAC\"\n\"\\x63\\x21\\x0A\\x3D\\xAC\\x3F\\x20\\x98\\x3C\\x3B\\xAE\\x15\\x2C\\x17\\x54\\xAC\\x4F\\x0B\\x65\\x2B\\xF7\\xC0\"\n\"\\xE6\\xAA\\x5C\\x8C\\xC9\\x55\\xAF\\xDA\\x18\\x77\\x48\\xB3\\x48\\x56\\x5C\\xED\\x1C\\xFD\\x12\\x81\\x66\\x08\"\n\"\\xD2\\x21\\xAE\\xF8\\xC7\\x33\\xB8\\x06\\x96\\x42\\x55\\xA0\\x2C\\xBA\\xF3\\x88\\xC8\\x66\\xC1\\x0F\\x11\\xE6\"\n\"\\x14\\x3D\\x2B\\x41\\x2E\\x6B\\xDD\\xD7\\xB9\\xD6\\xA2\\x86\\x6D\\xCC\\x85\\xA1\\x6C\\x53\\x8B\\x1A\\x45\\xC0\"\n\"\\x29\\x20\\x1D\\x9B\\x6E\\xD7\\x04\\xC2\\x80\\xCE\\x6E\\x25\\x1D\\x6D\\xF2\\xCF\\xF6\\xE6\\xAA\\x94\\x0A\\x1C\"\n\"\\xC4\\xB2\\xFB\\x51\\xAD\\x1C\\x57\\xF9\\xB1\\xFF\\xED\\xA7\\x7A\\xB4\\x95\\xC9\\x55\\xF5\\xC1\\x2C\\xF8\\x22\"\n\"\\xE6\\x63\\xFB\\xF0\\xAC\\x43\\x32\\xE0\\xA9\\xC8\\x15\\x93\\xA7\\x76\\x2B\\x00\\x44\\x9C\\x96\\x5F\\xE7\\xFE\"\n\"\\x0B\\xBA\\xEA\\x41\\xDE\\x23\\x67\\xDB\\xDE\\x71\\xD2\\xE7\\x52\\xC0\\xAB\\xA5\\xCF\\x00\\x2C\\x93\\x00\\x11\"\n\"\\x2F\\x52\\x5B\\x14\\xF0\\x97\\xEE\\x81\\xBE\\xBD\\xB1\\xD7\\x76\\xF4\\x6D\\xD3\\x45\\xBA\\x80\\x1A\\x06\\x73\"\n\"\\xAE\\xAB\\x86\\x51\\xF1\\x39\\x07\\xF2\\x14\\x4A\\xA1\\xB8\\xB9\\x03\\x09\\x00\\x6E\\x49\\x3B\\x90\\x30\\x09\"\n\"\\x44\\x64\\xBF\\x13\\xF0\\xC0\\x0C\\x7C\\x60\\x0A\\x3F\\xF7\\x1F\\x80\\xA8\\x03\\x91\\x89\\xAC\\x86\\x60\\x9C\"\n\"\\xD8\\x2F\\x3C\\x30\\x45\\x26\\x32\\x61\\x8A\\xB7\\x3C\\x43\\x0D\\x45\\xAE\\x03\\x0D\\xB2\\xF2\\x0D\\x46\\x34\"\n\"\\xD9\\xC9\\x98\\x74\\xEF\\xE3\\x62\\x5C\\x27\\x26\\x67\\x62\\x16\\x06\\x09\\xB0\\x40\\xE0\\x23\\x4C\\xEE\\x90\"\n\"\\x39\\xB9\\xEA\\x64\\x67\\x88\\xDF\\x47\\xDF\\x59\\x5E\\x74\\xC2\\x02\\xD9\\x43\\x32\\xC1\\xFA\\x49\\x45\\x38\"\n\"\\xF1\\xCE\\x10\\xBE\\x08\\x28\\xBA\\xEC\\xBE\\xE4\\x7C\\xD2\\x1F\\x06\\xC6\\xCF\\x96\\x35\\x09\\xC8\\x9E\\x82\"\n\"\\xC4\\x34\\xEC\\x12\\xA6\\x88\\xDA\\xFC\\x5C\\x7F\\xB4\\x60\\x03\\x92\\x96\\x74\\x05\\x2E\\x91\\x64\\xAB\\x24\"\n\"\\xEC\\x00\\x8A\\x30\\x13\\x26\\x2A\\x30\\xE9\\xAD\\x65\\x65\\x11\\x07\\x68\\x00\\xA9\\x1B\\x30\\xCF\\x38\\x02\"\n\"\\xE0\\xC5\\x98\\xFA\\x73\\x67\\x36\\x50\\xEA\\x0A\\x4C\\xE8\\x1F\\xBE\\x75\\x48\\x52\\x0A\\x16\\x90\\x00\\xF9\"\n\"\\xD8\\xA6\\x24\\xB1\\x4D\\x00\\xCA\\x52\\x68\\xEB\\x38\\x3A\\xC1\\x24\\x76\\x08\\xE5\\x68\\x1D\\xD8\\xCB\\xB1\"\n\"\\x78\\x77\\xD6\\x6D\\x9A\\xB1\\x29\\x7C\\x95\\x8B\\x10\\x8B\\xD1\\x02\\x29\\x4B\\x1D\\xC0\\x60\\x6D\\x2B\\x64\"\n\"\\x36\\xD9\\x34\\x45\\x0F\\x6E\\x82\\x23\\xA2\\x3E\\x20\\xB8\\xB6\\x08\\x1C\\x08\\xED\\x36\\x8C\\xD5\\xF9\\x26\"\n\"\\x6B\\xD9\\xD4\\xF2\\xC7\\xAC\\xAD\\xE6\\xED\\x1F\\xBB\\x84\\xBF\\x00\\x60\\x1B\\x9C\\xA5\\xAD\\xD3\\x42\\x01\"\n\"\\x25\\xCD\\x32\\xD1\\x12\\x90\\x85\\x3D\\x6E\\x81\\xF0\\xA8\\x44\\xAA\\x95\\xEF\\x83\\xE3\\xC8\\x9E\\xFA\\x0D\"\n\"\\x52\\x69\\xC0\\x46\\xCD\\x00\\xBE\\xE8\\xB9\\xBA\\x6C\\xC0\\x04\\x12\\x07\\x01\\x0D\\xDA\\xF3\\x53\\x71\\xB9\"\n\"\\xC8\\xC6\\x01\\xE1\\xA4\\x40\\x5C\\x26\\xD7\\x4C\\xBA\\x17\\x35\\x21\\x44\\xB5\\x9B\\xAB\\x0B\\xEF\\x81\\x2C\"\n\"\\xE3\\x1F\\xF2\\x73\\x48\\x08\\x9D\\xDD\\xDD\\x8E\\x83\\x57\\x2F\\x50\\x15\\x08\\xBF\\x4B\\xCB\\x19\\xF8\\xBC\"\n\"\\xE8\\x22\\x5D\\xF1\\x06\\x27\\x23\\x50\\x16\\x8D\\xA3\\xBB\\xC5\\x3F\\x1B\\x08\\xBB\\xBC\\xD1\\x6E\\x34\\xF4\"\n\"\\xCF\\x87\\x0E\\x2E\\x54\\x04\\x32\\x2B\\xC1\\x50\\xFC\\x83\\xE7\\x27\\x27\\xC8\\xB7\\x86\\xBB\\x4B\\x44\\x02\"\n\"\\x8A\\x45\\x88\\x46\\x0D\\x7E\\x10\\x7E\\x80\\x0B\\xBE\\x63\\x16\\x5B\\x75\\xB8\\x43\\xF8\\x7A\\x90\\x77\\xF8\"\n\"\\x03\\xB0\\xFF\\x16\\xC8\\x00\\x2E\\x08\\x8D\\x30\\x6F\\x35\\xE9\\xB0\\x69\\x65\\x5E\\x25\\x2B\\x91\\x3A\\x4A\"\n\"\\x47\\xBD\\x33\\x4E\\xD7\\x66\\x83\\x81\\xC7\\xA5\\xDC\\x91\\x22\\x64\\xC6\\xD5\\xB3\\x6C\\x4E\\x1F\\xB4\\xEC\"\n\"\\x38\\x20\\x4D\\x18\\x3B\\x61\\xAD\\xD0\\xCD\\x4F\\x06\\x49\\xC1\\x31\\x01\\x83\\x5A\\x23\\x22\\x8B\\xA3\\x69\"\n\"\\x7B\\xDA\\x5F\\xD5\\x4B\\x32\\xDD\\x8A\\x98\\x26\\x58\\x52\\x9D\\x5D\\x4A\\x9A\\x3F\\xBE\\xB1\\x4C\\xA4\\x4C\"\n\"\\x15\\x24\\x26\\x60\\xAA\\x75\\x02\\x20\\x00\\xA4\\x8E\\xF4\\xA3\\x04\\x70\\x39\\x4A\\x65\\x0F\\x7B\\xD6\\xE3\"\n\"\\x3E\\xF7\\xBA\\xDF\\x3D\\xEF\\x7B\\xEF\\xFB\\xDF\\x03\\x3F\\xF8\\xC2\\x1F\\x3E\\xF1\\x8B\\x6F\\xFC\\xE3\\x23\"\n\"\\x3F\\xF9\\xCA\\x5F\\x3E\\xF3\\x9B\\xEF\\xFC\\xE7\\x43\\x3F\\xFA\\xD2\\x9F\\x3E\\xF5\\xAB\\x6F\\xFD\\xEB\\x63\"\n\"\\x3F\\xFB\\xDA\\xDF\\x3E\\xF7\\xBB\\xEF\\xFD\\xEF\\x83\\x3F\\xFC\\xE2\\x1F\\x3F\\xF9\\xCB\\x6F\\xFE\\xF3\\xA3\"\n\"\\x3F\\xFD\\xEA\\x5F\\x3F\\xFB\\xDB\\xEF\\xFE\\xF7\\xC3\\xFF\\xF8\";\n#undef DD_ALIGNED_BUFFER\n\nstatic const FontCharSet s_fontMonoid18CharSet = {\n  /* bitmap               = */ s_fontMonoid18Bitmap,\n  /* bitmapWidth          = */ 256,\n  /* bitmapHeight         = */ 256,\n  /* bitmapColorChannels  = */ 1,\n  /* bitmapDecompressSize = */ 65536,\n  /* charBaseHeight       = */ 20,\n  /* charWidth            = */ 17,\n  /* charHeight           = */ 30,\n  /* charCount            = */ 96,\n  {\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0, 150 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,  60 }, {  17,  60 }, {  68,   0 },\n   { 153,   0 }, { 119,   0 }, {  34,   0 }, { 204,  30 },\n   { 119,  30 }, { 102,  30 }, {   0,   0 }, { 102,   0 },\n   { 170,  30 }, { 136,   0 }, { 187,  30 }, { 221,   0 },\n   {  34,  60 }, { 187,  60 }, { 170,  60 }, { 153,  60 },\n   { 136,  60 }, { 119,  60 }, { 102,  60 }, {  85,  60 },\n   {  68,  60 }, {  51,  60 }, { 136,  30 }, { 153,  30 },\n   {  17,  30 }, {  85,   0 }, {   0,  30 }, { 221,  30 },\n   { 204,   0 }, { 170, 210 }, { 153, 210 }, { 136, 210 },\n   { 119, 210 }, { 102, 210 }, {  85, 210 }, {  68, 210 },\n   {  51, 210 }, {  34, 210 }, {  17, 210 }, {   0, 210 },\n   { 238, 180 }, { 221, 180 }, { 204, 180 }, { 187, 180 },\n   { 170, 180 }, { 153, 180 }, { 136, 180 }, { 119, 180 },\n   { 102, 180 }, {  85, 180 }, {  68, 180 }, {  51, 180 },\n   {  34, 180 }, {  17, 180 }, {   0, 180 }, {  85,  30 },\n   { 187,   0 }, {  68,  30 }, { 170,   0 }, {  51,   0 },\n   { 238,  30 }, { 119, 120 }, { 102, 120 }, {  85, 120 },\n   {  68, 120 }, {  51, 120 }, {  34, 120 }, {  17, 120 },\n   {   0, 120 }, { 238,  90 }, { 221,  90 }, { 204,  90 },\n   { 187,  90 }, { 170,  90 }, { 153,  90 }, { 136,  90 },\n   { 119,  90 }, { 102,  90 }, {  85,  90 }, {  68,  90 },\n   {  51,  90 }, {  34,  90 }, {  17,  90 }, {   0,  90 },\n   { 238,  60 }, { 221,  60 }, { 204,  60 }, {  51,  30 },\n   { 238,   0 }, {  34,  30 }, {  17,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },\n   {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }\n  }\n};\n\n// ========================================================\n// LZW decompression helpers for the font bitmap:\n// ========================================================\n\n// These must match the font-tool encoder!\nstatic const int LzwNil            = -1;\nstatic const int LzwMaxDictBits    = 12;\nstatic const int LzwStartBits      = 9;\nstatic const int LzwFirstCode      = (1 << (LzwStartBits - 1)); // 256\nstatic const int LzwMaxDictEntries = (1 << LzwMaxDictBits);     // 4096\n\nstruct LzwDictionary\n{\n    // Dictionary entries 0-255 are always reserved to the byte/ASCII range.\n    struct Entry\n    {\n        int code;\n        int value;\n    };\n\n    int size;\n    Entry entries[LzwMaxDictEntries];\n\n    LzwDictionary();\n    int findIndex(int code, int value) const;\n    bool add(int code, int value);\n    bool flush(int & codeBitsWidth);\n};\n\nstruct LzwBitStreamReader\n{\n    const std::uint8_t * stream; // Pointer to the external bit stream. Not owned by the reader.\n    int sizeInBytes;             // Size of the stream in bytes. Might include padding.\n    int sizeInBits;              // Size of the stream in bits, padding not include.\n    int currBytePos;             // Current byte being read in the stream.\n    int nextBitPos;              // Bit position within the current byte to access next. 0 to 7.\n    int numBitsRead;             // Total bits read from the stream so far. Never includes byte-rounding.\n\n    LzwBitStreamReader(const std::uint8_t * bitStream, int byteCount, int bitCount);\n    bool readNextBit(int & outBit);\n    int readBits(int bitCount);\n};\n\n// ========================================================\n// LzwDictionary:\n// ========================================================\n\nLzwDictionary::LzwDictionary()\n{\n    // First 256 dictionary entries are reserved to the byte/ASCII\n    // range. Additional entries follow for the character sequences\n    // found in the input. Up to 4096 - 256 (LzwMaxDictEntries - LzwFirstCode).\n    size = LzwFirstCode;\n    for (int i = 0; i < size; ++i)\n    {\n        entries[i].code  = LzwNil;\n        entries[i].value = i;\n    }\n}\n\nint LzwDictionary::findIndex(const int code, const int value) const\n{\n    if (code == LzwNil)\n    {\n        return value;\n    }\n    for (int i = 0; i < size; ++i)\n    {\n        if (entries[i].code == code && entries[i].value == value)\n        {\n            return i;\n        }\n    }\n    return LzwNil;\n}\n\nbool LzwDictionary::add(const int code, const int value)\n{\n    if (size == LzwMaxDictEntries)\n    {\n        return false;\n    }\n    entries[size].code  = code;\n    entries[size].value = value;\n    ++size;\n    return true;\n}\n\nbool LzwDictionary::flush(int & codeBitsWidth)\n{\n    if (size == (1 << codeBitsWidth))\n    {\n        ++codeBitsWidth;\n        if (codeBitsWidth > LzwMaxDictBits)\n        {\n            // Clear the dictionary (except the first 256 byte entries).\n            codeBitsWidth = LzwStartBits;\n            size = LzwFirstCode;\n            return true;\n        }\n    }\n    return false;\n}\n\n// ========================================================\n// LzwBitStreamReader:\n// ========================================================\n\nLzwBitStreamReader::LzwBitStreamReader(const std::uint8_t * bitStream, const int byteCount, const int bitCount)\n    : stream(bitStream)\n    , sizeInBytes(byteCount)\n    , sizeInBits(bitCount)\n    , currBytePos(0)\n    , nextBitPos(0)\n    , numBitsRead(0)\n{ }\n\nbool LzwBitStreamReader::readNextBit(int & outBit)\n{\n    if (numBitsRead >= sizeInBits)\n    {\n        return false; // We are done.\n    }\n\n    const int mask = 1 << nextBitPos;\n    outBit = !!(stream[currBytePos] & mask);\n    ++numBitsRead;\n\n    if (++nextBitPos == 8)\n    {\n        nextBitPos = 0;\n        ++currBytePos;\n    }\n    return true;\n}\n\nint LzwBitStreamReader::readBits(const int bitCount)\n{\n    int num = 0;\n    for (int b = 0; b < bitCount; ++b)\n    {\n        int bit;\n        if (!readNextBit(bit))\n        {\n            break;\n        }\n        const int mask = 1 << b;\n        num = (num & ~mask) | (-bit & mask);\n    }\n    return num;\n}\n\n// ========================================================\n// lzwDecompress() and helpers:\n// ========================================================\n\nstatic bool lzwOutputByte(int code, std::uint8_t *& output, int outputSizeBytes, int & bytesDecodedSoFar)\n{\n    if (code < 0 || code >= 256)\n    {\n        return false;\n    }\n    if (bytesDecodedSoFar >= outputSizeBytes)\n    {\n        return false;\n    }\n    *output++ = static_cast<std::uint8_t>(code);\n    ++bytesDecodedSoFar;\n    return true;\n}\n\nstatic bool lzwOutputSequence(const LzwDictionary & dict, int code,\n                              std::uint8_t *& output, int outputSizeBytes,\n                              int & bytesDecodedSoFar, int & firstByte)\n{\n    // A sequence is stored backwards, so we have to write\n    // it to a temp then output the buffer in reverse.\n    int i = 0;\n    std::uint8_t sequence[LzwMaxDictEntries];\n    do\n    {\n        sequence[i++] = dict.entries[code].value & 0xFF;\n        code = dict.entries[code].code;\n    } while (code >= 0);\n\n    firstByte = sequence[--i];\n    for (; i >= 0; --i)\n    {\n        if (!lzwOutputByte(sequence[i], output, outputSizeBytes, bytesDecodedSoFar))\n        {\n            return false;\n        }\n    }\n    return true;\n}\n\nstatic int lzwDecompress(const void * compressedData, int compressedSizeBytes,\n                         int compressedSizeBits, void * uncompressedData,\n                         int uncompressedSizeBytes)\n{\n    if (compressedData == nullptr || uncompressedData == nullptr)\n    {\n        return 0;\n    }\n    if (compressedSizeBytes <= 0 || compressedSizeBits <= 0 || uncompressedSizeBytes <= 0)\n    {\n        return 0;\n    }\n\n    int code          = LzwNil;\n    int prevCode      = LzwNil;\n    int codeBitsWidth = LzwStartBits;\n    int firstByte     = 0;\n    int bytesDecoded  = 0;\n\n    const std::uint8_t * compressedPtr = reinterpret_cast<const std::uint8_t *>(compressedData);\n    std::uint8_t * uncompressedPtr = reinterpret_cast<std::uint8_t *>(uncompressedData);\n\n    // We'll reconstruct the dictionary based on the bit stream codes.\n    LzwBitStreamReader bitStream(compressedPtr, compressedSizeBytes, compressedSizeBits);\n    LzwDictionary dictionary;\n\n    // We check to avoid an overflow of the user buffer.\n    // If the buffer is smaller than the decompressed size, we\n    // break the loop and return the current decompression count.\n    while (bitStream.numBitsRead < bitStream.sizeInBits)\n    {\n        if (codeBitsWidth > LzwMaxDictBits)\n        {\n            break;\n        }\n        code = bitStream.readBits(codeBitsWidth);\n\n        if (prevCode == LzwNil)\n        {\n            if (!lzwOutputByte(code, uncompressedPtr, uncompressedSizeBytes, bytesDecoded))\n            {\n                break;\n            }\n            firstByte = code;\n            prevCode  = code;\n            continue;\n        }\n\n        if (code >= dictionary.size)\n        {\n            if (!lzwOutputSequence(dictionary, prevCode, uncompressedPtr,\n                 uncompressedSizeBytes, bytesDecoded, firstByte))\n            {\n                break;\n            }\n            if (!lzwOutputByte(firstByte, uncompressedPtr, uncompressedSizeBytes, bytesDecoded))\n            {\n                break;\n            }\n        }\n        else\n        {\n            if (!lzwOutputSequence(dictionary, code, uncompressedPtr,\n                 uncompressedSizeBytes, bytesDecoded, firstByte))\n            {\n                break;\n            }\n        }\n\n        if (!dictionary.add(prevCode, firstByte))\n        {\n            break;\n        }\n\n        if (dictionary.flush(codeBitsWidth))\n        {\n            prevCode = LzwNil;\n        }\n        else\n        {\n            prevCode = code;\n        }\n    }\n\n    return bytesDecoded;\n}\n\n// ========================================================\n// Built-in font glyph bitmap decompression:\n// ========================================================\n\n// If you decide to change the font, these are the only things that\n// need to be updated. The s_font* variables are never referenced\n// directly in the code, these functions are used instead.\nstatic inline const std::uint8_t * getRawFontBitmapData() { return s_fontMonoid18Bitmap;  }\nstatic inline const FontCharSet  & getFontCharSet()       { return s_fontMonoid18CharSet; }\n\nstatic std::uint8_t * decompressFontBitmap()\n{\n    const std::uint32_t * compressedData = reinterpret_cast<const std::uint32_t *>(getRawFontBitmapData());\n\n    // First two uint32s are the compressed size in\n    // bytes followed by the compressed size in bits.\n    const int compressedSizeBytes = *compressedData++;\n    const int compressedSizeBits  = *compressedData++;\n\n    // Allocate the decompression buffer:\n    const int uncompressedSizeBytes = getFontCharSet().bitmapDecompressSize;\n    std::uint8_t * uncompressedData = static_cast<std::uint8_t *>(DD_MALLOC(uncompressedSizeBytes));\n\n    // Out of memory? Font rendering will be disable.\n    if (uncompressedData == nullptr)\n    {\n        return nullptr;\n    }\n\n    // Decode the bitmap pixels (stored with an LZW-flavor of compression):\n    const int bytesDecoded = lzwDecompress(compressedData,\n                                           compressedSizeBytes,\n                                           compressedSizeBits,\n                                           uncompressedData,\n                                           uncompressedSizeBytes);\n\n    // Unexpected decompression size? Probably a data mismatch in the font-tool.\n    if (bytesDecoded != uncompressedSizeBytes)\n    {\n        DD_MFREE(uncompressedData);\n        return nullptr;\n    }\n\n    // Must later free with DD_MFREE().\n    return uncompressedData;\n}\n\n// ========================================================\n// Internal Debug Draw queues and helper types/functions:\n// ========================================================\n\nstruct DebugString\n{\n    std::int64_t expiryDateMillis;\n    ddVec3       color;\n    float        posX;\n    float        posY;\n    float        scaling;\n    ddStr        text;\n    bool         centered;\n};\n\nstruct DebugPoint\n{\n    std::int64_t expiryDateMillis;\n    ddVec3       position;\n    ddVec3       color;\n    float        size;\n    bool         depthEnabled;\n};\n\nstruct DebugLine\n{\n    std::int64_t expiryDateMillis;\n    ddVec3       posFrom;\n    ddVec3       posTo;\n    ddVec3       color;\n    bool         depthEnabled;\n};\n\nstruct InternalContext DD_EXPLICIT_CONTEXT_ONLY(: public OpaqueContextType)\n{\n    int                vertexBufferUsed;\n    int                debugStringsCount;\n    int                debugPointsCount;\n    int                debugLinesCount;\n    std::int64_t       currentTimeMillis;                           // Latest time value (in milliseconds) from dd::flush().\n    GlyphTextureHandle glyphTexHandle;                              // Our built-in glyph bitmap. If kept null, no text is rendered.\n    RenderInterface *  renderInterface;                             // Ref to the external renderer. Can be null for a no-op debug draw.\n    DrawVertex         vertexBuffer[DEBUG_DRAW_VERTEX_BUFFER_SIZE]; // Vertex buffer we use to expand the lines/points before calling on RenderInterface.\n    DebugString        debugStrings[DEBUG_DRAW_MAX_STRINGS];        // Debug strings queue (2D screen-space strings + 3D projected labels).\n    DebugPoint         debugPoints[DEBUG_DRAW_MAX_POINTS];          // 3D debug points queue.\n    DebugLine          debugLines[DEBUG_DRAW_MAX_LINES];            // 3D debug lines queue.\n\n    InternalContext(RenderInterface * renderer)\n        : vertexBufferUsed(0)\n        , debugStringsCount(0)\n        , debugPointsCount(0)\n        , debugLinesCount(0)\n        , currentTimeMillis(0)\n        , glyphTexHandle(nullptr)\n        , renderInterface(renderer)\n    { }\n};\n\n// ========================================================\n// Library context mode selection:\n// ========================================================\n\n#if (defined(DEBUG_DRAW_PER_THREAD_CONTEXT) && defined(DEBUG_DRAW_EXPLICIT_CONTEXT))\n    #error \"DEBUG_DRAW_PER_THREAD_CONTEXT and DEBUG_DRAW_EXPLICIT_CONTEXT are mutually exclusive!\"\n#endif // DEBUG_DRAW_PER_THREAD_CONTEXT && DEBUG_DRAW_EXPLICIT_CONTEXT\n\n#if defined(DEBUG_DRAW_EXPLICIT_CONTEXT)\n    //\n    // Explicit context passed as argument\n    //\n    #define DD_CONTEXT static_cast<InternalContext *>(ctx)\n#elif defined(DEBUG_DRAW_PER_THREAD_CONTEXT)\n    //\n    // Per-thread global context (MT safe)\n    //\n    #if defined(__GNUC__) || defined(__clang__) // GCC/Clang\n        #define DD_THREAD_LOCAL static __thread\n    #elif defined(_MSC_VER) // Visual Studio\n        #define DD_THREAD_LOCAL static __declspec(thread)\n    #else // Try C++11 thread_local\n        #if DEBUG_DRAW_CXX11_SUPPORTED\n            #define DD_THREAD_LOCAL static thread_local\n        #else // !DEBUG_DRAW_CXX11_SUPPORTED\n            #error \"Unsupported compiler - unknown TLS model\"\n        #endif // DEBUG_DRAW_CXX11_SUPPORTED\n    #endif // TLS model\n    DD_THREAD_LOCAL InternalContext * s_threadContext = nullptr;\n    #define DD_CONTEXT s_threadContext\n    #undef DD_THREAD_LOCAL\n#else // Debug Draw context selection\n    //\n    // Global static context (single threaded operation)\n    //\n    static InternalContext * s_globalContext = nullptr;\n    #define DD_CONTEXT s_globalContext\n#endif // Debug Draw context selection\n\n// ========================================================\n\n#if DEBUG_DRAW_USE_STD_MATH\n\nstatic inline float floatAbs(float x)       { return fabsf(x); }\nstatic inline float floatSin(float radians) { return sinf(radians); }\nstatic inline float floatCos(float radians) { return cosf(radians); }\nstatic inline float floatInvSqrt(float x)   { return (1.0f / sqrtf(x)); }\n\n#else // !DEBUG_DRAW_USE_STD_MATH\n\n// ========================================================\n// Fast approximations of math functions used by Debug Draw\n// ========================================================\n\nunion Float2UInt\n{\n    float asFloat;\n    std::uint32_t asUInt;\n};\n\nstatic inline float floatRound(float x)\n{\n    // Probably slower than std::floor(), also depends of FPU settings,\n    // but we only need this for that special sin/cos() case anyways...\n    const int i = static_cast<int>(x);\n    return (x >= 0.0f) ? static_cast<float>(i) : static_cast<float>(i - 1);\n}\n\nstatic inline float floatAbs(float x)\n{\n    // Mask-off the sign bit\n    Float2UInt i;\n    i.asFloat = x;\n    i.asUInt &= 0x7FFFFFFF;\n    return i.asFloat;\n}\n\nstatic inline float floatInvSqrt(float x)\n{\n    // Modified version of the emblematic Q_rsqrt() from Quake 3.\n    // See: http://en.wikipedia.org/wiki/Fast_inverse_square_root\n    Float2UInt i;\n    float y, r;\n    y = x * 0.5f;\n    i.asFloat = x;\n    i.asUInt = 0x5F3759DF - (i.asUInt >> 1);\n    r = i.asFloat;\n    r = r * (1.5f - (r * r * y));\n    return r;\n}\n\nstatic inline float floatSin(float radians)\n{\n    static const float A = -2.39e-08;\n    static const float B = 2.7526e-06;\n    static const float C = 1.98409e-04;\n    static const float D = 8.3333315e-03;\n    static const float E = 1.666666664e-01;\n\n    if (radians < 0.0f || radians >= TAU)\n    {\n        radians -= floatRound(radians / TAU) * TAU;\n    }\n\n    if (radians < PI)\n    {\n        if (radians > HalfPI)\n        {\n            radians = PI - radians;\n        }\n    }\n    else\n    {\n        radians = (radians > (PI + HalfPI)) ? (radians - TAU) : (PI - radians);\n    }\n\n    const float s = radians * radians;\n    return radians * (((((A * s + B) * s - C) * s + D) * s - E) * s + 1.0f);\n}\n\nstatic inline float floatCos(float radians)\n{\n    static const float A = -2.605e-07;\n    static const float B = 2.47609e-05;\n    static const float C = 1.3888397e-03;\n    static const float D = 4.16666418e-02;\n    static const float E = 4.999999963e-01;\n\n    if (radians < 0.0f || radians >= TAU)\n    {\n        radians -= floatRound(radians / TAU) * TAU;\n    }\n\n    float d;\n    if (radians < PI)\n    {\n        if (radians > HalfPI)\n        {\n            radians = PI - radians;\n            d = -1.0f;\n        }\n        else\n        {\n            d = 1.0f;\n        }\n    }\n    else\n    {\n        if (radians > (PI + HalfPI))\n        {\n            radians = radians - TAU;\n            d = 1.0f;\n        }\n        else\n        {\n            radians = PI - radians;\n            d = -1.0f;\n        }\n    }\n\n    const float s = radians * radians;\n    return d * (((((A * s + B) * s - C) * s + D) * s - E) * s + 1.0f);\n}\n\n#endif // DEBUG_DRAW_USE_STD_MATH\n\n// ========================================================\n// ddVec3 helpers:\n// ========================================================\n\nenum VecElements { X, Y, Z, W };\n\nstatic inline void vecSet(ddVec3_Out dest, const float x, const float y, const float z)\n{\n    dest[X] = x;\n    dest[Y] = y;\n    dest[Z] = z;\n}\n\nstatic inline void vecCopy(ddVec3_Out dest, ddVec3_In src)\n{\n    dest[X] = src[X];\n    dest[Y] = src[Y];\n    dest[Z] = src[Z];\n}\n\nstatic inline void vecAdd(ddVec3_Out result, ddVec3_In a, ddVec3_In b)\n{\n    result[X] = a[X] + b[X];\n    result[Y] = a[Y] + b[Y];\n    result[Z] = a[Z] + b[Z];\n}\n\nstatic inline void vecSub(ddVec3_Out result, ddVec3_In a, ddVec3_In b)\n{\n    result[X] = a[X] - b[X];\n    result[Y] = a[Y] - b[Y];\n    result[Z] = a[Z] - b[Z];\n}\n\nstatic inline void vecScale(ddVec3_Out result, ddVec3_In v, const float s)\n{\n    result[X] = v[X] * s;\n    result[Y] = v[Y] * s;\n    result[Z] = v[Z] * s;\n}\n\nstatic inline void vecNormalize(ddVec3_Out result, ddVec3_In v)\n{\n    const float lenSqr = v[X] * v[X] + v[Y] * v[Y] + v[Z] * v[Z];\n    const float invLen = floatInvSqrt(lenSqr);\n    result[X] = v[X] * invLen;\n    result[Y] = v[Y] * invLen;\n    result[Z] = v[Z] * invLen;\n}\n\nstatic inline void vecCross(ddVec3_Out result, ddVec3_In a, ddVec3_In b)\n{\n    result[X] = a[Y] * b[Z] - a[Z] * b[Y];\n    result[Y] = a[Z] * b[X] - a[X] * b[Z];\n    result[Z] = a[X] * b[Y] - a[Y] * b[X];\n}\n\nstatic inline void vecOrthogonalBasis(ddVec3_Out left, ddVec3_Out up, ddVec3_In v)\n{\n    // Produces two orthogonal vectors for normalized vector v.\n    float lenSqr, invLen;\n    if (floatAbs(v[Z]) > 0.7f)\n    {\n        lenSqr  = v[Y] * v[Y] + v[Z] * v[Z];\n        invLen  = floatInvSqrt(lenSqr);\n        up[X]   = 0.0f;\n        up[Y]   =  v[Z] * invLen;\n        up[Z]   = -v[Y] * invLen;\n        left[X] = lenSqr * invLen;\n        left[Y] = -v[X] * up[Z];\n        left[Z] =  v[X] * up[Y];\n    }\n    else\n    {\n        lenSqr  = v[X] * v[X] + v[Y] * v[Y];\n        invLen  = floatInvSqrt(lenSqr);\n        left[X] = -v[Y] * invLen;\n        left[Y] =  v[X] * invLen;\n        left[Z] = 0.0f;\n        up[X]   = -v[Z] * left[Y];\n        up[Y]   =  v[Z] * left[X];\n        up[Z]   = lenSqr * invLen;\n    }\n}\n\n// ========================================================\n// ddMat4x4 helpers:\n// ========================================================\n\nstatic inline void matTransformPointXYZ(ddVec3_Out result, ddVec3_In p, ddMat4x4_In m)\n{\n    result[X] = (m[0] * p[X]) + (m[4] * p[Y]) + (m[8]  * p[Z]) + m[12]; // p[W] assumed to be 1\n    result[Y] = (m[1] * p[X]) + (m[5] * p[Y]) + (m[9]  * p[Z]) + m[13];\n    result[Z] = (m[2] * p[X]) + (m[6] * p[Y]) + (m[10] * p[Z]) + m[14];\n}\n\nstatic inline void matTransformPointXYZW(float result[4], ddVec3_In p, ddMat4x4_In m)\n{\n    result[X] = (m[0] * p[X]) + (m[4] * p[Y]) + (m[8]  * p[Z]) + m[12]; // p[W] assumed to be 1\n    result[Y] = (m[1] * p[X]) + (m[5] * p[Y]) + (m[9]  * p[Z]) + m[13];\n    result[Z] = (m[2] * p[X]) + (m[6] * p[Y]) + (m[10] * p[Z]) + m[14];\n    result[W] = (m[3] * p[X]) + (m[7] * p[Y]) + (m[11] * p[Z]) + m[15];\n}\n\nstatic inline float matTransformPointXYZW2(ddVec3_Out result, const float p[3], ddMat4x4_In m)\n{\n    result[X] = (m[0] * p[X]) + (m[4] * p[Y]) + (m[8]  * p[Z]) + m[12]; // p[W] assumed to be 1\n    result[Y] = (m[1] * p[X]) + (m[5] * p[Y]) + (m[9]  * p[Z]) + m[13];\n    result[Z] = (m[2] * p[X]) + (m[6] * p[Y]) + (m[10] * p[Z]) + m[14];\n    float rw  = (m[3] * p[X]) + (m[7] * p[Y]) + (m[11] * p[Z]) + m[15];\n    return rw;\n}\n\n// ========================================================\n// Misc local functions for draw queue management:\n// ========================================================\n\nenum DrawMode\n{\n    DrawModePoints,\n    DrawModeLines,\n    DrawModeText\n};\n\nstatic void flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DrawMode mode, const bool depthEnabled)\n{\n    if (DD_CONTEXT->vertexBufferUsed == 0)\n    {\n        return;\n    }\n\n    switch (mode)\n    {\n    case DrawModePoints :\n        DD_CONTEXT->renderInterface->drawPointList(DD_CONTEXT->vertexBuffer,\n                                                   DD_CONTEXT->vertexBufferUsed,\n                                                   depthEnabled);\n        break;\n    case DrawModeLines :\n        DD_CONTEXT->renderInterface->drawLineList(DD_CONTEXT->vertexBuffer,\n                                                  DD_CONTEXT->vertexBufferUsed,\n                                                  depthEnabled);\n        break;\n    case DrawModeText :\n        DD_CONTEXT->renderInterface->drawGlyphList(DD_CONTEXT->vertexBuffer,\n                                                   DD_CONTEXT->vertexBufferUsed,\n                                                   DD_CONTEXT->glyphTexHandle);\n        break;\n    } // switch (mode)\n\n    DD_CONTEXT->vertexBufferUsed = 0;\n}\n\nstatic void pushPointVert(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DebugPoint & point)\n{\n    // Make room for one more vert:\n    if ((DD_CONTEXT->vertexBufferUsed + 1) >= DEBUG_DRAW_VERTEX_BUFFER_SIZE)\n    {\n        flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModePoints, point.depthEnabled);\n    }\n\n    DrawVertex & v = DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++];\n    v.point.x      = point.position[X];\n    v.point.y      = point.position[Y];\n    v.point.z      = point.position[Z];\n    v.point.r      = point.color[X];\n    v.point.g      = point.color[Y];\n    v.point.b      = point.color[Z];\n    v.point.size   = point.size;\n}\n\nstatic void pushLineVert(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DebugLine & line)\n{\n    // Make room for two more verts:\n    if ((DD_CONTEXT->vertexBufferUsed + 2) >= DEBUG_DRAW_VERTEX_BUFFER_SIZE)\n    {\n        flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeLines, line.depthEnabled);\n    }\n\n    DrawVertex & v0 = DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++];\n    DrawVertex & v1 = DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++];\n\n    v0.line.x = line.posFrom[X];\n    v0.line.y = line.posFrom[Y];\n    v0.line.z = line.posFrom[Z];\n    v0.line.r = line.color[X];\n    v0.line.g = line.color[Y];\n    v0.line.b = line.color[Z];\n\n    v1.line.x = line.posTo[X];\n    v1.line.y = line.posTo[Y];\n    v1.line.z = line.posTo[Z];\n    v1.line.r = line.color[X];\n    v1.line.g = line.color[Y];\n    v1.line.b = line.color[Z];\n}\n\nstatic void pushGlyphVerts(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DrawVertex verts[4])\n{\n    static const int indexes[6] = { 0, 1, 2, 2, 1, 3 };\n\n    // Make room for one more glyph (2 tris):\n    if ((DD_CONTEXT->vertexBufferUsed + 6) >= DEBUG_DRAW_VERTEX_BUFFER_SIZE)\n    {\n        flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeText, false);\n    }\n\n    for (int i = 0; i < 6; ++i)\n    {\n        DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++].glyph = verts[indexes[i]].glyph;\n    }\n}\n\nstatic void pushStringGlyphs(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) float x, float y,\n                             const char * text, ddVec3_In color, const float scaling)\n{\n    // Invariants for all characters:\n    const float initialX    = x;\n    const float scaleU      = static_cast<float>(getFontCharSet().bitmapWidth);\n    const float scaleV      = static_cast<float>(getFontCharSet().bitmapHeight);\n    const float fixedWidth  = static_cast<float>(getFontCharSet().charWidth);\n    const float fixedHeight = static_cast<float>(getFontCharSet().charHeight);\n    const float tabW        = fixedWidth  * 4.0f * scaling; // TAB = 4 spaces.\n    const float chrW        = fixedWidth  * scaling;\n    const float chrH        = fixedHeight * scaling;\n\n    for (; *text != '\\0'; ++text)\n    {\n        const int charVal = *text;\n        if (charVal >= FontCharSet::MaxChars)\n        {\n            continue;\n        }\n        if (charVal == ' ')\n        {\n            x += chrW;\n            continue;\n        }\n        if (charVal == '\\t')\n        {\n            x += tabW;\n            continue;\n        }\n        if (charVal == '\\n')\n        {\n            y += chrH;\n            x  = initialX;\n            continue;\n        }\n\n        const FontChar fontChar = getFontCharSet().chars[charVal];\n        const float u0 = (fontChar.x + 0.5f) / scaleU;\n        const float v0 = (fontChar.y + 0.5f) / scaleV;\n        const float u1 = u0 + (fixedWidth  / scaleU);\n        const float v1 = v0 + (fixedHeight / scaleV);\n\n        DrawVertex verts[4];\n        verts[0].glyph.x = x;\n        verts[0].glyph.y = y;\n        verts[0].glyph.u = u0;\n        verts[0].glyph.v = v0;\n        verts[0].glyph.r = color[X];\n        verts[0].glyph.g = color[Y];\n        verts[0].glyph.b = color[Z];\n        verts[1].glyph.x = x;\n        verts[1].glyph.y = y + chrH;\n        verts[1].glyph.u = u0;\n        verts[1].glyph.v = v1;\n        verts[1].glyph.r = color[X];\n        verts[1].glyph.g = color[Y];\n        verts[1].glyph.b = color[Z];\n        verts[2].glyph.x = x + chrW;\n        verts[2].glyph.y = y;\n        verts[2].glyph.u = u1;\n        verts[2].glyph.v = v0;\n        verts[2].glyph.r = color[X];\n        verts[2].glyph.g = color[Y];\n        verts[2].glyph.b = color[Z];\n        verts[3].glyph.x = x + chrW;\n        verts[3].glyph.y = y + chrH;\n        verts[3].glyph.u = u1;\n        verts[3].glyph.v = v1;\n        verts[3].glyph.r = color[X];\n        verts[3].glyph.g = color[Y];\n        verts[3].glyph.b = color[Z];\n\n        pushGlyphVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) verts);\n        x += chrW;\n    }\n}\n\nstatic float calcTextWidth(const char * text, const float scaling)\n{\n    const float fixedWidth = static_cast<float>(getFontCharSet().charWidth);\n    const float tabW = fixedWidth * 4.0f * scaling; // TAB = 4 spaces.\n    const float chrW = fixedWidth * scaling;\n\n    float x = 0.0f;\n    for (; *text != '\\0'; ++text)\n    {\n        // Tabs are handled differently (4 spaces)\n        if (*text == '\\t')\n        {\n            x += tabW;\n        }\n        else // Non-tab char (including whitespace)\n        {\n            x += chrW;\n        }\n    }\n\n    return x;\n}\n\nstatic void drawDebugStrings(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    const int count = DD_CONTEXT->debugStringsCount;\n    if (count == 0)\n    {\n        return;\n    }\n\n    const DebugString * const debugStrings = DD_CONTEXT->debugStrings;\n\n    for (int i = 0; i < count; ++i)\n    {\n        const DebugString & dstr = debugStrings[i];\n        if (dstr.centered)\n        {\n            // 3D Labels are centered at the point of origin, e.g. center-aligned.\n            const float offset = calcTextWidth(dstr.text.c_str(), dstr.scaling) * 0.5f;\n            pushStringGlyphs(DD_EXPLICIT_CONTEXT_ONLY(ctx,) dstr.posX - offset, dstr.posY, dstr.text.c_str(), dstr.color, dstr.scaling);\n        }\n        else\n        {\n            // Left-aligned\n            pushStringGlyphs(DD_EXPLICIT_CONTEXT_ONLY(ctx,) dstr.posX, dstr.posY, dstr.text.c_str(), dstr.color, dstr.scaling);\n        }\n    }\n\n    flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeText, false);\n}\n\nstatic void drawDebugPoints(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    const int count = DD_CONTEXT->debugPointsCount;\n    if (count == 0)\n    {\n        return;\n    }\n\n    const DebugPoint * const debugPoints = DD_CONTEXT->debugPoints;\n\n    //\n    // First pass, points with depth test ENABLED:\n    //\n    int numDepthlessPoints = 0;\n    for (int i = 0; i < count; ++i)\n    {\n        const DebugPoint & point = debugPoints[i];\n        if (point.depthEnabled)\n        {\n            pushPointVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point);\n        }\n        numDepthlessPoints += !point.depthEnabled;\n    }\n    flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModePoints, true);\n\n    //\n    // Second pass draws points with depth DISABLED:\n    //\n    if (numDepthlessPoints > 0)\n    {\n        for (int i = 0; i < count; ++i)\n        {\n            const DebugPoint & point = debugPoints[i];\n            if (!point.depthEnabled)\n            {\n                pushPointVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point);\n            }\n        }\n        flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModePoints, false);\n    }\n}\n\nstatic void drawDebugLines(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    const int count = DD_CONTEXT->debugLinesCount;\n    if (count == 0)\n    {\n        return;\n    }\n\n    const DebugLine * const debugLines = DD_CONTEXT->debugLines;\n\n    //\n    // First pass, lines with depth test ENABLED:\n    //\n    int numDepthlessLines = 0;\n    for (int i = 0; i < count; ++i)\n    {\n        const DebugLine & line = debugLines[i];\n        if (line.depthEnabled)\n        {\n            pushLineVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) line);\n        }\n        numDepthlessLines += !line.depthEnabled;\n    }\n    flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeLines, true);\n\n    //\n    // Second pass draws lines with depth DISABLED:\n    //\n    if (numDepthlessLines > 0)\n    {\n        for (int i = 0; i < count; ++i)\n        {\n            const DebugLine & line = debugLines[i];\n            if (!line.depthEnabled)\n            {\n                pushLineVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) line);\n            }\n        }\n        flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeLines, false);\n    }\n}\n\ntemplate<typename T>\nstatic void clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) T * queue, int & queueCount)\n{\n    const std::int64_t time = DD_CONTEXT->currentTimeMillis;\n    if (time == 0)\n    {\n        queueCount = 0;\n        return;\n    }\n\n    int index = 0;\n    T * pElem = queue;\n\n    // Concatenate elements that still need to be draw on future frames:\n    for (int i = 0; i < queueCount; ++i, ++pElem)\n    {\n        if (pElem->expiryDateMillis > time)\n        {\n            if (index != i)\n            {\n                queue[index] = *pElem;\n            }\n            ++index;\n        }\n    }\n\n    queueCount = index;\n}\n\nstatic void setupGlyphTexture(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    if (DD_CONTEXT->renderInterface == nullptr)\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->glyphTexHandle != nullptr)\n    {\n        DD_CONTEXT->renderInterface->destroyGlyphTexture(DD_CONTEXT->glyphTexHandle);\n        DD_CONTEXT->glyphTexHandle = nullptr;\n    }\n\n    std::uint8_t * decompressedBitmap = decompressFontBitmap();\n    if (decompressedBitmap == nullptr)\n    {\n        return; // Failed to decompressed. No font rendering available.\n    }\n\n    DD_CONTEXT->glyphTexHandle = DD_CONTEXT->renderInterface->createGlyphTexture(\n                                        getFontCharSet().bitmapWidth,\n                                        getFontCharSet().bitmapHeight,\n                                        decompressedBitmap);\n\n    // No longer needed.\n    DD_MFREE(decompressedBitmap);\n}\n\n// ========================================================\n// Public Debug Draw interface:\n// ========================================================\n\nbool initialize(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle * outCtx,) RenderInterface * renderer)\n{\n    if (renderer == nullptr)\n    {\n        return false;\n    }\n\n    void * buffer = DD_MALLOC(sizeof(InternalContext));\n    if (buffer == nullptr)\n    {\n        return false;\n    }\n\n    InternalContext * newCtx = ::new(buffer) InternalContext(renderer);\n\n    #ifdef DEBUG_DRAW_EXPLICIT_CONTEXT\n    if ((*outCtx) != nullptr) { shutdown(*outCtx); }\n    (*outCtx) = newCtx;\n    #else // !DEBUG_DRAW_EXPLICIT_CONTEXT\n    if (DD_CONTEXT != nullptr) { shutdown(); }\n    DD_CONTEXT = newCtx;\n    #endif // DEBUG_DRAW_EXPLICIT_CONTEXT\n\n    setupGlyphTexture(DD_EXPLICIT_CONTEXT_ONLY(*outCtx));\n    return true;\n}\n\nvoid shutdown(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    if (DD_CONTEXT != nullptr)\n    {\n        // If this macro is defined, the user-provided ddStr type\n        // needs some extra cleanup before shutdown, so we run for\n        // all entries in the debugStrings[] array.\n        //\n        // We could call std::string::clear() here, but clear()\n        // doesn't deallocate memory in std string, so we might\n        // as well let the default destructor do the cleanup,\n        // when using the default (AKA std::string) ddStr.\n        #ifdef DEBUG_DRAW_STR_DEALLOC_FUNC\n        for (int i = 0; i < DEBUG_DRAW_MAX_STRINGS; ++i)\n        {\n            DEBUG_DRAW_STR_DEALLOC_FUNC(DD_CONTEXT->debugStrings[i].text);\n        }\n        #endif // DEBUG_DRAW_STR_DEALLOC_FUNC\n\n        if (DD_CONTEXT->renderInterface != nullptr && DD_CONTEXT->glyphTexHandle != nullptr)\n        {\n            DD_CONTEXT->renderInterface->destroyGlyphTexture(DD_CONTEXT->glyphTexHandle);\n        }\n\n        DD_CONTEXT->~InternalContext(); // Destroy first\n        DD_MFREE(DD_CONTEXT);\n\n        #ifndef DEBUG_DRAW_EXPLICIT_CONTEXT\n        DD_CONTEXT = nullptr;\n        #endif // DEBUG_DRAW_EXPLICIT_CONTEXT\n    }\n}\n\nbool isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    return (DD_CONTEXT != nullptr && DD_CONTEXT->renderInterface != nullptr);\n}\n\nbool hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return false;\n    }\n    return (DD_CONTEXT->debugStringsCount + DD_CONTEXT->debugPointsCount + DD_CONTEXT->debugLinesCount) > 0;\n}\n\nvoid flush(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const std::int64_t currTimeMillis, const std::uint32_t flags)\n{\n    if (!hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    // Save the last know time value for next dd::line/dd::point calls.\n    DD_CONTEXT->currentTimeMillis = currTimeMillis;\n\n    // Let the user set common render states.\n    DD_CONTEXT->renderInterface->beginDraw();\n\n    // Issue the render calls:\n    if (flags & FlushLines)  { drawDebugLines(DD_EXPLICIT_CONTEXT_ONLY(ctx));   }\n    if (flags & FlushPoints) { drawDebugPoints(DD_EXPLICIT_CONTEXT_ONLY(ctx));  }\n    if (flags & FlushText)   { drawDebugStrings(DD_EXPLICIT_CONTEXT_ONLY(ctx)); }\n\n    // And cleanup if needed.\n    DD_CONTEXT->renderInterface->endDraw();\n\n    // Remove all expired objects, regardless of draw flags:\n    clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DD_CONTEXT->debugStrings, DD_CONTEXT->debugStringsCount);\n    clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DD_CONTEXT->debugPoints,  DD_CONTEXT->debugPointsCount);\n    clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DD_CONTEXT->debugLines,   DD_CONTEXT->debugLinesCount);\n}\n\nvoid clear(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx))\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    // Let the user cleanup the debug strings:\n    #ifdef DEBUG_DRAW_STR_DEALLOC_FUNC\n    for (int i = 0; i < DEBUG_DRAW_MAX_STRINGS; ++i)\n    {\n        DEBUG_DRAW_STR_DEALLOC_FUNC(DD_CONTEXT->debugStrings[i].text);\n    }\n    #endif // DEBUG_DRAW_STR_DEALLOC_FUNC\n\n    DD_CONTEXT->vertexBufferUsed  = 0;\n    DD_CONTEXT->debugStringsCount = 0;\n    DD_CONTEXT->debugPointsCount  = 0;\n    DD_CONTEXT->debugLinesCount   = 0;\n}\n\nvoid point(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In pos, ddVec3_In color,\n           const float size, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->debugPointsCount == DEBUG_DRAW_MAX_POINTS)\n    {\n        DEBUG_DRAW_OVERFLOWED(\"DEBUG_DRAW_MAX_POINTS limit reached! Dropping further debug point draws.\");\n        return;\n    }\n\n    DebugPoint & point     = DD_CONTEXT->debugPoints[DD_CONTEXT->debugPointsCount++];\n    point.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis;\n    point.depthEnabled     = depthEnabled;\n    point.size             = size;\n\n    vecCopy(point.position, pos);\n    vecCopy(point.color, color);\n}\n\nvoid line(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In from, ddVec3_In to,\n          ddVec3_In color, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->debugLinesCount == DEBUG_DRAW_MAX_LINES)\n    {\n        DEBUG_DRAW_OVERFLOWED(\"DEBUG_DRAW_MAX_LINES limit reached! Dropping further debug line draws.\");\n        return;\n    }\n\n    DebugLine & line      = DD_CONTEXT->debugLines[DD_CONTEXT->debugLinesCount++];\n    line.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis;\n    line.depthEnabled     = depthEnabled;\n\n    vecCopy(line.posFrom, from);\n    vecCopy(line.posTo, to);\n    vecCopy(line.color, color);\n}\n\nvoid screenText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const char * const str, ddVec3_In pos,\n                ddVec3_In color, const float scaling, const int durationMillis)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->glyphTexHandle == nullptr)\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->debugStringsCount == DEBUG_DRAW_MAX_STRINGS)\n    {\n        DEBUG_DRAW_OVERFLOWED(\"DEBUG_DRAW_MAX_STRINGS limit reached! Dropping further debug string draws.\");\n        return;\n    }\n\n    DebugString & dstr    = DD_CONTEXT->debugStrings[DD_CONTEXT->debugStringsCount++];\n    dstr.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis;\n    dstr.posX             = pos[X];\n    dstr.posY             = pos[Y];\n    dstr.scaling          = scaling;\n    dstr.text             = str;\n    dstr.centered         = false;\n    vecCopy(dstr.color, color);\n}\n\nvoid projectedText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const char * const str, ddVec3_In pos, ddVec3_In color,\n                   ddMat4x4_In vpMatrix, const int sx, const int sy, const int sw, const int sh, const float scaling,\n                   const int durationMillis)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->glyphTexHandle == nullptr)\n    {\n        return;\n    }\n\n    if (DD_CONTEXT->debugStringsCount == DEBUG_DRAW_MAX_STRINGS)\n    {\n        DEBUG_DRAW_OVERFLOWED(\"DEBUG_DRAW_MAX_STRINGS limit reached! Dropping further debug string draws.\");\n        return;\n    }\n\n    float tempPoint[4];\n    matTransformPointXYZW(tempPoint, pos, vpMatrix);\n\n    // Bail if W ended up as zero.\n    if (floatAbs(tempPoint[W]) < FloatEpsilon)\n    {\n        return;\n    }\n\n    // Bail if point is behind camera.\n    if (tempPoint[Z] < -tempPoint[W] || tempPoint[Z] > tempPoint[W])\n    {\n        return;\n    }\n    \n    // Perspective divide (we only care about the 2D part now):\n    tempPoint[X] /= tempPoint[W];\n    tempPoint[Y] /= tempPoint[W];\n\n    // Map to window coordinates:\n    float scrX = ((tempPoint[X] * 0.5f) + 0.5f) * sw + sx;\n    float scrY = ((tempPoint[Y] * 0.5f) + 0.5f) * sh + sy;\n\n    // Need to invert the direction because on OGL the screen origin is the bottom-left corner.\n    // NOTE: This is not renderer agnostic, I think... Should add a #define or something!\n    scrY = static_cast<float>(sh) - scrY;\n\n    DebugString & dstr    = DD_CONTEXT->debugStrings[DD_CONTEXT->debugStringsCount++];\n    dstr.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis;\n    dstr.posX             = scrX;\n    dstr.posY             = scrY;\n    dstr.scaling          = scaling;\n    dstr.text             = str;\n    dstr.centered         = true;\n    vecCopy(dstr.color, color);\n}\n\nvoid axisTriad(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddMat4x4_In transform, const float size,\n               const float length, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 p0, p1, p2, p3;\n    ddVec3 xEnd, yEnd, zEnd;\n    ddVec3 origin, cR, cG, cB;\n\n    vecSet(cR, 1.0f, 0.0f, 0.0f);\n    vecSet(cG, 0.0f, 1.0f, 0.0f);\n    vecSet(cB, 0.0f, 0.0f, 1.0f);\n\n    vecSet(origin, 0.0f, 0.0f, 0.0f);\n    vecSet(xEnd, length, 0.0f, 0.0f);\n    vecSet(yEnd, 0.0f, length, 0.0f);\n    vecSet(zEnd, 0.0f, 0.0f, length);\n\n    matTransformPointXYZ(p0, origin, transform);\n    matTransformPointXYZ(p1, xEnd, transform);\n    matTransformPointXYZ(p2, yEnd, transform);\n    matTransformPointXYZ(p3, zEnd, transform);\n\n    arrow(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p0, p1, cR, size, durationMillis, depthEnabled); // X: red axis\n    arrow(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p0, p2, cG, size, durationMillis, depthEnabled); // Y: green axis\n    arrow(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p0, p3, cB, size, durationMillis, depthEnabled); // Z: blue axis\n}\n\nvoid arrow(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In from, ddVec3_In to, ddVec3_In color,\n           const float size, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    static const float arrowStep = 30.0f; // In degrees\n    static const float arrowSin[45] = {\n        0.0f, 0.5f, 0.866025f, 1.0f, 0.866025f, 0.5f, -0.0f, -0.5f, -0.866025f,\n        -1.0f, -0.866025f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f\n    };\n    static const float arrowCos[45] = {\n        1.0f, 0.866025f, 0.5f, -0.0f, -0.5f, -0.866026f, -1.0f, -0.866025f, -0.5f, 0.0f,\n        0.5f, 0.866026f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,\n        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f\n    };\n\n    // Body line:\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, color, durationMillis, depthEnabled);\n\n    // Aux vectors to compute the arrowhead:\n    ddVec3 up, right, forward;\n    vecSub(forward, to, from);\n    vecNormalize(forward, forward);\n    vecOrthogonalBasis(right, up, forward);\n    vecScale(forward, forward, size);\n\n    // Arrowhead is a cone (sin/cos tables used here):\n    float degrees = 0.0f;\n    for (int i = 0; degrees < 360.0f; degrees += arrowStep, ++i)\n    {\n        float scale;\n        ddVec3 v1, v2, temp;\n\n        scale = 0.5f * size * arrowCos[i];\n        vecScale(temp, right, scale);\n        vecSub(v1, to, forward);\n        vecAdd(v1, v1, temp);\n\n        scale = 0.5f * size * arrowSin[i];\n        vecScale(temp, up, scale);\n        vecAdd(v1, v1, temp);\n\n        scale = 0.5f * size * arrowCos[i + 1];\n        vecScale(temp, right, scale);\n        vecSub(v2, to, forward);\n        vecAdd(v2, v2, temp);\n\n        scale = 0.5f * size * arrowSin[i + 1];\n        vecScale(temp, up, scale);\n        vecAdd(v2, v2, temp);\n\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v1, to, color, durationMillis, depthEnabled);\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v1, v2, color, durationMillis, depthEnabled);\n    }\n}\n\nvoid cross(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, const float length,\n           const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 from, to;\n    ddVec3 cR, cG, cB;\n\n    vecSet(cR, 1.0f, 0.0f, 0.0f);\n    vecSet(cG, 0.0f, 1.0f, 0.0f);\n    vecSet(cB, 0.0f, 0.0f, 1.0f);\n\n    const float cx = center[X];\n    const float cy = center[Y];\n    const float cz = center[Z];\n    const float hl = length * 0.5f; // Half on each side.\n\n    // Red line: X - length/2 to X + length/2\n    vecSet(from, cx - hl, cy, cz);\n    vecSet(to,   cx + hl, cy, cz);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, cR, durationMillis, depthEnabled);\n\n    // Green line: Y - length/2 to Y + length/2\n    vecSet(from, cx, cy - hl, cz);\n    vecSet(to,   cx, cy + hl, cz);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, cG, durationMillis, depthEnabled);\n\n    // Blue line: Z - length/2 to Z + length/2\n    vecSet(from, cx, cy, cz - hl);\n    vecSet(to,   cx, cy, cz + hl);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, cB, durationMillis, depthEnabled);\n}\n\nvoid circle(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In planeNormal, ddVec3_In color,\n            const float radius, const float numSteps, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 left, up;\n    ddVec3 point, lastPoint;\n\n    vecOrthogonalBasis(left, up, planeNormal);\n\n    vecScale(up, up, radius);\n    vecScale(left, left, radius);\n    vecAdd(lastPoint, center, up);\n\n    for (int i = 1; i <= numSteps; ++i)\n    {\n        const float radians = TAU * i / numSteps;\n\n        ddVec3 vs, vc;\n        vecScale(vs, left, floatSin(radians));\n        vecScale(vc, up,   floatCos(radians));\n\n        vecAdd(point, center, vs);\n        vecAdd(point, point,  vc);\n\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastPoint, point, color, durationMillis, depthEnabled);\n        vecCopy(lastPoint, point);\n    }\n}\n\nvoid plane(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In planeNormal, ddVec3_In planeColor,\n           ddVec3_In normalVecColor, const float planeScale, const float normalVecScale, const int durationMillis,\n           const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 v1, v2, v3, v4;\n    ddVec3 tangent, bitangent;\n    vecOrthogonalBasis(tangent, bitangent, planeNormal);\n\n    // A little bit of preprocessor voodoo to make things more interesting :P\n    #define DD_PLANE_V(v, op1, op2) \\\n    v[X] = (center[X] op1 (tangent[X] * planeScale) op2 (bitangent[X] * planeScale)); \\\n    v[Y] = (center[Y] op1 (tangent[Y] * planeScale) op2 (bitangent[Y] * planeScale)); \\\n    v[Z] = (center[Z] op1 (tangent[Z] * planeScale) op2 (bitangent[Z] * planeScale))\n    DD_PLANE_V(v1, -, -);\n    DD_PLANE_V(v2, +, -);\n    DD_PLANE_V(v3, +, +);\n    DD_PLANE_V(v4, -, +);\n    #undef DD_PLANE_V\n\n    // Draw the wireframe plane quadrilateral:\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v1, v2, planeColor, durationMillis, depthEnabled);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v2, v3, planeColor, durationMillis, depthEnabled);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v3, v4, planeColor, durationMillis, depthEnabled);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v4, v1, planeColor, durationMillis, depthEnabled);\n\n    // Optionally add a line depicting the plane normal:\n    if (normalVecScale != 0.0f)\n    {\n        ddVec3 normalVec;\n        normalVec[X] = (planeNormal[X] * normalVecScale) + center[X];\n        normalVec[Y] = (planeNormal[Y] * normalVecScale) + center[Y];\n        normalVec[Z] = (planeNormal[Z] * normalVecScale) + center[Z];\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) center, normalVec, normalVecColor, durationMillis, depthEnabled);\n    }\n}\n\nvoid sphere(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In color,\n            const float radius, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    static const int stepSize = 15;\n    ddVec3 cache[360 / stepSize];\n    ddVec3 radiusVec;\n\n    vecSet(radiusVec, 0.0f, 0.0f, radius);\n    vecAdd(cache[0], center, radiusVec);\n\n    for (int n = 1; n < arrayLength(cache); ++n)\n    {\n        vecCopy(cache[n], cache[0]);\n    }\n\n    ddVec3 lastPoint, temp;\n    for (int i = stepSize; i <= 360; i += stepSize)\n    {\n        const float s = floatSin(degreesToRadians(i));\n        const float c = floatCos(degreesToRadians(i));\n\n        lastPoint[X] = center[X];\n        lastPoint[Y] = center[Y] + radius * s;\n        lastPoint[Z] = center[Z] + radius * c;\n\n        for (int n = 0, j = stepSize; j <= 360; j += stepSize, ++n)\n        {\n            temp[X] = center[X] + floatSin(degreesToRadians(j)) * radius * s;\n            temp[Y] = center[Y] + floatCos(degreesToRadians(j)) * radius * s;\n            temp[Z] = lastPoint[Z];\n\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastPoint, temp, color, durationMillis, depthEnabled);\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastPoint, cache[n], color, durationMillis, depthEnabled);\n\n            vecCopy(cache[n], lastPoint);\n            vecCopy(lastPoint, temp);\n        }\n    }\n}\n\nvoid cone(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In apex, ddVec3_In dir, ddVec3_In color,\n          const float baseRadius, const float apexRadius, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    static const int stepSize = 20;\n    ddVec3 axis[3];\n    ddVec3 top, temp0, temp1, temp2;\n    ddVec3 p1, p2, lastP1, lastP2;\n\n    vecCopy(axis[2], dir);\n    vecNormalize(axis[2], axis[2]);\n    vecOrthogonalBasis(axis[0], axis[1], axis[2]);\n\n    axis[1][X] = -axis[1][X];\n    axis[1][Y] = -axis[1][Y];\n    axis[1][Z] = -axis[1][Z];\n\n    vecAdd(top, apex, dir);\n    vecScale(temp1, axis[1], baseRadius);\n    vecAdd(lastP2, top, temp1);\n\n    if (apexRadius == 0.0f)\n    {\n        for (int i = stepSize; i <= 360; i += stepSize)\n        {\n            vecScale(temp1, axis[0], floatSin(degreesToRadians(i)));\n            vecScale(temp2, axis[1], floatCos(degreesToRadians(i)));\n            vecAdd(temp0, temp1, temp2);\n\n            vecScale(temp0, temp0, baseRadius);\n            vecAdd(p2, top, temp0);\n\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastP2, p2, color, durationMillis, depthEnabled);\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p2, apex, color, durationMillis, depthEnabled);\n\n            vecCopy(lastP2, p2);\n        }\n    }\n    else // A degenerate cone with open apex:\n    {\n        vecScale(temp1, axis[1], apexRadius);\n        vecAdd(lastP1, apex, temp1);\n\n        for (int i = stepSize; i <= 360; i += stepSize)\n        {\n            vecScale(temp1, axis[0], floatSin(degreesToRadians(i)));\n            vecScale(temp2, axis[1], floatCos(degreesToRadians(i)));\n            vecAdd(temp0, temp1, temp2);\n\n            vecScale(temp1, temp0, apexRadius);\n            vecScale(temp2, temp0, baseRadius);\n\n            vecAdd(p1, apex, temp1);\n            vecAdd(p2, top,  temp2);\n\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastP1, p1, color, durationMillis, depthEnabled);\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastP2, p2, color, durationMillis, depthEnabled);\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p1, p2, color, durationMillis, depthEnabled);\n\n            vecCopy(lastP1, p1);\n            vecCopy(lastP2, p2);\n        }\n    }\n}\n\nvoid box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const ddVec3 points[8], ddVec3_In color,\n         const int durationMillis, const bool depthEnabled)\n{\n    // Build the lines from points using clever indexing tricks:\n    // (& 3 is a fancy way of doing % 4, but avoids the expensive modulo operation)\n    for (int i = 0; i < 4; ++i)\n    {\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points[i], points[(i + 1) & 3], color, durationMillis, depthEnabled);\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points[4 + i], points[4 + ((i + 1) & 3)], color, durationMillis, depthEnabled);\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points[i], points[4 + i], color, durationMillis, depthEnabled);\n    }\n}\n\nvoid box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In color, const float width,\n         const float height, const float depth, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    const float cx = center[X];\n    const float cy = center[Y];\n    const float cz = center[Z];\n    const float w  = width  * 0.5f;\n    const float h  = height * 0.5f;\n    const float d  = depth  * 0.5f;\n\n    // Create all the 8 points:\n    ddVec3 points[8];\n    #define DD_BOX_V(v, op1, op2, op3) \\\n    v[X] = cx op1 w; \\\n    v[Y] = cy op2 h; \\\n    v[Z] = cz op3 d\n    DD_BOX_V(points[0], -, +, +);\n    DD_BOX_V(points[1], -, +, -);\n    DD_BOX_V(points[2], +, +, -);\n    DD_BOX_V(points[3], +, +, +);\n    DD_BOX_V(points[4], -, -, +);\n    DD_BOX_V(points[5], -, -, -);\n    DD_BOX_V(points[6], +, -, -);\n    DD_BOX_V(points[7], +, -, +);\n    #undef DD_BOX_V\n\n    box(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points, color, durationMillis, depthEnabled);\n}\n\nvoid aabb(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In mins, ddVec3_In maxs,\n          ddVec3_In color, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 bb[2];\n    ddVec3 points[8];\n\n    vecCopy(bb[0], mins);\n    vecCopy(bb[1], maxs);\n\n    // Expand min/max bounds:\n    for (int i = 0; i < arrayLength(points); ++i)\n    {\n        points[i][X] = bb[(i ^ (i >> 1)) & 1][X];\n        points[i][Y] = bb[(i >> 1) & 1][Y];\n        points[i][Z] = bb[(i >> 2) & 1][Z];\n    }\n\n    // Build the lines:\n    box(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points, color, durationMillis, depthEnabled);\n}\n\nvoid frustum(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddMat4x4_In invClipMatrix,\n             ddVec3_In color, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    // Start with the standard clip volume, then bring it back to world space.\n    static const float planes[8][3] = {\n        // near plane\n        { -1.0f, -1.0f, -1.0f }, {  1.0f, -1.0f, -1.0f },\n        {  1.0f,  1.0f, -1.0f }, { -1.0f,  1.0f, -1.0f },\n        // far plane\n        { -1.0f, -1.0f,  1.0f }, {  1.0f, -1.0f,  1.0f },\n        {  1.0f,  1.0f,  1.0f }, { -1.0f,  1.0f,  1.0f }\n    };\n\n    ddVec3 points[8];\n    float wCoords[8];\n\n    // Transform the planes by the inverse clip matrix:\n    for (int i = 0; i < arrayLength(planes); ++i)\n    {\n        wCoords[i] = matTransformPointXYZW2(points[i], planes[i], invClipMatrix);\n    }\n\n    // Divide by the W component of each:\n    for (int i = 0; i < arrayLength(planes); ++i)\n    {\n        // But bail if any W ended up as zero.\n        if (floatAbs(wCoords[W]) < FloatEpsilon)\n        {\n            return;\n        }\n\n        points[i][X] /= wCoords[i];\n        points[i][Y] /= wCoords[i];\n        points[i][Z] /= wCoords[i];\n    }\n\n    // Connect the dots:\n    box(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points, color, durationMillis, depthEnabled);\n}\n\nvoid vertexNormal(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In origin, ddVec3_In normal,\n                  const float length, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 normalVec;\n    ddVec3 normalColor;\n\n    vecSet(normalColor, 1.0f, 1.0f, 1.0f);\n\n    normalVec[X] = (normal[X] * length) + origin[X];\n    normalVec[Y] = (normal[Y] * length) + origin[Y];\n    normalVec[Z] = (normal[Z] * length) + origin[Z];\n\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, normalVec, normalColor, durationMillis, depthEnabled);\n}\n\nvoid tangentBasis(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In origin, ddVec3_In normal, ddVec3_In tangent,\n                  ddVec3_In bitangent, const float lengths, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 cN, cT, cB;\n    ddVec3 vN, vT, vB;\n\n    vecSet(cN, 1.0f, 1.0f, 1.0f); // Vertex normals are WHITE\n    vecSet(cT, 1.0f, 1.0f, 0.0f); // Tangents are YELLOW\n    vecSet(cB, 1.0f, 0.0f, 1.0f); // Bi-tangents are MAGENTA\n\n    vN[X] = (normal[X] * lengths) + origin[X];\n    vN[Y] = (normal[Y] * lengths) + origin[Y];\n    vN[Z] = (normal[Z] * lengths) + origin[Z];\n\n    vT[X] = (tangent[X] * lengths) + origin[X];\n    vT[Y] = (tangent[Y] * lengths) + origin[Y];\n    vT[Z] = (tangent[Z] * lengths) + origin[Z];\n\n    vB[X] = (bitangent[X] * lengths) + origin[X];\n    vB[Y] = (bitangent[Y] * lengths) + origin[Y];\n    vB[Z] = (bitangent[Z] * lengths) + origin[Z];\n\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, vN, cN, durationMillis, depthEnabled);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, vT, cT, durationMillis, depthEnabled);\n    line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, vB, cB, durationMillis, depthEnabled);\n}\n\nvoid xzSquareGrid(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const float mins, const float maxs, const float y,\n                  const float step, ddVec3_In color, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    ddVec3 from, to;\n    for (float i = mins; i <= maxs; i += step)\n    {\n        // Horizontal line (along the X)\n        vecSet(from, mins, y, i);\n        vecSet(to,   maxs, y, i);\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, color, durationMillis, depthEnabled);\n\n        // Vertical line (along the Z)\n        vecSet(from, i, y, mins);\n        vecSet(to,   i, y, maxs);\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, color, durationMillis, depthEnabled);\n    }\n}\n\nvoid capsule(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In axis, \n    float length, float radius, ddVec3_In color, const int durationMillis, const bool depthEnabled)\n{\n    if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx)))\n    {\n        return;\n    }\n\n    // Normalize the axis vector\n    float magnitude = sqrt(axis[X] * axis[X] + axis[Y] * axis[Y] + axis[Z] * axis[Z]);\n    if (magnitude == 0.0f)\n    {\n        return; // Invalid axis, exit gracefully\n    }\n    ddVec3 dir;\n    vecScale(dir, axis, 1.0f / magnitude);\n\n    // Compute endpoints (centers of the hemispheres)\n    ddVec3 temp;\n    vecScale(temp, dir, length / 2.0f);\n    ddVec3 p1, p2;\n    vecSub(p1, center, temp); // Start point\n    vecAdd(p2, center, temp); // End point\n\n    // Find vectors u and v perpendicular to dir for the cross-section plane\n    ddVec3 u, v, tempVec;\n    // Choose a vector not parallel to dir\n    if (fabs(dir[X]) <= fabs(dir[Y]) && fabs(dir[X]) <= fabs(dir[Z]))\n    {\n        vecSet(tempVec, 1.0f, 0.0f, 0.0f);\n    }\n    else if (fabs(dir[Y]) <= fabs(dir[Z]))\n    {\n        vecSet(tempVec, 0.0f, 1.0f, 0.0f);\n    }\n    else\n    {\n        vecSet(tempVec, 0.0f, 0.0f, 1.0f);\n    }\n    vecCross(u, tempVec, dir);\n    float uMag = sqrt(u[X] * u[X] + u[Y] * u[Y] + u[Z] * u[Z]);\n    vecScale(u, u, 1.0f / uMag);\n    vecCross(v, dir, u); // v is already unit length since dir and u are orthonormal\n\n    static const int stepSize = 15;\n\n    // Draw the cylinder\n    for (int j = 0; j < 360; j += stepSize)\n    {\n        float theta = degreesToRadians((float)j);\n        float theta2 = degreesToRadians((float)(j + stepSize));\n        ddVec3 point1, point2, point3, point4;\n\n        float c = floatCos(theta);\n        float s = floatSin(theta);\n        float c2 = floatCos(theta2);\n        float s2 = floatSin(theta2);\n\n        // Circle at p1\n        vecSet(point1, p1[X] + radius * (c * u[X] + s * v[X]),\n            p1[Y] + radius * (c * u[Y] + s * v[Y]),\n            p1[Z] + radius * (c * u[Z] + s * v[Z]));\n        vecSet(point2, p1[X] + radius * (c2 * u[X] + s2 * v[X]),\n            p1[Y] + radius * (c2 * u[Y] + s2 * v[Y]),\n            p1[Z] + radius * (c2 * u[Z] + s2 * v[Z]));\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point2, color, durationMillis, depthEnabled);\n\n        // Circle at p2\n        vecSet(point3, p2[X] + radius * (c * u[X] + s * v[X]),\n            p2[Y] + radius * (c * u[Y] + s * v[Y]),\n            p2[Z] + radius * (c * u[Z] + s * v[Z]));\n        vecSet(point4, p2[X] + radius * (c2 * u[X] + s2 * v[X]),\n            p2[Y] + radius * (c2 * u[Y] + s2 * v[Y]),\n            p2[Z] + radius * (c2 * u[Z] + s2 * v[Z]));\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point3, point4, color, durationMillis, depthEnabled);\n\n        // Connecting line between circles\n        line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point3, color, durationMillis, depthEnabled);\n    }\n\n    // Draw hemisphere at p1 (dome along -dir)\n    ddVec3 d1;\n    vecScale(d1, dir, -1.0f); // Direction for p1 hemisphere\n    for (int i = 0; i <= 90; i += stepSize)\n    {\n        float phi = degreesToRadians((float)i);\n        float s = floatSin(phi);\n        float c = floatCos(phi);\n\n        for (int j = 0; j < 360; j += stepSize)\n        {\n            float theta = degreesToRadians((float)j);\n            float theta2 = degreesToRadians((float)(j + stepSize));\n            ddVec3 point1, point2;\n\n            vecSet(point1, p1[X] + radius * (s * floatCos(theta) * u[X] + s * floatSin(theta) * v[X] + c * d1[X]),\n                p1[Y] + radius * (s * floatCos(theta) * u[Y] + s * floatSin(theta) * v[Y] + c * d1[Y]),\n                p1[Z] + radius * (s * floatCos(theta) * u[Z] + s * floatSin(theta) * v[Z] + c * d1[Z]));\n            vecSet(point2, p1[X] + radius * (s * floatCos(theta2) * u[X] + s * floatSin(theta2) * v[X] + c * d1[X]),\n                p1[Y] + radius * (s * floatCos(theta2) * u[Y] + s * floatSin(theta2) * v[Y] + c * d1[Y]),\n                p1[Z] + radius * (s * floatCos(theta2) * u[Z] + s * floatSin(theta2) * v[Z] + c * d1[Z]));\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point2, color, durationMillis, depthEnabled);\n\n            if (i < 90)\n            {\n                float phi2 = degreesToRadians((float)(i + stepSize));\n                float s2 = floatSin(phi2);\n                float c2 = floatCos(phi2);\n                ddVec3 point3;\n                vecSet(point3, p1[X] + radius * (s2 * floatCos(theta) * u[X] + s2 * floatSin(theta) * v[X] + c2 * d1[X]),\n                    p1[Y] + radius * (s2 * floatCos(theta) * u[Y] + s2 * floatSin(theta) * v[Y] + c2 * d1[Y]),\n                    p1[Z] + radius * (s2 * floatCos(theta) * u[Z] + s2 * floatSin(theta) * v[Z] + c2 * d1[Z]));\n                line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point3, color, durationMillis, depthEnabled);\n            }\n        }\n    }\n\n    // Draw hemisphere at p2 (dome along +dir)\n    for (int i = 0; i <= 90; i += stepSize)\n    {\n        float phi = degreesToRadians((float)i);\n        float s = floatSin(phi);\n        float c = floatCos(phi);\n\n        for (int j = 0; j < 360; j += stepSize)\n        {\n            float theta = degreesToRadians((float)j);\n            float theta2 = degreesToRadians((float)(j + stepSize));\n            ddVec3 point1, point2;\n\n            vecSet(point1, p2[X] + radius * (s * floatCos(theta) * u[X] + s * floatSin(theta) * v[X] + c * dir[X]),\n                p2[Y] + radius * (s * floatCos(theta) * u[Y] + s * floatSin(theta) * v[Y] + c * dir[Y]),\n                p2[Z] + radius * (s * floatCos(theta) * u[Z] + s * floatSin(theta) * v[Z] + c * dir[Z]));\n            vecSet(point2, p2[X] + radius * (s * floatCos(theta2) * u[X] + s * floatSin(theta2) * v[X] + c * dir[X]),\n                p2[Y] + radius * (s * floatCos(theta2) * u[Y] + s * floatSin(theta2) * v[Y] + c * dir[Y]),\n                p2[Z] + radius * (s * floatCos(theta2) * u[Z] + s * floatSin(theta2) * v[Z] + c * dir[Z]));\n            line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point2, color, durationMillis, depthEnabled);\n\n            if (i < 90)\n            {\n                float phi2 = degreesToRadians((float)(i + stepSize));\n                float s2 = floatSin(phi2);\n                float c2 = floatCos(phi2);\n                ddVec3 point3;\n                vecSet(point3, p2[X] + radius * (s2 * floatCos(theta) * u[X] + s2 * floatSin(theta) * v[X] + c2 * dir[X]),\n                    p2[Y] + radius * (s2 * floatCos(theta) * u[Y] + s2 * floatSin(theta) * v[Y] + c2 * dir[Y]),\n                    p2[Z] + radius * (s2 * floatCos(theta) * u[Z] + s2 * floatSin(theta) * v[Z] + c2 * dir[Z]));\n                line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point3, color, durationMillis, depthEnabled);\n            }\n        }\n    }\n}\n\n// ========================================================\n// RenderInterface stubs:\n// ========================================================\n\nRenderInterface::~RenderInterface()                                              { }\nvoid RenderInterface::beginDraw()                                                { }\nvoid RenderInterface::endDraw()                                                  { }\nvoid RenderInterface::drawPointList(const DrawVertex *, int, bool)               { }\nvoid RenderInterface::drawLineList(const DrawVertex *, int, bool)                { }\nvoid RenderInterface::drawGlyphList(const DrawVertex *, int, GlyphTextureHandle) { }\nvoid RenderInterface::destroyGlyphTexture(GlyphTextureHandle)                    { }\nGlyphTextureHandle RenderInterface::createGlyphTexture(int, int, const void *)   { return nullptr; }\n\n} // namespace dd\n\n#undef DD_CONTEXT\n#undef DD_MALLOC\n#undef DD_MFREE\n\n// ================ End of implementation =================\n#endif // DEBUG_DRAW_IMPLEMENTATION\n// ================ End of implementation =================\n\n"
  },
  {
    "path": "samples/Makefile",
    "content": "\n#------------------------------------------------\n# Brief: Makefile for the Debug Draw samples.\n#\n# Remarks:\n# - Tested only on Mac OSX; Should work on Linux.\n# - GLFW must be installed on the system.\n#   (http://www.glfw.org)\n#------------------------------------------------\n\n# Select the proper OpenGL library for Mac (-framework OpenGL)\n# or use a default (-lGL) that should work on most Unix-like systems.\n# This script also assumes GLFW is installed and available in the system path.\nUNAME = $(shell uname -s)\nifeq ($(UNAME), Darwin)\n  OPENGL_LIB = -framework CoreFoundation -framework OpenGL\nelse\n  OPENGL_LIB = -lGL\nendif\n\n# GLFW Should be installed and visible in the system path!\nifeq ($(UNAME), Darwin)\n  CXXFLAGS += -Weffc++\n  GLFW_LIB  = -L/usr/local/lib -lglfw\n  LIBRARIES = -framework Cocoa -framework IOKit -framework CoreVideo\nendif\nifeq ($(UNAME), Linux)\n  CXXFLAGS += `pkg-config --cflags glfw3`\n  GLFW_LIB  = `pkg-config --static --libs glfw3`\nendif\n\n# Compile an Address Sanitizer build if this flag is set\nifdef ASAN\n  CXXFLAGS += -g -fsanitize=address -fno-omit-frame-pointer\nendif\n\n# Define 'VERBOSE' to get the full console output.\n# Otherwise we print a shorter message for each rule.\nifndef VERBOSE\n  QUIET          = @\n  ECHO_COMPILING = @echo \"-> Building Debug Draw samples ...\"\n  ECHO_CLEANING  = @echo \"-> Cleaning ...\"\nendif\n\n#------------------------------------------------\n# Macros / source files:\n#------------------------------------------------\n\nLIBRARIES += $(OPENGL_LIB) $(GLFW_LIB)\nINC_DIRS   = -I. -I.. -Ivectormath -Igl3w/include\nCXXFLAGS  += $(INC_DIRS) -std=c++11 -O3 -Wall -Wextra -Winit-self -Wunused -Wshadow -Wno-strict-aliasing\nCFLAGS     = $(CXXFLAGS)\n\n# Null renderer sample:\nSRC_FILES_NULL_SAMP  = sample_null_renderer.cpp\nBIN_TARGET_NULL_SAMP = sample_null_renderer\n\n# Legacy OpenGL sample:\nSRC_FILES_GL_LEGACY_SAMP  = sample_gl_legacy.cpp\nBIN_TARGET_GL_LEGACY_SAMP = sample_gl_legacy\n\n# Core OpenGL sample:\nSRC_FILES_GL_CORE_SAMP  = gl3w/src/gl3w.cpp sample_gl_core.cpp\nBIN_TARGET_GL_CORE_SAMP = sample_gl_core\n\n# Multi-threaded sample with explicit context:\nSRC_FILES_GL_CORE_MT_SAMP_1  = gl3w/src/gl3w.cpp sample_gl_core_multithreaded_explicit.cpp\nBIN_TARGET_GL_CORE_MT_SAMP_1 = sample_gl_core_multithreaded_explicit\n\n# Multi-threaded sample with thread-local implicit context:\nSRC_FILES_GL_CORE_MT_SAMP_2  = gl3w/src/gl3w.cpp sample_gl_core_multithreaded_tls.cpp\nBIN_TARGET_GL_CORE_MT_SAMP_2 = sample_gl_core_multithreaded_tls\n\n#------------------------------------------------\n# Build rules:\n#------------------------------------------------\n\nall:\n\t$(ECHO_COMPILING)\n\t$(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_NULL_SAMP) -o $(BIN_TARGET_NULL_SAMP)\n\t$(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_LEGACY_SAMP) -o $(BIN_TARGET_GL_LEGACY_SAMP) $(LIBRARIES)\n\t$(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_CORE_SAMP) -o $(BIN_TARGET_GL_CORE_SAMP) $(LIBRARIES)\n\t$(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_CORE_MT_SAMP_1) -o $(BIN_TARGET_GL_CORE_MT_SAMP_1) $(LIBRARIES)\n\t$(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_CORE_MT_SAMP_2) -o $(BIN_TARGET_GL_CORE_MT_SAMP_2) $(LIBRARIES)\n\nclean:\n\t$(ECHO_CLEANING)\n\t$(QUIET) rm -f $(BIN_TARGET_NULL_SAMP)\n\t$(QUIET) rm -f $(BIN_TARGET_GL_LEGACY_SAMP)\n\t$(QUIET) rm -f $(BIN_TARGET_GL_CORE_SAMP)\n\t$(QUIET) rm -f $(BIN_TARGET_GL_CORE_MT_SAMP_1)\n\t$(QUIET) rm -f $(BIN_TARGET_GL_CORE_MT_SAMP_2)\n\t$(QUIET) rm -rf *.dSYM\n\n"
  },
  {
    "path": "samples/README.md",
    "content": "\n### Debug Draw Samples\n\nThree sample programs showing basic usage of the Debug Draw library are currently provided:\n\n- `sample_null_renderer.cpp`: Just a tiny `main()` that calls a couple functions and exists.\n  This sample is meant only to test if the library will compile without errors.\n\n- `sample_gl_core.cpp`: Sample using core (shader-based) OpenGL that draws a handful of debug\n  shapes using the library. You can move around using `W,A,S,D` or the arrow keys. Click on the\n  window and drag the mouse to rotate the camera. This sample requires OpenGL version 3.2 or newer.\n\n- `sample_gl_legacy.cpp`: Exact same as the core GL sample, but uses a legacy (AKA fixed-function)\n  OpenGL renderer instead.\n\n- `sample_gl_core_multithreaded_tls.cpp` and `sample_gl_core_multithreaded_explicit.cpp` are\n  similar to the Core OpenGL sample but demonstrate how to use the TLS or explicit context modes.\n\n- `sample_d3d11.cpp`: Windows sample using D3D11 as the renderer interface for Debug Draw.\n\n- `samples_common.hpp`: Contains code shared by all samples, such as input handling and camera/controls.\n\n----\n\nTo build the samples on Linux or MacOS, run the provided Makefile.\nFor Windows, Visual Studio projects are included for VS2015.\n\nThe only external dependency required to build the samples is [GLFW](http://www.glfw.org/). Make sure to install\nit before attempting to build them. [GL3W](https://github.com/skaslev/gl3w) is our extension wrangler\nfor the Core OpenGL sample. It is included here and builds with DD. Sony's Vectormath library is also\na dependency, but it is included as well. Those libraries are only required for the samples and\nnot by Debug Draw itself.\n\nThe samples have only been officially tested on MacOS and Windows 7 & 10, though should build and run fine\non Linux, provided that you have GLFW installed. Running them requires at least OpenGL v3.2, but due\nto hardware differences there's no guarantee that they will render the expected outputs, even if your machine supports GL3+.\nLittle to no handling is done to account for GL version and hardware differences, so the samples might not run properly on your hardware.\n\nThe main idea is that they serve as a rough guide on how to integrate Debug Draw into your own projects,\nso there's more value in the code itself than in the demo applications, which are just drawing some line\nshapes in the 3D world and some HUD text, nothing more.\n\n"
  },
  {
    "path": "samples/gl3w/README.rst",
    "content": "========================================\ngl3w: Simple OpenGL core profile loading\n========================================\n\nIntroduction\n------------\n\ngl3w_ is the easiest way to get your hands on the functionality offered by the\nOpenGL core profile specification.\n\nIts main part is a simple gl3w_gen.py_ Python script that downloads the\nKhronos_ supported glcorearb.h_ header and generates gl3w.h and gl3w.c from it.\nThose files can then be added and linked (statically or dynamically) into your\nproject.\n\nRequirements\n------------\n\ngl3w_gen.py_ requires Python version 2.6 or newer, with SSL support.\nIt is also compatible with Python 3.x.\n\nExample\n-------\n\nHere is a simple example of using gl3w_ with glut. Note that GL/gl3w.h must be\nincluded before any other OpenGL related headers::\n\n    #include <stdio.h>\n    #include <GL/gl3w.h>\n    #include <GL/glut.h>\n\n    // ...\n\n    int main(int argc, char **argv)\n    {\n            glutInit(&argc, argv);\n            glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);\n            glutInitWindowSize(width, height);\n            glutCreateWindow(\"cookie\");\n\n            glutReshapeFunc(reshape);\n            glutDisplayFunc(display);\n            glutKeyboardFunc(keyboard);\n            glutSpecialFunc(special);\n            glutMouseFunc(mouse);\n            glutMotionFunc(motion);\n\n            if (gl3wInit()) {\n                    fprintf(stderr, \"failed to initialize OpenGL\\n\");\n                    return -1;\n            }\n            if (!gl3wIsSupported(3, 2)) {\n                    fprintf(stderr, \"OpenGL 3.2 not supported\\n\");\n                    return -1;\n            }\n            printf(\"OpenGL %s, GLSL %s\\n\", glGetString(GL_VERSION),\n                   glGetString(GL_SHADING_LANGUAGE_VERSION));\n\n            // ...\n\n            glutMainLoop();\n            return 0;\n    }\n\nAPI Reference\n-------------\n\nThe gl3w_ API consists of just three functions:\n\n``int gl3wInit(void)``\n\n    Initializes the library. Should be called once after an OpenGL context has\n    been created. Returns ``0`` when gl3w_ was initialized successfully,\n    ``-1`` if there was an error.\n\n``int gl3wIsSupported(int major, int minor)``\n\n    Returns ``1`` when OpenGL core profile version *major.minor* is available\n    and ``0`` otherwise.\n\n``GL3WglProc gl3wGetProcAddress(const char *proc)``\n\n    Returns the address of an OpenGL extension function. Generally, you won't\n    need to use it since gl3w_ loads all functions defined in the OpenGL core\n    profile on initialization. It allows you to load OpenGL extensions outside\n    of the core profile.\n\nLicense\n-------\n\ngl3w_ is in the public domain. See the file UNLICENSE for more information.\n\nCredits\n-------\n\nSlavomir Kaslev <slavomir.kaslev@gmail.com>\n    Initial implementation\n\nKelvin McDowell\n    Mac OS X support\n\nSjors Gielen\n    Mac OS X support\n\nTravis Gesslein\n    Patches regarding glcorearb.h\n\nArthur Tombs\n    Port to Python 3\n\nRommel160 [github.com/Rommel160]\n    Code contributions\n\nCopyright\n---------\n\nOpenGL_ is a registered trademark of SGI_.\n\n.. _gl3w: https://github.com/skaslev/gl3w\n.. _gl3w_gen.py: https://github.com/skaslev/gl3w/blob/master/gl3w_gen.py\n.. _glcorearb.h: https://www.opengl.org/registry/api/GL/glcorearb.h\n.. _OpenGL: http://www.opengl.org/\n.. _Khronos: http://www.khronos.org/\n.. _SGI: http://www.sgi.com/\n"
  },
  {
    "path": "samples/gl3w/UNLICENSE",
    "content": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, compile, sell, or\ndistribute this software, either in source code form or as a compiled\nbinary, for any purpose, commercial or non-commercial, and by any\nmeans.\n\nIn jurisdictions that recognize copyright laws, the author or authors\nof this software dedicate any and all copyright interest in the\nsoftware to the public domain. We make this dedication for the benefit\nof the public at large and to the detriment of our heirs and\nsuccessors. We intend this dedication to be an overt act of\nrelinquishment in perpetuity of all present and future rights to this\nsoftware under copyright law.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "samples/gl3w/gl3w_gen.py",
    "content": "#!/usr/bin/env python\n\n#   This file is part of gl3w, hosted at https://github.com/skaslev/gl3w\n#\n#   This is free and unencumbered software released into the public domain.\n#\n#   Anyone is free to copy, modify, publish, use, compile, sell, or\n#   distribute this software, either in source code form or as a compiled\n#   binary, for any purpose, commercial or non-commercial, and by any\n#   means.\n#\n#   In jurisdictions that recognize copyright laws, the author or authors\n#   of this software dedicate any and all copyright interest in the\n#   software to the public domain. We make this dedication for the benefit\n#   of the public at large and to the detriment of our heirs and\n#   successors. We intend this dedication to be an overt act of\n#   relinquishment in perpetuity of all present and future rights to this\n#   software under copyright law.\n#\n#   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n#   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n#   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n#   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n#   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n#   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n#   OTHER DEALINGS IN THE SOFTWARE.\n\n# Allow Python 2.6+ to use the print() function\nfrom __future__ import print_function\n\nimport re\nimport os\n\n# Try to import Python 3 library urllib.request\n# and if it fails, fall back to Python 2 urllib2\ntry:\n    import urllib.request as urllib2\nexcept ImportError:\n    import urllib2\n\n# UNLICENSE copyright header\nUNLICENSE = br'''/*\n\n    This file was generated with gl3w_gen.py, part of gl3w\n    (hosted at https://github.com/skaslev/gl3w)\n\n    This is free and unencumbered software released into the public domain.\n\n    Anyone is free to copy, modify, publish, use, compile, sell, or\n    distribute this software, either in source code form or as a compiled\n    binary, for any purpose, commercial or non-commercial, and by any\n    means.\n\n    In jurisdictions that recognize copyright laws, the author or authors\n    of this software dedicate any and all copyright interest in the\n    software to the public domain. We make this dedication for the benefit\n    of the public at large and to the detriment of our heirs and\n    successors. We intend this dedication to be an overt act of\n    relinquishment in perpetuity of all present and future rights to this\n    software under copyright law.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n    IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n    OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n'''\n\n# Create directories\nif not os.path.exists('include/GL'):\n    os.makedirs('include/GL')\nif not os.path.exists('src'):\n    os.makedirs('src')\n\n# Download glcorearb.h\nif not os.path.exists('include/GL/glcorearb.h'):\n    print('Downloading glcorearb.h to include/GL...')\n    web = urllib2.urlopen('https://www.opengl.org/registry/api/GL/glcorearb.h')\n    with open('include/GL/glcorearb.h', 'wb') as f:\n        f.writelines(web.readlines())\nelse:\n    print('Reusing glcorearb.h from include/GL...')\n\n# Parse function names from glcorearb.h\nprint('Parsing glcorearb.h header...')\nprocs = []\np = re.compile(r'GLAPI.*APIENTRY\\s+(\\w+)')\nwith open('include/GL/glcorearb.h', 'r') as f:\n    for line in f:\n        m = p.match(line)\n        if m:\n            procs.append(m.group(1))\nprocs.sort()\n\ndef proc_t(proc):\n    return { 'p': proc,\n             'p_s': 'gl3w' + proc[2:],\n             'p_t': 'PFN' + proc.upper() + 'PROC' }\n\n# Generate gl3w.h\nprint('Generating gl3w.h in include/GL...')\nwith open('include/GL/gl3w.h', 'wb') as f:\n    f.write(UNLICENSE)\n    f.write(br'''#ifndef __gl3w_h_\n#define __gl3w_h_\n\n#include <GL/glcorearb.h>\n\n#ifndef __gl_h_\n#define __gl_h_\n#endif\n\ntypedef void (*GL3WglProc)(void);\n\n/* gl3w API: */\nint gl3wInit(void);\nvoid gl3wShutdown(void);\nint gl3wIsSupported(int major, int minor);\nGL3WglProc gl3wGetProcAddress(const char *proc);\n\n/* OpenGL functions: */\n''')\n    for proc in procs:\n        f.write('extern {0[p_t]: <52} {0[p_s]};\\n'.format(proc_t(proc)).encode(\"utf-8\"))\n    f.write(b'\\n')\n    for proc in procs:\n        f.write('#define {0[p]: <51} {0[p_s]}\\n'.format(proc_t(proc)).encode(\"utf-8\"))\n    f.write(br'''\n#endif // __gl3w_h_\n''')\n\n# Generate gl3w.cpp\nprint('Generating gl3w.cpp in src...')\nwith open('src/gl3w.cpp', 'wb') as f:\n    f.write(UNLICENSE)\n    f.write(br'''#include <GL/gl3w.h>\n\n/* --------------------------------------------------------------------------------------------- */\n\n#ifdef _WIN32\n\n/* ------------------------------------\n * Windows\n * ------------------------------------ */\n\n#define WIN32_LEAN_AND_MEAN 1\n#include <windows.h>\n\nstatic HMODULE gl3w_libgl = NULL;\n\nstatic int gl3w_open_libgl(void)\n{\n    if (!gl3w_libgl)\n    {\n        gl3w_libgl = LoadLibraryA(\"opengl32.dll\");\n    }\n\n    return gl3w_libgl != NULL;\n}\n\nstatic void gl3w_close_libgl(void)\n{\n    if (gl3w_libgl)\n    {\n        FreeLibrary(gl3w_libgl);\n        gl3w_libgl = NULL;\n    }\n}\n\nstatic GL3WglProc gl3w_fn(const char *proc)\n{\n    GL3WglProc res;\n    res = (GL3WglProc) wglGetProcAddress(proc);\n\n    if (!res)\n    {\n        res = (GL3WglProc) GetProcAddress(gl3w_libgl, proc);\n    }\n\n    return res;\n}\n\n#elif defined(__APPLE__) || defined(__APPLE_CC__)\n\n/* ------------------------------------\n * Mac OS\n * ------------------------------------ */\n\n#include <Carbon/Carbon.h>\n\nstatic CFBundleRef gl3w_cfBundle = NULL;\nstatic CFURLRef gl3w_cfBundleURL = NULL;\n\nstatic int gl3w_open_libgl(void)\n{\n    if (gl3w_cfBundle)\n    {\n        return 1; /* Already init */\n    }\n\n    gl3w_cfBundleURL = CFURLCreateWithFileSystemPath(\n                            kCFAllocatorDefault,\n                            CFSTR(\"/System/Library/Frameworks/OpenGL.framework\"),\n                            kCFURLPOSIXPathStyle, true);\n    if (!gl3w_cfBundleURL)\n    {\n        return 0;\n    }\n\n    gl3w_cfBundle = CFBundleCreate(kCFAllocatorDefault, gl3w_cfBundleURL);\n    if (!gl3w_cfBundle)\n    {\n        CFRelease(gl3w_cfBundleURL);\n        return 0;\n    }\n\n    return 1;\n}\n\nstatic void gl3w_close_libgl(void)\n{\n    if (gl3w_cfBundle)\n    {\n        CFRelease(gl3w_cfBundle);\n        gl3w_cfBundle = NULL;\n    }\n    if (gl3w_cfBundleURL)\n    {\n        CFRelease(gl3w_cfBundleURL);\n        gl3w_cfBundleURL = NULL;\n    }\n}\n\nstatic GL3WglProc gl3w_fn(const char *proc)\n{\n    GL3WglProc res;\n    CFStringRef procName;\n\n    procName = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII);\n    res = (GL3WglProc) CFBundleGetFunctionPointerForName(gl3w_cfBundle, procName);\n    CFRelease(procName);\n\n    return res;\n}\n\n#else\n\n/* ------------------------------------\n * GLX\n * ------------------------------------ */\n\n#include <dlfcn.h>\n#include <GL/glx.h>\n\nstatic void *gl3w_libgl = NULL;\n\nstatic int gl3w_open_libgl(void)\n{\n    if (!gl3w_libgl)\n    {\n        gl3w_libgl = dlopen(\"libGL.so.1\", RTLD_LAZY | RTLD_GLOBAL);\n    }\n\n    return gl3w_libgl != NULL;\n}\n\nstatic void gl3w_close_libgl(void)\n{\n    if (gl3w_libgl)\n    {\n        dlclose(gl3w_libgl);\n        gl3w_libgl = NULL;\n    }\n}\n\nstatic GL3WglProc gl3w_fn(const char *proc)\n{\n    GL3WglProc res;\n    res = (GL3WglProc) glXGetProcAddress((const GLubyte *) proc);\n\n    if (!res)\n    {\n        res = (GL3WglProc) dlsym(gl3w_libgl, proc);\n    }\n\n    return res;\n}\n\n#endif\n\n/* ------------------------------------\n * GL3W API\n * ------------------------------------ */\n\nstatic struct {\n\tint major, minor;\n} gl3w_version;\n\nstatic void gl3w_load_all_functions(void);\n\nstatic int gl3w_parse_version(void)\n{\n    if (!glGetIntegerv)\n    {\n        return 0;\n    }\n\n    glGetIntegerv(GL_MAJOR_VERSION, &gl3w_version.major);\n    glGetIntegerv(GL_MINOR_VERSION, &gl3w_version.minor);\n\n    if (gl3w_version.major < 3)\n    {\n        return 0;\n    }\n\n    return 1;\n}\n\nint gl3wInit(void)\n{\n    if (!gl3w_open_libgl())\n    {\n        return 0;\n    }\n\n    gl3w_load_all_functions();\n    return gl3w_parse_version();\n}\n\nvoid gl3wShutdown(void)\n{\n    gl3w_close_libgl();\n}\n\nint gl3wIsSupported(int major, int minor)\n{\n    if (major < 3)\n    {\n        return 0;\n    }\n    if (gl3w_version.major == major)\n    {\n        return gl3w_version.minor >= minor;\n    }\n    return gl3w_version.major >= major;\n}\n\nGL3WglProc gl3wGetProcAddress(const char *proc)\n{\n    if (!proc)\n    {\n        return NULL;\n    }\n    return gl3w_fn(proc);\n}\n\n/* --------------------------------------------------------------------------------------------- */\n\n''')\n    for proc in procs:\n        f.write('{0[p_t]: <52} {0[p_s]};\\n'.format(proc_t(proc)).encode(\"utf-8\"))\n    f.write(br'''\n/* --------------------------------------------------------------------------------------------- */\n\nstatic void gl3w_load_all_functions(void)\n{\n''')\n    for proc in procs:\n        f.write('\\t{0[p_s]: <47} = ( {0[p_t]: <52} ) gl3w_fn(\"{0[p]}\");\\n'.format(proc_t(proc)).encode(\"utf-8\"))\n    f.write(b'}\\n')\n"
  },
  {
    "path": "samples/gl3w/include/GL/gl3w.h",
    "content": "/*\n\n    This file was generated with gl3w_gen.py, part of gl3w\n    (hosted at https://github.com/skaslev/gl3w)\n\n    This is free and unencumbered software released into the public domain.\n\n    Anyone is free to copy, modify, publish, use, compile, sell, or\n    distribute this software, either in source code form or as a compiled\n    binary, for any purpose, commercial or non-commercial, and by any\n    means.\n\n    In jurisdictions that recognize copyright laws, the author or authors\n    of this software dedicate any and all copyright interest in the\n    software to the public domain. We make this dedication for the benefit\n    of the public at large and to the detriment of our heirs and\n    successors. We intend this dedication to be an overt act of\n    relinquishment in perpetuity of all present and future rights to this\n    software under copyright law.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n    IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n    OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n#ifndef __gl3w_h_\n#define __gl3w_h_\n\n#include <GL/glcorearb.h>\n\n#ifndef __gl_h_\n#define __gl_h_\n#endif\n\ntypedef void (*GL3WglProc)(void);\n\n/* gl3w API: */\nint gl3wInit(void);\nvoid gl3wShutdown(void);\nint gl3wIsSupported(int major, int minor);\nGL3WglProc gl3wGetProcAddress(const char *proc);\n\n/* OpenGL functions: */\nextern PFNGLACTIVESHADERPROGRAMPROC                         gl3wActiveShaderProgram;\nextern PFNGLACTIVETEXTUREPROC                               gl3wActiveTexture;\nextern PFNGLATTACHSHADERPROC                                gl3wAttachShader;\nextern PFNGLBEGINCONDITIONALRENDERPROC                      gl3wBeginConditionalRender;\nextern PFNGLBEGINQUERYPROC                                  gl3wBeginQuery;\nextern PFNGLBEGINQUERYINDEXEDPROC                           gl3wBeginQueryIndexed;\nextern PFNGLBEGINTRANSFORMFEEDBACKPROC                      gl3wBeginTransformFeedback;\nextern PFNGLBINDATTRIBLOCATIONPROC                          gl3wBindAttribLocation;\nextern PFNGLBINDBUFFERPROC                                  gl3wBindBuffer;\nextern PFNGLBINDBUFFERBASEPROC                              gl3wBindBufferBase;\nextern PFNGLBINDBUFFERRANGEPROC                             gl3wBindBufferRange;\nextern PFNGLBINDBUFFERSBASEPROC                             gl3wBindBuffersBase;\nextern PFNGLBINDBUFFERSRANGEPROC                            gl3wBindBuffersRange;\nextern PFNGLBINDFRAGDATALOCATIONPROC                        gl3wBindFragDataLocation;\nextern PFNGLBINDFRAGDATALOCATIONINDEXEDPROC                 gl3wBindFragDataLocationIndexed;\nextern PFNGLBINDFRAMEBUFFERPROC                             gl3wBindFramebuffer;\nextern PFNGLBINDIMAGETEXTUREPROC                            gl3wBindImageTexture;\nextern PFNGLBINDIMAGETEXTURESPROC                           gl3wBindImageTextures;\nextern PFNGLBINDPROGRAMPIPELINEPROC                         gl3wBindProgramPipeline;\nextern PFNGLBINDRENDERBUFFERPROC                            gl3wBindRenderbuffer;\nextern PFNGLBINDSAMPLERPROC                                 gl3wBindSampler;\nextern PFNGLBINDSAMPLERSPROC                                gl3wBindSamplers;\nextern PFNGLBINDTEXTUREPROC                                 gl3wBindTexture;\nextern PFNGLBINDTEXTUREUNITPROC                             gl3wBindTextureUnit;\nextern PFNGLBINDTEXTURESPROC                                gl3wBindTextures;\nextern PFNGLBINDTRANSFORMFEEDBACKPROC                       gl3wBindTransformFeedback;\nextern PFNGLBINDVERTEXARRAYPROC                             gl3wBindVertexArray;\nextern PFNGLBINDVERTEXBUFFERPROC                            gl3wBindVertexBuffer;\nextern PFNGLBINDVERTEXBUFFERSPROC                           gl3wBindVertexBuffers;\nextern PFNGLBLENDCOLORPROC                                  gl3wBlendColor;\nextern PFNGLBLENDEQUATIONPROC                               gl3wBlendEquation;\nextern PFNGLBLENDEQUATIONSEPARATEPROC                       gl3wBlendEquationSeparate;\nextern PFNGLBLENDEQUATIONSEPARATEIPROC                      gl3wBlendEquationSeparatei;\nextern PFNGLBLENDEQUATIONSEPARATEIARBPROC                   gl3wBlendEquationSeparateiARB;\nextern PFNGLBLENDEQUATIONIPROC                              gl3wBlendEquationi;\nextern PFNGLBLENDEQUATIONIARBPROC                           gl3wBlendEquationiARB;\nextern PFNGLBLENDFUNCPROC                                   gl3wBlendFunc;\nextern PFNGLBLENDFUNCSEPARATEPROC                           gl3wBlendFuncSeparate;\nextern PFNGLBLENDFUNCSEPARATEIPROC                          gl3wBlendFuncSeparatei;\nextern PFNGLBLENDFUNCSEPARATEIARBPROC                       gl3wBlendFuncSeparateiARB;\nextern PFNGLBLENDFUNCIPROC                                  gl3wBlendFunci;\nextern PFNGLBLENDFUNCIARBPROC                               gl3wBlendFunciARB;\nextern PFNGLBLITFRAMEBUFFERPROC                             gl3wBlitFramebuffer;\nextern PFNGLBLITNAMEDFRAMEBUFFERPROC                        gl3wBlitNamedFramebuffer;\nextern PFNGLBUFFERDATAPROC                                  gl3wBufferData;\nextern PFNGLBUFFERPAGECOMMITMENTARBPROC                     gl3wBufferPageCommitmentARB;\nextern PFNGLBUFFERSTORAGEPROC                               gl3wBufferStorage;\nextern PFNGLBUFFERSUBDATAPROC                               gl3wBufferSubData;\nextern PFNGLCHECKFRAMEBUFFERSTATUSPROC                      gl3wCheckFramebufferStatus;\nextern PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC                 gl3wCheckNamedFramebufferStatus;\nextern PFNGLCLAMPCOLORPROC                                  gl3wClampColor;\nextern PFNGLCLEARPROC                                       gl3wClear;\nextern PFNGLCLEARBUFFERDATAPROC                             gl3wClearBufferData;\nextern PFNGLCLEARBUFFERSUBDATAPROC                          gl3wClearBufferSubData;\nextern PFNGLCLEARBUFFERFIPROC                               gl3wClearBufferfi;\nextern PFNGLCLEARBUFFERFVPROC                               gl3wClearBufferfv;\nextern PFNGLCLEARBUFFERIVPROC                               gl3wClearBufferiv;\nextern PFNGLCLEARBUFFERUIVPROC                              gl3wClearBufferuiv;\nextern PFNGLCLEARCOLORPROC                                  gl3wClearColor;\nextern PFNGLCLEARDEPTHPROC                                  gl3wClearDepth;\nextern PFNGLCLEARDEPTHFPROC                                 gl3wClearDepthf;\nextern PFNGLCLEARNAMEDBUFFERDATAPROC                        gl3wClearNamedBufferData;\nextern PFNGLCLEARNAMEDBUFFERSUBDATAPROC                     gl3wClearNamedBufferSubData;\nextern PFNGLCLEARNAMEDFRAMEBUFFERFIPROC                     gl3wClearNamedFramebufferfi;\nextern PFNGLCLEARNAMEDFRAMEBUFFERFVPROC                     gl3wClearNamedFramebufferfv;\nextern PFNGLCLEARNAMEDFRAMEBUFFERIVPROC                     gl3wClearNamedFramebufferiv;\nextern PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC                    gl3wClearNamedFramebufferuiv;\nextern PFNGLCLEARSTENCILPROC                                gl3wClearStencil;\nextern PFNGLCLEARTEXIMAGEPROC                               gl3wClearTexImage;\nextern PFNGLCLEARTEXSUBIMAGEPROC                            gl3wClearTexSubImage;\nextern PFNGLCLIENTWAITSYNCPROC                              gl3wClientWaitSync;\nextern PFNGLCLIPCONTROLPROC                                 gl3wClipControl;\nextern PFNGLCOLORMASKPROC                                   gl3wColorMask;\nextern PFNGLCOLORMASKIPROC                                  gl3wColorMaski;\nextern PFNGLCOMPILESHADERPROC                               gl3wCompileShader;\nextern PFNGLCOMPILESHADERINCLUDEARBPROC                     gl3wCompileShaderIncludeARB;\nextern PFNGLCOMPRESSEDTEXIMAGE1DPROC                        gl3wCompressedTexImage1D;\nextern PFNGLCOMPRESSEDTEXIMAGE2DPROC                        gl3wCompressedTexImage2D;\nextern PFNGLCOMPRESSEDTEXIMAGE3DPROC                        gl3wCompressedTexImage3D;\nextern PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC                     gl3wCompressedTexSubImage1D;\nextern PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC                     gl3wCompressedTexSubImage2D;\nextern PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC                     gl3wCompressedTexSubImage3D;\nextern PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC                 gl3wCompressedTextureSubImage1D;\nextern PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC                 gl3wCompressedTextureSubImage2D;\nextern PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC                 gl3wCompressedTextureSubImage3D;\nextern PFNGLCOPYBUFFERSUBDATAPROC                           gl3wCopyBufferSubData;\nextern PFNGLCOPYIMAGESUBDATAPROC                            gl3wCopyImageSubData;\nextern PFNGLCOPYNAMEDBUFFERSUBDATAPROC                      gl3wCopyNamedBufferSubData;\nextern PFNGLCOPYTEXIMAGE1DPROC                              gl3wCopyTexImage1D;\nextern PFNGLCOPYTEXIMAGE2DPROC                              gl3wCopyTexImage2D;\nextern PFNGLCOPYTEXSUBIMAGE1DPROC                           gl3wCopyTexSubImage1D;\nextern PFNGLCOPYTEXSUBIMAGE2DPROC                           gl3wCopyTexSubImage2D;\nextern PFNGLCOPYTEXSUBIMAGE3DPROC                           gl3wCopyTexSubImage3D;\nextern PFNGLCOPYTEXTURESUBIMAGE1DPROC                       gl3wCopyTextureSubImage1D;\nextern PFNGLCOPYTEXTURESUBIMAGE2DPROC                       gl3wCopyTextureSubImage2D;\nextern PFNGLCOPYTEXTURESUBIMAGE3DPROC                       gl3wCopyTextureSubImage3D;\nextern PFNGLCREATEBUFFERSPROC                               gl3wCreateBuffers;\nextern PFNGLCREATEFRAMEBUFFERSPROC                          gl3wCreateFramebuffers;\nextern PFNGLCREATEPROGRAMPROC                               gl3wCreateProgram;\nextern PFNGLCREATEPROGRAMPIPELINESPROC                      gl3wCreateProgramPipelines;\nextern PFNGLCREATEQUERIESPROC                               gl3wCreateQueries;\nextern PFNGLCREATERENDERBUFFERSPROC                         gl3wCreateRenderbuffers;\nextern PFNGLCREATESAMPLERSPROC                              gl3wCreateSamplers;\nextern PFNGLCREATESHADERPROC                                gl3wCreateShader;\nextern PFNGLCREATESHADERPROGRAMVPROC                        gl3wCreateShaderProgramv;\nextern PFNGLCREATESYNCFROMCLEVENTARBPROC                    gl3wCreateSyncFromCLeventARB;\nextern PFNGLCREATETEXTURESPROC                              gl3wCreateTextures;\nextern PFNGLCREATETRANSFORMFEEDBACKSPROC                    gl3wCreateTransformFeedbacks;\nextern PFNGLCREATEVERTEXARRAYSPROC                          gl3wCreateVertexArrays;\nextern PFNGLCULLFACEPROC                                    gl3wCullFace;\nextern PFNGLDEBUGMESSAGECALLBACKPROC                        gl3wDebugMessageCallback;\nextern PFNGLDEBUGMESSAGECALLBACKARBPROC                     gl3wDebugMessageCallbackARB;\nextern PFNGLDEBUGMESSAGECONTROLPROC                         gl3wDebugMessageControl;\nextern PFNGLDEBUGMESSAGECONTROLARBPROC                      gl3wDebugMessageControlARB;\nextern PFNGLDEBUGMESSAGEINSERTPROC                          gl3wDebugMessageInsert;\nextern PFNGLDEBUGMESSAGEINSERTARBPROC                       gl3wDebugMessageInsertARB;\nextern PFNGLDELETEBUFFERSPROC                               gl3wDeleteBuffers;\nextern PFNGLDELETEFRAMEBUFFERSPROC                          gl3wDeleteFramebuffers;\nextern PFNGLDELETENAMEDSTRINGARBPROC                        gl3wDeleteNamedStringARB;\nextern PFNGLDELETEPROGRAMPROC                               gl3wDeleteProgram;\nextern PFNGLDELETEPROGRAMPIPELINESPROC                      gl3wDeleteProgramPipelines;\nextern PFNGLDELETEQUERIESPROC                               gl3wDeleteQueries;\nextern PFNGLDELETERENDERBUFFERSPROC                         gl3wDeleteRenderbuffers;\nextern PFNGLDELETESAMPLERSPROC                              gl3wDeleteSamplers;\nextern PFNGLDELETESHADERPROC                                gl3wDeleteShader;\nextern PFNGLDELETESYNCPROC                                  gl3wDeleteSync;\nextern PFNGLDELETETEXTURESPROC                              gl3wDeleteTextures;\nextern PFNGLDELETETRANSFORMFEEDBACKSPROC                    gl3wDeleteTransformFeedbacks;\nextern PFNGLDELETEVERTEXARRAYSPROC                          gl3wDeleteVertexArrays;\nextern PFNGLDEPTHFUNCPROC                                   gl3wDepthFunc;\nextern PFNGLDEPTHMASKPROC                                   gl3wDepthMask;\nextern PFNGLDEPTHRANGEPROC                                  gl3wDepthRange;\nextern PFNGLDEPTHRANGEARRAYVPROC                            gl3wDepthRangeArrayv;\nextern PFNGLDEPTHRANGEINDEXEDPROC                           gl3wDepthRangeIndexed;\nextern PFNGLDEPTHRANGEFPROC                                 gl3wDepthRangef;\nextern PFNGLDETACHSHADERPROC                                gl3wDetachShader;\nextern PFNGLDISABLEPROC                                     gl3wDisable;\nextern PFNGLDISABLEVERTEXARRAYATTRIBPROC                    gl3wDisableVertexArrayAttrib;\nextern PFNGLDISABLEVERTEXATTRIBARRAYPROC                    gl3wDisableVertexAttribArray;\nextern PFNGLDISABLEIPROC                                    gl3wDisablei;\nextern PFNGLDISPATCHCOMPUTEPROC                             gl3wDispatchCompute;\nextern PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC                 gl3wDispatchComputeGroupSizeARB;\nextern PFNGLDISPATCHCOMPUTEINDIRECTPROC                     gl3wDispatchComputeIndirect;\nextern PFNGLDRAWARRAYSPROC                                  gl3wDrawArrays;\nextern PFNGLDRAWARRAYSINDIRECTPROC                          gl3wDrawArraysIndirect;\nextern PFNGLDRAWARRAYSINSTANCEDPROC                         gl3wDrawArraysInstanced;\nextern PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC             gl3wDrawArraysInstancedBaseInstance;\nextern PFNGLDRAWBUFFERPROC                                  gl3wDrawBuffer;\nextern PFNGLDRAWBUFFERSPROC                                 gl3wDrawBuffers;\nextern PFNGLDRAWELEMENTSPROC                                gl3wDrawElements;\nextern PFNGLDRAWELEMENTSBASEVERTEXPROC                      gl3wDrawElementsBaseVertex;\nextern PFNGLDRAWELEMENTSINDIRECTPROC                        gl3wDrawElementsIndirect;\nextern PFNGLDRAWELEMENTSINSTANCEDPROC                       gl3wDrawElementsInstanced;\nextern PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC           gl3wDrawElementsInstancedBaseInstance;\nextern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC             gl3wDrawElementsInstancedBaseVertex;\nextern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC gl3wDrawElementsInstancedBaseVertexBaseInstance;\nextern PFNGLDRAWRANGEELEMENTSPROC                           gl3wDrawRangeElements;\nextern PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC                 gl3wDrawRangeElementsBaseVertex;\nextern PFNGLDRAWTRANSFORMFEEDBACKPROC                       gl3wDrawTransformFeedback;\nextern PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC              gl3wDrawTransformFeedbackInstanced;\nextern PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC                 gl3wDrawTransformFeedbackStream;\nextern PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC        gl3wDrawTransformFeedbackStreamInstanced;\nextern PFNGLENABLEPROC                                      gl3wEnable;\nextern PFNGLENABLEVERTEXARRAYATTRIBPROC                     gl3wEnableVertexArrayAttrib;\nextern PFNGLENABLEVERTEXATTRIBARRAYPROC                     gl3wEnableVertexAttribArray;\nextern PFNGLENABLEIPROC                                     gl3wEnablei;\nextern PFNGLENDCONDITIONALRENDERPROC                        gl3wEndConditionalRender;\nextern PFNGLENDQUERYPROC                                    gl3wEndQuery;\nextern PFNGLENDQUERYINDEXEDPROC                             gl3wEndQueryIndexed;\nextern PFNGLENDTRANSFORMFEEDBACKPROC                        gl3wEndTransformFeedback;\nextern PFNGLFENCESYNCPROC                                   gl3wFenceSync;\nextern PFNGLFINISHPROC                                      gl3wFinish;\nextern PFNGLFLUSHPROC                                       gl3wFlush;\nextern PFNGLFLUSHMAPPEDBUFFERRANGEPROC                      gl3wFlushMappedBufferRange;\nextern PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC                 gl3wFlushMappedNamedBufferRange;\nextern PFNGLFRAMEBUFFERPARAMETERIPROC                       gl3wFramebufferParameteri;\nextern PFNGLFRAMEBUFFERRENDERBUFFERPROC                     gl3wFramebufferRenderbuffer;\nextern PFNGLFRAMEBUFFERTEXTUREPROC                          gl3wFramebufferTexture;\nextern PFNGLFRAMEBUFFERTEXTURE1DPROC                        gl3wFramebufferTexture1D;\nextern PFNGLFRAMEBUFFERTEXTURE2DPROC                        gl3wFramebufferTexture2D;\nextern PFNGLFRAMEBUFFERTEXTURE3DPROC                        gl3wFramebufferTexture3D;\nextern PFNGLFRAMEBUFFERTEXTURELAYERPROC                     gl3wFramebufferTextureLayer;\nextern PFNGLFRONTFACEPROC                                   gl3wFrontFace;\nextern PFNGLGENBUFFERSPROC                                  gl3wGenBuffers;\nextern PFNGLGENFRAMEBUFFERSPROC                             gl3wGenFramebuffers;\nextern PFNGLGENPROGRAMPIPELINESPROC                         gl3wGenProgramPipelines;\nextern PFNGLGENQUERIESPROC                                  gl3wGenQueries;\nextern PFNGLGENRENDERBUFFERSPROC                            gl3wGenRenderbuffers;\nextern PFNGLGENSAMPLERSPROC                                 gl3wGenSamplers;\nextern PFNGLGENTEXTURESPROC                                 gl3wGenTextures;\nextern PFNGLGENTRANSFORMFEEDBACKSPROC                       gl3wGenTransformFeedbacks;\nextern PFNGLGENVERTEXARRAYSPROC                             gl3wGenVertexArrays;\nextern PFNGLGENERATEMIPMAPPROC                              gl3wGenerateMipmap;\nextern PFNGLGENERATETEXTUREMIPMAPPROC                       gl3wGenerateTextureMipmap;\nextern PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC              gl3wGetActiveAtomicCounterBufferiv;\nextern PFNGLGETACTIVEATTRIBPROC                             gl3wGetActiveAttrib;\nextern PFNGLGETACTIVESUBROUTINENAMEPROC                     gl3wGetActiveSubroutineName;\nextern PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC              gl3wGetActiveSubroutineUniformName;\nextern PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC                gl3wGetActiveSubroutineUniformiv;\nextern PFNGLGETACTIVEUNIFORMPROC                            gl3wGetActiveUniform;\nextern PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC                   gl3wGetActiveUniformBlockName;\nextern PFNGLGETACTIVEUNIFORMBLOCKIVPROC                     gl3wGetActiveUniformBlockiv;\nextern PFNGLGETACTIVEUNIFORMNAMEPROC                        gl3wGetActiveUniformName;\nextern PFNGLGETACTIVEUNIFORMSIVPROC                         gl3wGetActiveUniformsiv;\nextern PFNGLGETATTACHEDSHADERSPROC                          gl3wGetAttachedShaders;\nextern PFNGLGETATTRIBLOCATIONPROC                           gl3wGetAttribLocation;\nextern PFNGLGETBOOLEANI_VPROC                               gl3wGetBooleani_v;\nextern PFNGLGETBOOLEANVPROC                                 gl3wGetBooleanv;\nextern PFNGLGETBUFFERPARAMETERI64VPROC                      gl3wGetBufferParameteri64v;\nextern PFNGLGETBUFFERPARAMETERIVPROC                        gl3wGetBufferParameteriv;\nextern PFNGLGETBUFFERPOINTERVPROC                           gl3wGetBufferPointerv;\nextern PFNGLGETBUFFERSUBDATAPROC                            gl3wGetBufferSubData;\nextern PFNGLGETCOMPRESSEDTEXIMAGEPROC                       gl3wGetCompressedTexImage;\nextern PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC                   gl3wGetCompressedTextureImage;\nextern PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC                gl3wGetCompressedTextureSubImage;\nextern PFNGLGETDEBUGMESSAGELOGPROC                          gl3wGetDebugMessageLog;\nextern PFNGLGETDEBUGMESSAGELOGARBPROC                       gl3wGetDebugMessageLogARB;\nextern PFNGLGETDOUBLEI_VPROC                                gl3wGetDoublei_v;\nextern PFNGLGETDOUBLEVPROC                                  gl3wGetDoublev;\nextern PFNGLGETERRORPROC                                    gl3wGetError;\nextern PFNGLGETFLOATI_VPROC                                 gl3wGetFloati_v;\nextern PFNGLGETFLOATVPROC                                   gl3wGetFloatv;\nextern PFNGLGETFRAGDATAINDEXPROC                            gl3wGetFragDataIndex;\nextern PFNGLGETFRAGDATALOCATIONPROC                         gl3wGetFragDataLocation;\nextern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC         gl3wGetFramebufferAttachmentParameteriv;\nextern PFNGLGETFRAMEBUFFERPARAMETERIVPROC                   gl3wGetFramebufferParameteriv;\nextern PFNGLGETGRAPHICSRESETSTATUSPROC                      gl3wGetGraphicsResetStatus;\nextern PFNGLGETGRAPHICSRESETSTATUSARBPROC                   gl3wGetGraphicsResetStatusARB;\nextern PFNGLGETIMAGEHANDLEARBPROC                           gl3wGetImageHandleARB;\nextern PFNGLGETINTEGER64I_VPROC                             gl3wGetInteger64i_v;\nextern PFNGLGETINTEGER64VPROC                               gl3wGetInteger64v;\nextern PFNGLGETINTEGERI_VPROC                               gl3wGetIntegeri_v;\nextern PFNGLGETINTEGERVPROC                                 gl3wGetIntegerv;\nextern PFNGLGETINTERNALFORMATI64VPROC                       gl3wGetInternalformati64v;\nextern PFNGLGETINTERNALFORMATIVPROC                         gl3wGetInternalformativ;\nextern PFNGLGETMULTISAMPLEFVPROC                            gl3wGetMultisamplefv;\nextern PFNGLGETNAMEDBUFFERPARAMETERI64VPROC                 gl3wGetNamedBufferParameteri64v;\nextern PFNGLGETNAMEDBUFFERPARAMETERIVPROC                   gl3wGetNamedBufferParameteriv;\nextern PFNGLGETNAMEDBUFFERPOINTERVPROC                      gl3wGetNamedBufferPointerv;\nextern PFNGLGETNAMEDBUFFERSUBDATAPROC                       gl3wGetNamedBufferSubData;\nextern PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC    gl3wGetNamedFramebufferAttachmentParameteriv;\nextern PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC              gl3wGetNamedFramebufferParameteriv;\nextern PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC             gl3wGetNamedRenderbufferParameteriv;\nextern PFNGLGETNAMEDSTRINGARBPROC                           gl3wGetNamedStringARB;\nextern PFNGLGETNAMEDSTRINGIVARBPROC                         gl3wGetNamedStringivARB;\nextern PFNGLGETOBJECTLABELPROC                              gl3wGetObjectLabel;\nextern PFNGLGETOBJECTPTRLABELPROC                           gl3wGetObjectPtrLabel;\nextern PFNGLGETPOINTERVPROC                                 gl3wGetPointerv;\nextern PFNGLGETPROGRAMBINARYPROC                            gl3wGetProgramBinary;\nextern PFNGLGETPROGRAMINFOLOGPROC                           gl3wGetProgramInfoLog;\nextern PFNGLGETPROGRAMINTERFACEIVPROC                       gl3wGetProgramInterfaceiv;\nextern PFNGLGETPROGRAMPIPELINEINFOLOGPROC                   gl3wGetProgramPipelineInfoLog;\nextern PFNGLGETPROGRAMPIPELINEIVPROC                        gl3wGetProgramPipelineiv;\nextern PFNGLGETPROGRAMRESOURCEINDEXPROC                     gl3wGetProgramResourceIndex;\nextern PFNGLGETPROGRAMRESOURCELOCATIONPROC                  gl3wGetProgramResourceLocation;\nextern PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC             gl3wGetProgramResourceLocationIndex;\nextern PFNGLGETPROGRAMRESOURCENAMEPROC                      gl3wGetProgramResourceName;\nextern PFNGLGETPROGRAMRESOURCEIVPROC                        gl3wGetProgramResourceiv;\nextern PFNGLGETPROGRAMSTAGEIVPROC                           gl3wGetProgramStageiv;\nextern PFNGLGETPROGRAMIVPROC                                gl3wGetProgramiv;\nextern PFNGLGETQUERYBUFFEROBJECTI64VPROC                    gl3wGetQueryBufferObjecti64v;\nextern PFNGLGETQUERYBUFFEROBJECTIVPROC                      gl3wGetQueryBufferObjectiv;\nextern PFNGLGETQUERYBUFFEROBJECTUI64VPROC                   gl3wGetQueryBufferObjectui64v;\nextern PFNGLGETQUERYBUFFEROBJECTUIVPROC                     gl3wGetQueryBufferObjectuiv;\nextern PFNGLGETQUERYINDEXEDIVPROC                           gl3wGetQueryIndexediv;\nextern PFNGLGETQUERYOBJECTI64VPROC                          gl3wGetQueryObjecti64v;\nextern PFNGLGETQUERYOBJECTIVPROC                            gl3wGetQueryObjectiv;\nextern PFNGLGETQUERYOBJECTUI64VPROC                         gl3wGetQueryObjectui64v;\nextern PFNGLGETQUERYOBJECTUIVPROC                           gl3wGetQueryObjectuiv;\nextern PFNGLGETQUERYIVPROC                                  gl3wGetQueryiv;\nextern PFNGLGETRENDERBUFFERPARAMETERIVPROC                  gl3wGetRenderbufferParameteriv;\nextern PFNGLGETSAMPLERPARAMETERIIVPROC                      gl3wGetSamplerParameterIiv;\nextern PFNGLGETSAMPLERPARAMETERIUIVPROC                     gl3wGetSamplerParameterIuiv;\nextern PFNGLGETSAMPLERPARAMETERFVPROC                       gl3wGetSamplerParameterfv;\nextern PFNGLGETSAMPLERPARAMETERIVPROC                       gl3wGetSamplerParameteriv;\nextern PFNGLGETSHADERINFOLOGPROC                            gl3wGetShaderInfoLog;\nextern PFNGLGETSHADERPRECISIONFORMATPROC                    gl3wGetShaderPrecisionFormat;\nextern PFNGLGETSHADERSOURCEPROC                             gl3wGetShaderSource;\nextern PFNGLGETSHADERIVPROC                                 gl3wGetShaderiv;\nextern PFNGLGETSTRINGPROC                                   gl3wGetString;\nextern PFNGLGETSTRINGIPROC                                  gl3wGetStringi;\nextern PFNGLGETSUBROUTINEINDEXPROC                          gl3wGetSubroutineIndex;\nextern PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC                gl3wGetSubroutineUniformLocation;\nextern PFNGLGETSYNCIVPROC                                   gl3wGetSynciv;\nextern PFNGLGETTEXIMAGEPROC                                 gl3wGetTexImage;\nextern PFNGLGETTEXLEVELPARAMETERFVPROC                      gl3wGetTexLevelParameterfv;\nextern PFNGLGETTEXLEVELPARAMETERIVPROC                      gl3wGetTexLevelParameteriv;\nextern PFNGLGETTEXPARAMETERIIVPROC                          gl3wGetTexParameterIiv;\nextern PFNGLGETTEXPARAMETERIUIVPROC                         gl3wGetTexParameterIuiv;\nextern PFNGLGETTEXPARAMETERFVPROC                           gl3wGetTexParameterfv;\nextern PFNGLGETTEXPARAMETERIVPROC                           gl3wGetTexParameteriv;\nextern PFNGLGETTEXTUREHANDLEARBPROC                         gl3wGetTextureHandleARB;\nextern PFNGLGETTEXTUREIMAGEPROC                             gl3wGetTextureImage;\nextern PFNGLGETTEXTURELEVELPARAMETERFVPROC                  gl3wGetTextureLevelParameterfv;\nextern PFNGLGETTEXTURELEVELPARAMETERIVPROC                  gl3wGetTextureLevelParameteriv;\nextern PFNGLGETTEXTUREPARAMETERIIVPROC                      gl3wGetTextureParameterIiv;\nextern PFNGLGETTEXTUREPARAMETERIUIVPROC                     gl3wGetTextureParameterIuiv;\nextern PFNGLGETTEXTUREPARAMETERFVPROC                       gl3wGetTextureParameterfv;\nextern PFNGLGETTEXTUREPARAMETERIVPROC                       gl3wGetTextureParameteriv;\nextern PFNGLGETTEXTURESAMPLERHANDLEARBPROC                  gl3wGetTextureSamplerHandleARB;\nextern PFNGLGETTEXTURESUBIMAGEPROC                          gl3wGetTextureSubImage;\nextern PFNGLGETTRANSFORMFEEDBACKVARYINGPROC                 gl3wGetTransformFeedbackVarying;\nextern PFNGLGETTRANSFORMFEEDBACKI64_VPROC                   gl3wGetTransformFeedbacki64_v;\nextern PFNGLGETTRANSFORMFEEDBACKI_VPROC                     gl3wGetTransformFeedbacki_v;\nextern PFNGLGETTRANSFORMFEEDBACKIVPROC                      gl3wGetTransformFeedbackiv;\nextern PFNGLGETUNIFORMBLOCKINDEXPROC                        gl3wGetUniformBlockIndex;\nextern PFNGLGETUNIFORMINDICESPROC                           gl3wGetUniformIndices;\nextern PFNGLGETUNIFORMLOCATIONPROC                          gl3wGetUniformLocation;\nextern PFNGLGETUNIFORMSUBROUTINEUIVPROC                     gl3wGetUniformSubroutineuiv;\nextern PFNGLGETUNIFORMDVPROC                                gl3wGetUniformdv;\nextern PFNGLGETUNIFORMFVPROC                                gl3wGetUniformfv;\nextern PFNGLGETUNIFORMIVPROC                                gl3wGetUniformiv;\nextern PFNGLGETUNIFORMUIVPROC                               gl3wGetUniformuiv;\nextern PFNGLGETVERTEXARRAYINDEXED64IVPROC                   gl3wGetVertexArrayIndexed64iv;\nextern PFNGLGETVERTEXARRAYINDEXEDIVPROC                     gl3wGetVertexArrayIndexediv;\nextern PFNGLGETVERTEXARRAYIVPROC                            gl3wGetVertexArrayiv;\nextern PFNGLGETVERTEXATTRIBIIVPROC                          gl3wGetVertexAttribIiv;\nextern PFNGLGETVERTEXATTRIBIUIVPROC                         gl3wGetVertexAttribIuiv;\nextern PFNGLGETVERTEXATTRIBLDVPROC                          gl3wGetVertexAttribLdv;\nextern PFNGLGETVERTEXATTRIBLUI64VARBPROC                    gl3wGetVertexAttribLui64vARB;\nextern PFNGLGETVERTEXATTRIBPOINTERVPROC                     gl3wGetVertexAttribPointerv;\nextern PFNGLGETVERTEXATTRIBDVPROC                           gl3wGetVertexAttribdv;\nextern PFNGLGETVERTEXATTRIBFVPROC                           gl3wGetVertexAttribfv;\nextern PFNGLGETVERTEXATTRIBIVPROC                           gl3wGetVertexAttribiv;\nextern PFNGLGETNCOMPRESSEDTEXIMAGEPROC                      gl3wGetnCompressedTexImage;\nextern PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC                   gl3wGetnCompressedTexImageARB;\nextern PFNGLGETNTEXIMAGEPROC                                gl3wGetnTexImage;\nextern PFNGLGETNTEXIMAGEARBPROC                             gl3wGetnTexImageARB;\nextern PFNGLGETNUNIFORMDVPROC                               gl3wGetnUniformdv;\nextern PFNGLGETNUNIFORMDVARBPROC                            gl3wGetnUniformdvARB;\nextern PFNGLGETNUNIFORMFVPROC                               gl3wGetnUniformfv;\nextern PFNGLGETNUNIFORMFVARBPROC                            gl3wGetnUniformfvARB;\nextern PFNGLGETNUNIFORMIVPROC                               gl3wGetnUniformiv;\nextern PFNGLGETNUNIFORMIVARBPROC                            gl3wGetnUniformivARB;\nextern PFNGLGETNUNIFORMUIVPROC                              gl3wGetnUniformuiv;\nextern PFNGLGETNUNIFORMUIVARBPROC                           gl3wGetnUniformuivARB;\nextern PFNGLHINTPROC                                        gl3wHint;\nextern PFNGLINVALIDATEBUFFERDATAPROC                        gl3wInvalidateBufferData;\nextern PFNGLINVALIDATEBUFFERSUBDATAPROC                     gl3wInvalidateBufferSubData;\nextern PFNGLINVALIDATEFRAMEBUFFERPROC                       gl3wInvalidateFramebuffer;\nextern PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC              gl3wInvalidateNamedFramebufferData;\nextern PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC           gl3wInvalidateNamedFramebufferSubData;\nextern PFNGLINVALIDATESUBFRAMEBUFFERPROC                    gl3wInvalidateSubFramebuffer;\nextern PFNGLINVALIDATETEXIMAGEPROC                          gl3wInvalidateTexImage;\nextern PFNGLINVALIDATETEXSUBIMAGEPROC                       gl3wInvalidateTexSubImage;\nextern PFNGLISBUFFERPROC                                    gl3wIsBuffer;\nextern PFNGLISENABLEDPROC                                   gl3wIsEnabled;\nextern PFNGLISENABLEDIPROC                                  gl3wIsEnabledi;\nextern PFNGLISFRAMEBUFFERPROC                               gl3wIsFramebuffer;\nextern PFNGLISIMAGEHANDLERESIDENTARBPROC                    gl3wIsImageHandleResidentARB;\nextern PFNGLISNAMEDSTRINGARBPROC                            gl3wIsNamedStringARB;\nextern PFNGLISPROGRAMPROC                                   gl3wIsProgram;\nextern PFNGLISPROGRAMPIPELINEPROC                           gl3wIsProgramPipeline;\nextern PFNGLISQUERYPROC                                     gl3wIsQuery;\nextern PFNGLISRENDERBUFFERPROC                              gl3wIsRenderbuffer;\nextern PFNGLISSAMPLERPROC                                   gl3wIsSampler;\nextern PFNGLISSHADERPROC                                    gl3wIsShader;\nextern PFNGLISSYNCPROC                                      gl3wIsSync;\nextern PFNGLISTEXTUREPROC                                   gl3wIsTexture;\nextern PFNGLISTEXTUREHANDLERESIDENTARBPROC                  gl3wIsTextureHandleResidentARB;\nextern PFNGLISTRANSFORMFEEDBACKPROC                         gl3wIsTransformFeedback;\nextern PFNGLISVERTEXARRAYPROC                               gl3wIsVertexArray;\nextern PFNGLLINEWIDTHPROC                                   gl3wLineWidth;\nextern PFNGLLINKPROGRAMPROC                                 gl3wLinkProgram;\nextern PFNGLLOGICOPPROC                                     gl3wLogicOp;\nextern PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC               gl3wMakeImageHandleNonResidentARB;\nextern PFNGLMAKEIMAGEHANDLERESIDENTARBPROC                  gl3wMakeImageHandleResidentARB;\nextern PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC             gl3wMakeTextureHandleNonResidentARB;\nextern PFNGLMAKETEXTUREHANDLERESIDENTARBPROC                gl3wMakeTextureHandleResidentARB;\nextern PFNGLMAPBUFFERPROC                                   gl3wMapBuffer;\nextern PFNGLMAPBUFFERRANGEPROC                              gl3wMapBufferRange;\nextern PFNGLMAPNAMEDBUFFERPROC                              gl3wMapNamedBuffer;\nextern PFNGLMAPNAMEDBUFFERRANGEPROC                         gl3wMapNamedBufferRange;\nextern PFNGLMEMORYBARRIERPROC                               gl3wMemoryBarrier;\nextern PFNGLMEMORYBARRIERBYREGIONPROC                       gl3wMemoryBarrierByRegion;\nextern PFNGLMINSAMPLESHADINGPROC                            gl3wMinSampleShading;\nextern PFNGLMINSAMPLESHADINGARBPROC                         gl3wMinSampleShadingARB;\nextern PFNGLMULTIDRAWARRAYSPROC                             gl3wMultiDrawArrays;\nextern PFNGLMULTIDRAWARRAYSINDIRECTPROC                     gl3wMultiDrawArraysIndirect;\nextern PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC             gl3wMultiDrawArraysIndirectCountARB;\nextern PFNGLMULTIDRAWELEMENTSPROC                           gl3wMultiDrawElements;\nextern PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC                 gl3wMultiDrawElementsBaseVertex;\nextern PFNGLMULTIDRAWELEMENTSINDIRECTPROC                   gl3wMultiDrawElementsIndirect;\nextern PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC           gl3wMultiDrawElementsIndirectCountARB;\nextern PFNGLNAMEDBUFFERDATAPROC                             gl3wNamedBufferData;\nextern PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC                gl3wNamedBufferPageCommitmentARB;\nextern PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC                gl3wNamedBufferPageCommitmentEXT;\nextern PFNGLNAMEDBUFFERSTORAGEPROC                          gl3wNamedBufferStorage;\nextern PFNGLNAMEDBUFFERSUBDATAPROC                          gl3wNamedBufferSubData;\nextern PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC                  gl3wNamedFramebufferDrawBuffer;\nextern PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC                 gl3wNamedFramebufferDrawBuffers;\nextern PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC                  gl3wNamedFramebufferParameteri;\nextern PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC                  gl3wNamedFramebufferReadBuffer;\nextern PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC                gl3wNamedFramebufferRenderbuffer;\nextern PFNGLNAMEDFRAMEBUFFERTEXTUREPROC                     gl3wNamedFramebufferTexture;\nextern PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC                gl3wNamedFramebufferTextureLayer;\nextern PFNGLNAMEDRENDERBUFFERSTORAGEPROC                    gl3wNamedRenderbufferStorage;\nextern PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC         gl3wNamedRenderbufferStorageMultisample;\nextern PFNGLNAMEDSTRINGARBPROC                              gl3wNamedStringARB;\nextern PFNGLOBJECTLABELPROC                                 gl3wObjectLabel;\nextern PFNGLOBJECTPTRLABELPROC                              gl3wObjectPtrLabel;\nextern PFNGLPATCHPARAMETERFVPROC                            gl3wPatchParameterfv;\nextern PFNGLPATCHPARAMETERIPROC                             gl3wPatchParameteri;\nextern PFNGLPAUSETRANSFORMFEEDBACKPROC                      gl3wPauseTransformFeedback;\nextern PFNGLPIXELSTOREFPROC                                 gl3wPixelStoref;\nextern PFNGLPIXELSTOREIPROC                                 gl3wPixelStorei;\nextern PFNGLPOINTPARAMETERFPROC                             gl3wPointParameterf;\nextern PFNGLPOINTPARAMETERFVPROC                            gl3wPointParameterfv;\nextern PFNGLPOINTPARAMETERIPROC                             gl3wPointParameteri;\nextern PFNGLPOINTPARAMETERIVPROC                            gl3wPointParameteriv;\nextern PFNGLPOINTSIZEPROC                                   gl3wPointSize;\nextern PFNGLPOLYGONMODEPROC                                 gl3wPolygonMode;\nextern PFNGLPOLYGONOFFSETPROC                               gl3wPolygonOffset;\nextern PFNGLPOPDEBUGGROUPPROC                               gl3wPopDebugGroup;\nextern PFNGLPRIMITIVERESTARTINDEXPROC                       gl3wPrimitiveRestartIndex;\nextern PFNGLPROGRAMBINARYPROC                               gl3wProgramBinary;\nextern PFNGLPROGRAMPARAMETERIPROC                           gl3wProgramParameteri;\nextern PFNGLPROGRAMUNIFORM1DPROC                            gl3wProgramUniform1d;\nextern PFNGLPROGRAMUNIFORM1DVPROC                           gl3wProgramUniform1dv;\nextern PFNGLPROGRAMUNIFORM1FPROC                            gl3wProgramUniform1f;\nextern PFNGLPROGRAMUNIFORM1FVPROC                           gl3wProgramUniform1fv;\nextern PFNGLPROGRAMUNIFORM1IPROC                            gl3wProgramUniform1i;\nextern PFNGLPROGRAMUNIFORM1IVPROC                           gl3wProgramUniform1iv;\nextern PFNGLPROGRAMUNIFORM1UIPROC                           gl3wProgramUniform1ui;\nextern PFNGLPROGRAMUNIFORM1UIVPROC                          gl3wProgramUniform1uiv;\nextern PFNGLPROGRAMUNIFORM2DPROC                            gl3wProgramUniform2d;\nextern PFNGLPROGRAMUNIFORM2DVPROC                           gl3wProgramUniform2dv;\nextern PFNGLPROGRAMUNIFORM2FPROC                            gl3wProgramUniform2f;\nextern PFNGLPROGRAMUNIFORM2FVPROC                           gl3wProgramUniform2fv;\nextern PFNGLPROGRAMUNIFORM2IPROC                            gl3wProgramUniform2i;\nextern PFNGLPROGRAMUNIFORM2IVPROC                           gl3wProgramUniform2iv;\nextern PFNGLPROGRAMUNIFORM2UIPROC                           gl3wProgramUniform2ui;\nextern PFNGLPROGRAMUNIFORM2UIVPROC                          gl3wProgramUniform2uiv;\nextern PFNGLPROGRAMUNIFORM3DPROC                            gl3wProgramUniform3d;\nextern PFNGLPROGRAMUNIFORM3DVPROC                           gl3wProgramUniform3dv;\nextern PFNGLPROGRAMUNIFORM3FPROC                            gl3wProgramUniform3f;\nextern PFNGLPROGRAMUNIFORM3FVPROC                           gl3wProgramUniform3fv;\nextern PFNGLPROGRAMUNIFORM3IPROC                            gl3wProgramUniform3i;\nextern PFNGLPROGRAMUNIFORM3IVPROC                           gl3wProgramUniform3iv;\nextern PFNGLPROGRAMUNIFORM3UIPROC                           gl3wProgramUniform3ui;\nextern PFNGLPROGRAMUNIFORM3UIVPROC                          gl3wProgramUniform3uiv;\nextern PFNGLPROGRAMUNIFORM4DPROC                            gl3wProgramUniform4d;\nextern PFNGLPROGRAMUNIFORM4DVPROC                           gl3wProgramUniform4dv;\nextern PFNGLPROGRAMUNIFORM4FPROC                            gl3wProgramUniform4f;\nextern PFNGLPROGRAMUNIFORM4FVPROC                           gl3wProgramUniform4fv;\nextern PFNGLPROGRAMUNIFORM4IPROC                            gl3wProgramUniform4i;\nextern PFNGLPROGRAMUNIFORM4IVPROC                           gl3wProgramUniform4iv;\nextern PFNGLPROGRAMUNIFORM4UIPROC                           gl3wProgramUniform4ui;\nextern PFNGLPROGRAMUNIFORM4UIVPROC                          gl3wProgramUniform4uiv;\nextern PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC                 gl3wProgramUniformHandleui64ARB;\nextern PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC                gl3wProgramUniformHandleui64vARB;\nextern PFNGLPROGRAMUNIFORMMATRIX2DVPROC                     gl3wProgramUniformMatrix2dv;\nextern PFNGLPROGRAMUNIFORMMATRIX2FVPROC                     gl3wProgramUniformMatrix2fv;\nextern PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC                   gl3wProgramUniformMatrix2x3dv;\nextern PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC                   gl3wProgramUniformMatrix2x3fv;\nextern PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC                   gl3wProgramUniformMatrix2x4dv;\nextern PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC                   gl3wProgramUniformMatrix2x4fv;\nextern PFNGLPROGRAMUNIFORMMATRIX3DVPROC                     gl3wProgramUniformMatrix3dv;\nextern PFNGLPROGRAMUNIFORMMATRIX3FVPROC                     gl3wProgramUniformMatrix3fv;\nextern PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC                   gl3wProgramUniformMatrix3x2dv;\nextern PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC                   gl3wProgramUniformMatrix3x2fv;\nextern PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC                   gl3wProgramUniformMatrix3x4dv;\nextern PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC                   gl3wProgramUniformMatrix3x4fv;\nextern PFNGLPROGRAMUNIFORMMATRIX4DVPROC                     gl3wProgramUniformMatrix4dv;\nextern PFNGLPROGRAMUNIFORMMATRIX4FVPROC                     gl3wProgramUniformMatrix4fv;\nextern PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC                   gl3wProgramUniformMatrix4x2dv;\nextern PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC                   gl3wProgramUniformMatrix4x2fv;\nextern PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC                   gl3wProgramUniformMatrix4x3dv;\nextern PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC                   gl3wProgramUniformMatrix4x3fv;\nextern PFNGLPROVOKINGVERTEXPROC                             gl3wProvokingVertex;\nextern PFNGLPUSHDEBUGGROUPPROC                              gl3wPushDebugGroup;\nextern PFNGLQUERYCOUNTERPROC                                gl3wQueryCounter;\nextern PFNGLREADBUFFERPROC                                  gl3wReadBuffer;\nextern PFNGLREADPIXELSPROC                                  gl3wReadPixels;\nextern PFNGLREADNPIXELSPROC                                 gl3wReadnPixels;\nextern PFNGLREADNPIXELSARBPROC                              gl3wReadnPixelsARB;\nextern PFNGLRELEASESHADERCOMPILERPROC                       gl3wReleaseShaderCompiler;\nextern PFNGLRENDERBUFFERSTORAGEPROC                         gl3wRenderbufferStorage;\nextern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC              gl3wRenderbufferStorageMultisample;\nextern PFNGLRESUMETRANSFORMFEEDBACKPROC                     gl3wResumeTransformFeedback;\nextern PFNGLSAMPLECOVERAGEPROC                              gl3wSampleCoverage;\nextern PFNGLSAMPLEMASKIPROC                                 gl3wSampleMaski;\nextern PFNGLSAMPLERPARAMETERIIVPROC                         gl3wSamplerParameterIiv;\nextern PFNGLSAMPLERPARAMETERIUIVPROC                        gl3wSamplerParameterIuiv;\nextern PFNGLSAMPLERPARAMETERFPROC                           gl3wSamplerParameterf;\nextern PFNGLSAMPLERPARAMETERFVPROC                          gl3wSamplerParameterfv;\nextern PFNGLSAMPLERPARAMETERIPROC                           gl3wSamplerParameteri;\nextern PFNGLSAMPLERPARAMETERIVPROC                          gl3wSamplerParameteriv;\nextern PFNGLSCISSORPROC                                     gl3wScissor;\nextern PFNGLSCISSORARRAYVPROC                               gl3wScissorArrayv;\nextern PFNGLSCISSORINDEXEDPROC                              gl3wScissorIndexed;\nextern PFNGLSCISSORINDEXEDVPROC                             gl3wScissorIndexedv;\nextern PFNGLSHADERBINARYPROC                                gl3wShaderBinary;\nextern PFNGLSHADERSOURCEPROC                                gl3wShaderSource;\nextern PFNGLSHADERSTORAGEBLOCKBINDINGPROC                   gl3wShaderStorageBlockBinding;\nextern PFNGLSTENCILFUNCPROC                                 gl3wStencilFunc;\nextern PFNGLSTENCILFUNCSEPARATEPROC                         gl3wStencilFuncSeparate;\nextern PFNGLSTENCILMASKPROC                                 gl3wStencilMask;\nextern PFNGLSTENCILMASKSEPARATEPROC                         gl3wStencilMaskSeparate;\nextern PFNGLSTENCILOPPROC                                   gl3wStencilOp;\nextern PFNGLSTENCILOPSEPARATEPROC                           gl3wStencilOpSeparate;\nextern PFNGLTEXBUFFERPROC                                   gl3wTexBuffer;\nextern PFNGLTEXBUFFERRANGEPROC                              gl3wTexBufferRange;\nextern PFNGLTEXIMAGE1DPROC                                  gl3wTexImage1D;\nextern PFNGLTEXIMAGE2DPROC                                  gl3wTexImage2D;\nextern PFNGLTEXIMAGE2DMULTISAMPLEPROC                       gl3wTexImage2DMultisample;\nextern PFNGLTEXIMAGE3DPROC                                  gl3wTexImage3D;\nextern PFNGLTEXIMAGE3DMULTISAMPLEPROC                       gl3wTexImage3DMultisample;\nextern PFNGLTEXPAGECOMMITMENTARBPROC                        gl3wTexPageCommitmentARB;\nextern PFNGLTEXPARAMETERIIVPROC                             gl3wTexParameterIiv;\nextern PFNGLTEXPARAMETERIUIVPROC                            gl3wTexParameterIuiv;\nextern PFNGLTEXPARAMETERFPROC                               gl3wTexParameterf;\nextern PFNGLTEXPARAMETERFVPROC                              gl3wTexParameterfv;\nextern PFNGLTEXPARAMETERIPROC                               gl3wTexParameteri;\nextern PFNGLTEXPARAMETERIVPROC                              gl3wTexParameteriv;\nextern PFNGLTEXSTORAGE1DPROC                                gl3wTexStorage1D;\nextern PFNGLTEXSTORAGE2DPROC                                gl3wTexStorage2D;\nextern PFNGLTEXSTORAGE2DMULTISAMPLEPROC                     gl3wTexStorage2DMultisample;\nextern PFNGLTEXSTORAGE3DPROC                                gl3wTexStorage3D;\nextern PFNGLTEXSTORAGE3DMULTISAMPLEPROC                     gl3wTexStorage3DMultisample;\nextern PFNGLTEXSUBIMAGE1DPROC                               gl3wTexSubImage1D;\nextern PFNGLTEXSUBIMAGE2DPROC                               gl3wTexSubImage2D;\nextern PFNGLTEXSUBIMAGE3DPROC                               gl3wTexSubImage3D;\nextern PFNGLTEXTUREBARRIERPROC                              gl3wTextureBarrier;\nextern PFNGLTEXTUREBUFFERPROC                               gl3wTextureBuffer;\nextern PFNGLTEXTUREBUFFERRANGEPROC                          gl3wTextureBufferRange;\nextern PFNGLTEXTUREPARAMETERIIVPROC                         gl3wTextureParameterIiv;\nextern PFNGLTEXTUREPARAMETERIUIVPROC                        gl3wTextureParameterIuiv;\nextern PFNGLTEXTUREPARAMETERFPROC                           gl3wTextureParameterf;\nextern PFNGLTEXTUREPARAMETERFVPROC                          gl3wTextureParameterfv;\nextern PFNGLTEXTUREPARAMETERIPROC                           gl3wTextureParameteri;\nextern PFNGLTEXTUREPARAMETERIVPROC                          gl3wTextureParameteriv;\nextern PFNGLTEXTURESTORAGE1DPROC                            gl3wTextureStorage1D;\nextern PFNGLTEXTURESTORAGE2DPROC                            gl3wTextureStorage2D;\nextern PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC                 gl3wTextureStorage2DMultisample;\nextern PFNGLTEXTURESTORAGE3DPROC                            gl3wTextureStorage3D;\nextern PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC                 gl3wTextureStorage3DMultisample;\nextern PFNGLTEXTURESUBIMAGE1DPROC                           gl3wTextureSubImage1D;\nextern PFNGLTEXTURESUBIMAGE2DPROC                           gl3wTextureSubImage2D;\nextern PFNGLTEXTURESUBIMAGE3DPROC                           gl3wTextureSubImage3D;\nextern PFNGLTEXTUREVIEWPROC                                 gl3wTextureView;\nextern PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC                 gl3wTransformFeedbackBufferBase;\nextern PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC                gl3wTransformFeedbackBufferRange;\nextern PFNGLTRANSFORMFEEDBACKVARYINGSPROC                   gl3wTransformFeedbackVaryings;\nextern PFNGLUNIFORM1DPROC                                   gl3wUniform1d;\nextern PFNGLUNIFORM1DVPROC                                  gl3wUniform1dv;\nextern PFNGLUNIFORM1FPROC                                   gl3wUniform1f;\nextern PFNGLUNIFORM1FVPROC                                  gl3wUniform1fv;\nextern PFNGLUNIFORM1IPROC                                   gl3wUniform1i;\nextern PFNGLUNIFORM1IVPROC                                  gl3wUniform1iv;\nextern PFNGLUNIFORM1UIPROC                                  gl3wUniform1ui;\nextern PFNGLUNIFORM1UIVPROC                                 gl3wUniform1uiv;\nextern PFNGLUNIFORM2DPROC                                   gl3wUniform2d;\nextern PFNGLUNIFORM2DVPROC                                  gl3wUniform2dv;\nextern PFNGLUNIFORM2FPROC                                   gl3wUniform2f;\nextern PFNGLUNIFORM2FVPROC                                  gl3wUniform2fv;\nextern PFNGLUNIFORM2IPROC                                   gl3wUniform2i;\nextern PFNGLUNIFORM2IVPROC                                  gl3wUniform2iv;\nextern PFNGLUNIFORM2UIPROC                                  gl3wUniform2ui;\nextern PFNGLUNIFORM2UIVPROC                                 gl3wUniform2uiv;\nextern PFNGLUNIFORM3DPROC                                   gl3wUniform3d;\nextern PFNGLUNIFORM3DVPROC                                  gl3wUniform3dv;\nextern PFNGLUNIFORM3FPROC                                   gl3wUniform3f;\nextern PFNGLUNIFORM3FVPROC                                  gl3wUniform3fv;\nextern PFNGLUNIFORM3IPROC                                   gl3wUniform3i;\nextern PFNGLUNIFORM3IVPROC                                  gl3wUniform3iv;\nextern PFNGLUNIFORM3UIPROC                                  gl3wUniform3ui;\nextern PFNGLUNIFORM3UIVPROC                                 gl3wUniform3uiv;\nextern PFNGLUNIFORM4DPROC                                   gl3wUniform4d;\nextern PFNGLUNIFORM4DVPROC                                  gl3wUniform4dv;\nextern PFNGLUNIFORM4FPROC                                   gl3wUniform4f;\nextern PFNGLUNIFORM4FVPROC                                  gl3wUniform4fv;\nextern PFNGLUNIFORM4IPROC                                   gl3wUniform4i;\nextern PFNGLUNIFORM4IVPROC                                  gl3wUniform4iv;\nextern PFNGLUNIFORM4UIPROC                                  gl3wUniform4ui;\nextern PFNGLUNIFORM4UIVPROC                                 gl3wUniform4uiv;\nextern PFNGLUNIFORMBLOCKBINDINGPROC                         gl3wUniformBlockBinding;\nextern PFNGLUNIFORMHANDLEUI64ARBPROC                        gl3wUniformHandleui64ARB;\nextern PFNGLUNIFORMHANDLEUI64VARBPROC                       gl3wUniformHandleui64vARB;\nextern PFNGLUNIFORMMATRIX2DVPROC                            gl3wUniformMatrix2dv;\nextern PFNGLUNIFORMMATRIX2FVPROC                            gl3wUniformMatrix2fv;\nextern PFNGLUNIFORMMATRIX2X3DVPROC                          gl3wUniformMatrix2x3dv;\nextern PFNGLUNIFORMMATRIX2X3FVPROC                          gl3wUniformMatrix2x3fv;\nextern PFNGLUNIFORMMATRIX2X4DVPROC                          gl3wUniformMatrix2x4dv;\nextern PFNGLUNIFORMMATRIX2X4FVPROC                          gl3wUniformMatrix2x4fv;\nextern PFNGLUNIFORMMATRIX3DVPROC                            gl3wUniformMatrix3dv;\nextern PFNGLUNIFORMMATRIX3FVPROC                            gl3wUniformMatrix3fv;\nextern PFNGLUNIFORMMATRIX3X2DVPROC                          gl3wUniformMatrix3x2dv;\nextern PFNGLUNIFORMMATRIX3X2FVPROC                          gl3wUniformMatrix3x2fv;\nextern PFNGLUNIFORMMATRIX3X4DVPROC                          gl3wUniformMatrix3x4dv;\nextern PFNGLUNIFORMMATRIX3X4FVPROC                          gl3wUniformMatrix3x4fv;\nextern PFNGLUNIFORMMATRIX4DVPROC                            gl3wUniformMatrix4dv;\nextern PFNGLUNIFORMMATRIX4FVPROC                            gl3wUniformMatrix4fv;\nextern PFNGLUNIFORMMATRIX4X2DVPROC                          gl3wUniformMatrix4x2dv;\nextern PFNGLUNIFORMMATRIX4X2FVPROC                          gl3wUniformMatrix4x2fv;\nextern PFNGLUNIFORMMATRIX4X3DVPROC                          gl3wUniformMatrix4x3dv;\nextern PFNGLUNIFORMMATRIX4X3FVPROC                          gl3wUniformMatrix4x3fv;\nextern PFNGLUNIFORMSUBROUTINESUIVPROC                       gl3wUniformSubroutinesuiv;\nextern PFNGLUNMAPBUFFERPROC                                 gl3wUnmapBuffer;\nextern PFNGLUNMAPNAMEDBUFFERPROC                            gl3wUnmapNamedBuffer;\nextern PFNGLUSEPROGRAMPROC                                  gl3wUseProgram;\nextern PFNGLUSEPROGRAMSTAGESPROC                            gl3wUseProgramStages;\nextern PFNGLVALIDATEPROGRAMPROC                             gl3wValidateProgram;\nextern PFNGLVALIDATEPROGRAMPIPELINEPROC                     gl3wValidateProgramPipeline;\nextern PFNGLVERTEXARRAYATTRIBBINDINGPROC                    gl3wVertexArrayAttribBinding;\nextern PFNGLVERTEXARRAYATTRIBFORMATPROC                     gl3wVertexArrayAttribFormat;\nextern PFNGLVERTEXARRAYATTRIBIFORMATPROC                    gl3wVertexArrayAttribIFormat;\nextern PFNGLVERTEXARRAYATTRIBLFORMATPROC                    gl3wVertexArrayAttribLFormat;\nextern PFNGLVERTEXARRAYBINDINGDIVISORPROC                   gl3wVertexArrayBindingDivisor;\nextern PFNGLVERTEXARRAYELEMENTBUFFERPROC                    gl3wVertexArrayElementBuffer;\nextern PFNGLVERTEXARRAYVERTEXBUFFERPROC                     gl3wVertexArrayVertexBuffer;\nextern PFNGLVERTEXARRAYVERTEXBUFFERSPROC                    gl3wVertexArrayVertexBuffers;\nextern PFNGLVERTEXATTRIB1DPROC                              gl3wVertexAttrib1d;\nextern PFNGLVERTEXATTRIB1DVPROC                             gl3wVertexAttrib1dv;\nextern PFNGLVERTEXATTRIB1FPROC                              gl3wVertexAttrib1f;\nextern PFNGLVERTEXATTRIB1FVPROC                             gl3wVertexAttrib1fv;\nextern PFNGLVERTEXATTRIB1SPROC                              gl3wVertexAttrib1s;\nextern PFNGLVERTEXATTRIB1SVPROC                             gl3wVertexAttrib1sv;\nextern PFNGLVERTEXATTRIB2DPROC                              gl3wVertexAttrib2d;\nextern PFNGLVERTEXATTRIB2DVPROC                             gl3wVertexAttrib2dv;\nextern PFNGLVERTEXATTRIB2FPROC                              gl3wVertexAttrib2f;\nextern PFNGLVERTEXATTRIB2FVPROC                             gl3wVertexAttrib2fv;\nextern PFNGLVERTEXATTRIB2SPROC                              gl3wVertexAttrib2s;\nextern PFNGLVERTEXATTRIB2SVPROC                             gl3wVertexAttrib2sv;\nextern PFNGLVERTEXATTRIB3DPROC                              gl3wVertexAttrib3d;\nextern PFNGLVERTEXATTRIB3DVPROC                             gl3wVertexAttrib3dv;\nextern PFNGLVERTEXATTRIB3FPROC                              gl3wVertexAttrib3f;\nextern PFNGLVERTEXATTRIB3FVPROC                             gl3wVertexAttrib3fv;\nextern PFNGLVERTEXATTRIB3SPROC                              gl3wVertexAttrib3s;\nextern PFNGLVERTEXATTRIB3SVPROC                             gl3wVertexAttrib3sv;\nextern PFNGLVERTEXATTRIB4NBVPROC                            gl3wVertexAttrib4Nbv;\nextern PFNGLVERTEXATTRIB4NIVPROC                            gl3wVertexAttrib4Niv;\nextern PFNGLVERTEXATTRIB4NSVPROC                            gl3wVertexAttrib4Nsv;\nextern PFNGLVERTEXATTRIB4NUBPROC                            gl3wVertexAttrib4Nub;\nextern PFNGLVERTEXATTRIB4NUBVPROC                           gl3wVertexAttrib4Nubv;\nextern PFNGLVERTEXATTRIB4NUIVPROC                           gl3wVertexAttrib4Nuiv;\nextern PFNGLVERTEXATTRIB4NUSVPROC                           gl3wVertexAttrib4Nusv;\nextern PFNGLVERTEXATTRIB4BVPROC                             gl3wVertexAttrib4bv;\nextern PFNGLVERTEXATTRIB4DPROC                              gl3wVertexAttrib4d;\nextern PFNGLVERTEXATTRIB4DVPROC                             gl3wVertexAttrib4dv;\nextern PFNGLVERTEXATTRIB4FPROC                              gl3wVertexAttrib4f;\nextern PFNGLVERTEXATTRIB4FVPROC                             gl3wVertexAttrib4fv;\nextern PFNGLVERTEXATTRIB4IVPROC                             gl3wVertexAttrib4iv;\nextern PFNGLVERTEXATTRIB4SPROC                              gl3wVertexAttrib4s;\nextern PFNGLVERTEXATTRIB4SVPROC                             gl3wVertexAttrib4sv;\nextern PFNGLVERTEXATTRIB4UBVPROC                            gl3wVertexAttrib4ubv;\nextern PFNGLVERTEXATTRIB4UIVPROC                            gl3wVertexAttrib4uiv;\nextern PFNGLVERTEXATTRIB4USVPROC                            gl3wVertexAttrib4usv;\nextern PFNGLVERTEXATTRIBBINDINGPROC                         gl3wVertexAttribBinding;\nextern PFNGLVERTEXATTRIBDIVISORPROC                         gl3wVertexAttribDivisor;\nextern PFNGLVERTEXATTRIBFORMATPROC                          gl3wVertexAttribFormat;\nextern PFNGLVERTEXATTRIBI1IPROC                             gl3wVertexAttribI1i;\nextern PFNGLVERTEXATTRIBI1IVPROC                            gl3wVertexAttribI1iv;\nextern PFNGLVERTEXATTRIBI1UIPROC                            gl3wVertexAttribI1ui;\nextern PFNGLVERTEXATTRIBI1UIVPROC                           gl3wVertexAttribI1uiv;\nextern PFNGLVERTEXATTRIBI2IPROC                             gl3wVertexAttribI2i;\nextern PFNGLVERTEXATTRIBI2IVPROC                            gl3wVertexAttribI2iv;\nextern PFNGLVERTEXATTRIBI2UIPROC                            gl3wVertexAttribI2ui;\nextern PFNGLVERTEXATTRIBI2UIVPROC                           gl3wVertexAttribI2uiv;\nextern PFNGLVERTEXATTRIBI3IPROC                             gl3wVertexAttribI3i;\nextern PFNGLVERTEXATTRIBI3IVPROC                            gl3wVertexAttribI3iv;\nextern PFNGLVERTEXATTRIBI3UIPROC                            gl3wVertexAttribI3ui;\nextern PFNGLVERTEXATTRIBI3UIVPROC                           gl3wVertexAttribI3uiv;\nextern PFNGLVERTEXATTRIBI4BVPROC                            gl3wVertexAttribI4bv;\nextern PFNGLVERTEXATTRIBI4IPROC                             gl3wVertexAttribI4i;\nextern PFNGLVERTEXATTRIBI4IVPROC                            gl3wVertexAttribI4iv;\nextern PFNGLVERTEXATTRIBI4SVPROC                            gl3wVertexAttribI4sv;\nextern PFNGLVERTEXATTRIBI4UBVPROC                           gl3wVertexAttribI4ubv;\nextern PFNGLVERTEXATTRIBI4UIPROC                            gl3wVertexAttribI4ui;\nextern PFNGLVERTEXATTRIBI4UIVPROC                           gl3wVertexAttribI4uiv;\nextern PFNGLVERTEXATTRIBI4USVPROC                           gl3wVertexAttribI4usv;\nextern PFNGLVERTEXATTRIBIFORMATPROC                         gl3wVertexAttribIFormat;\nextern PFNGLVERTEXATTRIBIPOINTERPROC                        gl3wVertexAttribIPointer;\nextern PFNGLVERTEXATTRIBL1DPROC                             gl3wVertexAttribL1d;\nextern PFNGLVERTEXATTRIBL1DVPROC                            gl3wVertexAttribL1dv;\nextern PFNGLVERTEXATTRIBL1UI64ARBPROC                       gl3wVertexAttribL1ui64ARB;\nextern PFNGLVERTEXATTRIBL1UI64VARBPROC                      gl3wVertexAttribL1ui64vARB;\nextern PFNGLVERTEXATTRIBL2DPROC                             gl3wVertexAttribL2d;\nextern PFNGLVERTEXATTRIBL2DVPROC                            gl3wVertexAttribL2dv;\nextern PFNGLVERTEXATTRIBL3DPROC                             gl3wVertexAttribL3d;\nextern PFNGLVERTEXATTRIBL3DVPROC                            gl3wVertexAttribL3dv;\nextern PFNGLVERTEXATTRIBL4DPROC                             gl3wVertexAttribL4d;\nextern PFNGLVERTEXATTRIBL4DVPROC                            gl3wVertexAttribL4dv;\nextern PFNGLVERTEXATTRIBLFORMATPROC                         gl3wVertexAttribLFormat;\nextern PFNGLVERTEXATTRIBLPOINTERPROC                        gl3wVertexAttribLPointer;\nextern PFNGLVERTEXATTRIBP1UIPROC                            gl3wVertexAttribP1ui;\nextern PFNGLVERTEXATTRIBP1UIVPROC                           gl3wVertexAttribP1uiv;\nextern PFNGLVERTEXATTRIBP2UIPROC                            gl3wVertexAttribP2ui;\nextern PFNGLVERTEXATTRIBP2UIVPROC                           gl3wVertexAttribP2uiv;\nextern PFNGLVERTEXATTRIBP3UIPROC                            gl3wVertexAttribP3ui;\nextern PFNGLVERTEXATTRIBP3UIVPROC                           gl3wVertexAttribP3uiv;\nextern PFNGLVERTEXATTRIBP4UIPROC                            gl3wVertexAttribP4ui;\nextern PFNGLVERTEXATTRIBP4UIVPROC                           gl3wVertexAttribP4uiv;\nextern PFNGLVERTEXATTRIBPOINTERPROC                         gl3wVertexAttribPointer;\nextern PFNGLVERTEXBINDINGDIVISORPROC                        gl3wVertexBindingDivisor;\nextern PFNGLVIEWPORTPROC                                    gl3wViewport;\nextern PFNGLVIEWPORTARRAYVPROC                              gl3wViewportArrayv;\nextern PFNGLVIEWPORTINDEXEDFPROC                            gl3wViewportIndexedf;\nextern PFNGLVIEWPORTINDEXEDFVPROC                           gl3wViewportIndexedfv;\nextern PFNGLWAITSYNCPROC                                    gl3wWaitSync;\n\n#define glActiveShaderProgram                               gl3wActiveShaderProgram\n#define glActiveTexture                                     gl3wActiveTexture\n#define glAttachShader                                      gl3wAttachShader\n#define glBeginConditionalRender                            gl3wBeginConditionalRender\n#define glBeginQuery                                        gl3wBeginQuery\n#define glBeginQueryIndexed                                 gl3wBeginQueryIndexed\n#define glBeginTransformFeedback                            gl3wBeginTransformFeedback\n#define glBindAttribLocation                                gl3wBindAttribLocation\n#define glBindBuffer                                        gl3wBindBuffer\n#define glBindBufferBase                                    gl3wBindBufferBase\n#define glBindBufferRange                                   gl3wBindBufferRange\n#define glBindBuffersBase                                   gl3wBindBuffersBase\n#define glBindBuffersRange                                  gl3wBindBuffersRange\n#define glBindFragDataLocation                              gl3wBindFragDataLocation\n#define glBindFragDataLocationIndexed                       gl3wBindFragDataLocationIndexed\n#define glBindFramebuffer                                   gl3wBindFramebuffer\n#define glBindImageTexture                                  gl3wBindImageTexture\n#define glBindImageTextures                                 gl3wBindImageTextures\n#define glBindProgramPipeline                               gl3wBindProgramPipeline\n#define glBindRenderbuffer                                  gl3wBindRenderbuffer\n#define glBindSampler                                       gl3wBindSampler\n#define glBindSamplers                                      gl3wBindSamplers\n#define glBindTexture                                       gl3wBindTexture\n#define glBindTextureUnit                                   gl3wBindTextureUnit\n#define glBindTextures                                      gl3wBindTextures\n#define glBindTransformFeedback                             gl3wBindTransformFeedback\n#define glBindVertexArray                                   gl3wBindVertexArray\n#define glBindVertexBuffer                                  gl3wBindVertexBuffer\n#define glBindVertexBuffers                                 gl3wBindVertexBuffers\n#define glBlendColor                                        gl3wBlendColor\n#define glBlendEquation                                     gl3wBlendEquation\n#define glBlendEquationSeparate                             gl3wBlendEquationSeparate\n#define glBlendEquationSeparatei                            gl3wBlendEquationSeparatei\n#define glBlendEquationSeparateiARB                         gl3wBlendEquationSeparateiARB\n#define glBlendEquationi                                    gl3wBlendEquationi\n#define glBlendEquationiARB                                 gl3wBlendEquationiARB\n#define glBlendFunc                                         gl3wBlendFunc\n#define glBlendFuncSeparate                                 gl3wBlendFuncSeparate\n#define glBlendFuncSeparatei                                gl3wBlendFuncSeparatei\n#define glBlendFuncSeparateiARB                             gl3wBlendFuncSeparateiARB\n#define glBlendFunci                                        gl3wBlendFunci\n#define glBlendFunciARB                                     gl3wBlendFunciARB\n#define glBlitFramebuffer                                   gl3wBlitFramebuffer\n#define glBlitNamedFramebuffer                              gl3wBlitNamedFramebuffer\n#define glBufferData                                        gl3wBufferData\n#define glBufferPageCommitmentARB                           gl3wBufferPageCommitmentARB\n#define glBufferStorage                                     gl3wBufferStorage\n#define glBufferSubData                                     gl3wBufferSubData\n#define glCheckFramebufferStatus                            gl3wCheckFramebufferStatus\n#define glCheckNamedFramebufferStatus                       gl3wCheckNamedFramebufferStatus\n#define glClampColor                                        gl3wClampColor\n#define glClear                                             gl3wClear\n#define glClearBufferData                                   gl3wClearBufferData\n#define glClearBufferSubData                                gl3wClearBufferSubData\n#define glClearBufferfi                                     gl3wClearBufferfi\n#define glClearBufferfv                                     gl3wClearBufferfv\n#define glClearBufferiv                                     gl3wClearBufferiv\n#define glClearBufferuiv                                    gl3wClearBufferuiv\n#define glClearColor                                        gl3wClearColor\n#define glClearDepth                                        gl3wClearDepth\n#define glClearDepthf                                       gl3wClearDepthf\n#define glClearNamedBufferData                              gl3wClearNamedBufferData\n#define glClearNamedBufferSubData                           gl3wClearNamedBufferSubData\n#define glClearNamedFramebufferfi                           gl3wClearNamedFramebufferfi\n#define glClearNamedFramebufferfv                           gl3wClearNamedFramebufferfv\n#define glClearNamedFramebufferiv                           gl3wClearNamedFramebufferiv\n#define glClearNamedFramebufferuiv                          gl3wClearNamedFramebufferuiv\n#define glClearStencil                                      gl3wClearStencil\n#define glClearTexImage                                     gl3wClearTexImage\n#define glClearTexSubImage                                  gl3wClearTexSubImage\n#define glClientWaitSync                                    gl3wClientWaitSync\n#define glClipControl                                       gl3wClipControl\n#define glColorMask                                         gl3wColorMask\n#define glColorMaski                                        gl3wColorMaski\n#define glCompileShader                                     gl3wCompileShader\n#define glCompileShaderIncludeARB                           gl3wCompileShaderIncludeARB\n#define glCompressedTexImage1D                              gl3wCompressedTexImage1D\n#define glCompressedTexImage2D                              gl3wCompressedTexImage2D\n#define glCompressedTexImage3D                              gl3wCompressedTexImage3D\n#define glCompressedTexSubImage1D                           gl3wCompressedTexSubImage1D\n#define glCompressedTexSubImage2D                           gl3wCompressedTexSubImage2D\n#define glCompressedTexSubImage3D                           gl3wCompressedTexSubImage3D\n#define glCompressedTextureSubImage1D                       gl3wCompressedTextureSubImage1D\n#define glCompressedTextureSubImage2D                       gl3wCompressedTextureSubImage2D\n#define glCompressedTextureSubImage3D                       gl3wCompressedTextureSubImage3D\n#define glCopyBufferSubData                                 gl3wCopyBufferSubData\n#define glCopyImageSubData                                  gl3wCopyImageSubData\n#define glCopyNamedBufferSubData                            gl3wCopyNamedBufferSubData\n#define glCopyTexImage1D                                    gl3wCopyTexImage1D\n#define glCopyTexImage2D                                    gl3wCopyTexImage2D\n#define glCopyTexSubImage1D                                 gl3wCopyTexSubImage1D\n#define glCopyTexSubImage2D                                 gl3wCopyTexSubImage2D\n#define glCopyTexSubImage3D                                 gl3wCopyTexSubImage3D\n#define glCopyTextureSubImage1D                             gl3wCopyTextureSubImage1D\n#define glCopyTextureSubImage2D                             gl3wCopyTextureSubImage2D\n#define glCopyTextureSubImage3D                             gl3wCopyTextureSubImage3D\n#define glCreateBuffers                                     gl3wCreateBuffers\n#define glCreateFramebuffers                                gl3wCreateFramebuffers\n#define glCreateProgram                                     gl3wCreateProgram\n#define glCreateProgramPipelines                            gl3wCreateProgramPipelines\n#define glCreateQueries                                     gl3wCreateQueries\n#define glCreateRenderbuffers                               gl3wCreateRenderbuffers\n#define glCreateSamplers                                    gl3wCreateSamplers\n#define glCreateShader                                      gl3wCreateShader\n#define glCreateShaderProgramv                              gl3wCreateShaderProgramv\n#define glCreateSyncFromCLeventARB                          gl3wCreateSyncFromCLeventARB\n#define glCreateTextures                                    gl3wCreateTextures\n#define glCreateTransformFeedbacks                          gl3wCreateTransformFeedbacks\n#define glCreateVertexArrays                                gl3wCreateVertexArrays\n#define glCullFace                                          gl3wCullFace\n#define glDebugMessageCallback                              gl3wDebugMessageCallback\n#define glDebugMessageCallbackARB                           gl3wDebugMessageCallbackARB\n#define glDebugMessageControl                               gl3wDebugMessageControl\n#define glDebugMessageControlARB                            gl3wDebugMessageControlARB\n#define glDebugMessageInsert                                gl3wDebugMessageInsert\n#define glDebugMessageInsertARB                             gl3wDebugMessageInsertARB\n#define glDeleteBuffers                                     gl3wDeleteBuffers\n#define glDeleteFramebuffers                                gl3wDeleteFramebuffers\n#define glDeleteNamedStringARB                              gl3wDeleteNamedStringARB\n#define glDeleteProgram                                     gl3wDeleteProgram\n#define glDeleteProgramPipelines                            gl3wDeleteProgramPipelines\n#define glDeleteQueries                                     gl3wDeleteQueries\n#define glDeleteRenderbuffers                               gl3wDeleteRenderbuffers\n#define glDeleteSamplers                                    gl3wDeleteSamplers\n#define glDeleteShader                                      gl3wDeleteShader\n#define glDeleteSync                                        gl3wDeleteSync\n#define glDeleteTextures                                    gl3wDeleteTextures\n#define glDeleteTransformFeedbacks                          gl3wDeleteTransformFeedbacks\n#define glDeleteVertexArrays                                gl3wDeleteVertexArrays\n#define glDepthFunc                                         gl3wDepthFunc\n#define glDepthMask                                         gl3wDepthMask\n#define glDepthRange                                        gl3wDepthRange\n#define glDepthRangeArrayv                                  gl3wDepthRangeArrayv\n#define glDepthRangeIndexed                                 gl3wDepthRangeIndexed\n#define glDepthRangef                                       gl3wDepthRangef\n#define glDetachShader                                      gl3wDetachShader\n#define glDisable                                           gl3wDisable\n#define glDisableVertexArrayAttrib                          gl3wDisableVertexArrayAttrib\n#define glDisableVertexAttribArray                          gl3wDisableVertexAttribArray\n#define glDisablei                                          gl3wDisablei\n#define glDispatchCompute                                   gl3wDispatchCompute\n#define glDispatchComputeGroupSizeARB                       gl3wDispatchComputeGroupSizeARB\n#define glDispatchComputeIndirect                           gl3wDispatchComputeIndirect\n#define glDrawArrays                                        gl3wDrawArrays\n#define glDrawArraysIndirect                                gl3wDrawArraysIndirect\n#define glDrawArraysInstanced                               gl3wDrawArraysInstanced\n#define glDrawArraysInstancedBaseInstance                   gl3wDrawArraysInstancedBaseInstance\n#define glDrawBuffer                                        gl3wDrawBuffer\n#define glDrawBuffers                                       gl3wDrawBuffers\n#define glDrawElements                                      gl3wDrawElements\n#define glDrawElementsBaseVertex                            gl3wDrawElementsBaseVertex\n#define glDrawElementsIndirect                              gl3wDrawElementsIndirect\n#define glDrawElementsInstanced                             gl3wDrawElementsInstanced\n#define glDrawElementsInstancedBaseInstance                 gl3wDrawElementsInstancedBaseInstance\n#define glDrawElementsInstancedBaseVertex                   gl3wDrawElementsInstancedBaseVertex\n#define glDrawElementsInstancedBaseVertexBaseInstance       gl3wDrawElementsInstancedBaseVertexBaseInstance\n#define glDrawRangeElements                                 gl3wDrawRangeElements\n#define glDrawRangeElementsBaseVertex                       gl3wDrawRangeElementsBaseVertex\n#define glDrawTransformFeedback                             gl3wDrawTransformFeedback\n#define glDrawTransformFeedbackInstanced                    gl3wDrawTransformFeedbackInstanced\n#define glDrawTransformFeedbackStream                       gl3wDrawTransformFeedbackStream\n#define glDrawTransformFeedbackStreamInstanced              gl3wDrawTransformFeedbackStreamInstanced\n#define glEnable                                            gl3wEnable\n#define glEnableVertexArrayAttrib                           gl3wEnableVertexArrayAttrib\n#define glEnableVertexAttribArray                           gl3wEnableVertexAttribArray\n#define glEnablei                                           gl3wEnablei\n#define glEndConditionalRender                              gl3wEndConditionalRender\n#define glEndQuery                                          gl3wEndQuery\n#define glEndQueryIndexed                                   gl3wEndQueryIndexed\n#define glEndTransformFeedback                              gl3wEndTransformFeedback\n#define glFenceSync                                         gl3wFenceSync\n#define glFinish                                            gl3wFinish\n#define glFlush                                             gl3wFlush\n#define glFlushMappedBufferRange                            gl3wFlushMappedBufferRange\n#define glFlushMappedNamedBufferRange                       gl3wFlushMappedNamedBufferRange\n#define glFramebufferParameteri                             gl3wFramebufferParameteri\n#define glFramebufferRenderbuffer                           gl3wFramebufferRenderbuffer\n#define glFramebufferTexture                                gl3wFramebufferTexture\n#define glFramebufferTexture1D                              gl3wFramebufferTexture1D\n#define glFramebufferTexture2D                              gl3wFramebufferTexture2D\n#define glFramebufferTexture3D                              gl3wFramebufferTexture3D\n#define glFramebufferTextureLayer                           gl3wFramebufferTextureLayer\n#define glFrontFace                                         gl3wFrontFace\n#define glGenBuffers                                        gl3wGenBuffers\n#define glGenFramebuffers                                   gl3wGenFramebuffers\n#define glGenProgramPipelines                               gl3wGenProgramPipelines\n#define glGenQueries                                        gl3wGenQueries\n#define glGenRenderbuffers                                  gl3wGenRenderbuffers\n#define glGenSamplers                                       gl3wGenSamplers\n#define glGenTextures                                       gl3wGenTextures\n#define glGenTransformFeedbacks                             gl3wGenTransformFeedbacks\n#define glGenVertexArrays                                   gl3wGenVertexArrays\n#define glGenerateMipmap                                    gl3wGenerateMipmap\n#define glGenerateTextureMipmap                             gl3wGenerateTextureMipmap\n#define glGetActiveAtomicCounterBufferiv                    gl3wGetActiveAtomicCounterBufferiv\n#define glGetActiveAttrib                                   gl3wGetActiveAttrib\n#define glGetActiveSubroutineName                           gl3wGetActiveSubroutineName\n#define glGetActiveSubroutineUniformName                    gl3wGetActiveSubroutineUniformName\n#define glGetActiveSubroutineUniformiv                      gl3wGetActiveSubroutineUniformiv\n#define glGetActiveUniform                                  gl3wGetActiveUniform\n#define glGetActiveUniformBlockName                         gl3wGetActiveUniformBlockName\n#define glGetActiveUniformBlockiv                           gl3wGetActiveUniformBlockiv\n#define glGetActiveUniformName                              gl3wGetActiveUniformName\n#define glGetActiveUniformsiv                               gl3wGetActiveUniformsiv\n#define glGetAttachedShaders                                gl3wGetAttachedShaders\n#define glGetAttribLocation                                 gl3wGetAttribLocation\n#define glGetBooleani_v                                     gl3wGetBooleani_v\n#define glGetBooleanv                                       gl3wGetBooleanv\n#define glGetBufferParameteri64v                            gl3wGetBufferParameteri64v\n#define glGetBufferParameteriv                              gl3wGetBufferParameteriv\n#define glGetBufferPointerv                                 gl3wGetBufferPointerv\n#define glGetBufferSubData                                  gl3wGetBufferSubData\n#define glGetCompressedTexImage                             gl3wGetCompressedTexImage\n#define glGetCompressedTextureImage                         gl3wGetCompressedTextureImage\n#define glGetCompressedTextureSubImage                      gl3wGetCompressedTextureSubImage\n#define glGetDebugMessageLog                                gl3wGetDebugMessageLog\n#define glGetDebugMessageLogARB                             gl3wGetDebugMessageLogARB\n#define glGetDoublei_v                                      gl3wGetDoublei_v\n#define glGetDoublev                                        gl3wGetDoublev\n#define glGetError                                          gl3wGetError\n#define glGetFloati_v                                       gl3wGetFloati_v\n#define glGetFloatv                                         gl3wGetFloatv\n#define glGetFragDataIndex                                  gl3wGetFragDataIndex\n#define glGetFragDataLocation                               gl3wGetFragDataLocation\n#define glGetFramebufferAttachmentParameteriv               gl3wGetFramebufferAttachmentParameteriv\n#define glGetFramebufferParameteriv                         gl3wGetFramebufferParameteriv\n#define glGetGraphicsResetStatus                            gl3wGetGraphicsResetStatus\n#define glGetGraphicsResetStatusARB                         gl3wGetGraphicsResetStatusARB\n#define glGetImageHandleARB                                 gl3wGetImageHandleARB\n#define glGetInteger64i_v                                   gl3wGetInteger64i_v\n#define glGetInteger64v                                     gl3wGetInteger64v\n#define glGetIntegeri_v                                     gl3wGetIntegeri_v\n#define glGetIntegerv                                       gl3wGetIntegerv\n#define glGetInternalformati64v                             gl3wGetInternalformati64v\n#define glGetInternalformativ                               gl3wGetInternalformativ\n#define glGetMultisamplefv                                  gl3wGetMultisamplefv\n#define glGetNamedBufferParameteri64v                       gl3wGetNamedBufferParameteri64v\n#define glGetNamedBufferParameteriv                         gl3wGetNamedBufferParameteriv\n#define glGetNamedBufferPointerv                            gl3wGetNamedBufferPointerv\n#define glGetNamedBufferSubData                             gl3wGetNamedBufferSubData\n#define glGetNamedFramebufferAttachmentParameteriv          gl3wGetNamedFramebufferAttachmentParameteriv\n#define glGetNamedFramebufferParameteriv                    gl3wGetNamedFramebufferParameteriv\n#define glGetNamedRenderbufferParameteriv                   gl3wGetNamedRenderbufferParameteriv\n#define glGetNamedStringARB                                 gl3wGetNamedStringARB\n#define glGetNamedStringivARB                               gl3wGetNamedStringivARB\n#define glGetObjectLabel                                    gl3wGetObjectLabel\n#define glGetObjectPtrLabel                                 gl3wGetObjectPtrLabel\n#define glGetPointerv                                       gl3wGetPointerv\n#define glGetProgramBinary                                  gl3wGetProgramBinary\n#define glGetProgramInfoLog                                 gl3wGetProgramInfoLog\n#define glGetProgramInterfaceiv                             gl3wGetProgramInterfaceiv\n#define glGetProgramPipelineInfoLog                         gl3wGetProgramPipelineInfoLog\n#define glGetProgramPipelineiv                              gl3wGetProgramPipelineiv\n#define glGetProgramResourceIndex                           gl3wGetProgramResourceIndex\n#define glGetProgramResourceLocation                        gl3wGetProgramResourceLocation\n#define glGetProgramResourceLocationIndex                   gl3wGetProgramResourceLocationIndex\n#define glGetProgramResourceName                            gl3wGetProgramResourceName\n#define glGetProgramResourceiv                              gl3wGetProgramResourceiv\n#define glGetProgramStageiv                                 gl3wGetProgramStageiv\n#define glGetProgramiv                                      gl3wGetProgramiv\n#define glGetQueryBufferObjecti64v                          gl3wGetQueryBufferObjecti64v\n#define glGetQueryBufferObjectiv                            gl3wGetQueryBufferObjectiv\n#define glGetQueryBufferObjectui64v                         gl3wGetQueryBufferObjectui64v\n#define glGetQueryBufferObjectuiv                           gl3wGetQueryBufferObjectuiv\n#define glGetQueryIndexediv                                 gl3wGetQueryIndexediv\n#define glGetQueryObjecti64v                                gl3wGetQueryObjecti64v\n#define glGetQueryObjectiv                                  gl3wGetQueryObjectiv\n#define glGetQueryObjectui64v                               gl3wGetQueryObjectui64v\n#define glGetQueryObjectuiv                                 gl3wGetQueryObjectuiv\n#define glGetQueryiv                                        gl3wGetQueryiv\n#define glGetRenderbufferParameteriv                        gl3wGetRenderbufferParameteriv\n#define glGetSamplerParameterIiv                            gl3wGetSamplerParameterIiv\n#define glGetSamplerParameterIuiv                           gl3wGetSamplerParameterIuiv\n#define glGetSamplerParameterfv                             gl3wGetSamplerParameterfv\n#define glGetSamplerParameteriv                             gl3wGetSamplerParameteriv\n#define glGetShaderInfoLog                                  gl3wGetShaderInfoLog\n#define glGetShaderPrecisionFormat                          gl3wGetShaderPrecisionFormat\n#define glGetShaderSource                                   gl3wGetShaderSource\n#define glGetShaderiv                                       gl3wGetShaderiv\n#define glGetString                                         gl3wGetString\n#define glGetStringi                                        gl3wGetStringi\n#define glGetSubroutineIndex                                gl3wGetSubroutineIndex\n#define glGetSubroutineUniformLocation                      gl3wGetSubroutineUniformLocation\n#define glGetSynciv                                         gl3wGetSynciv\n#define glGetTexImage                                       gl3wGetTexImage\n#define glGetTexLevelParameterfv                            gl3wGetTexLevelParameterfv\n#define glGetTexLevelParameteriv                            gl3wGetTexLevelParameteriv\n#define glGetTexParameterIiv                                gl3wGetTexParameterIiv\n#define glGetTexParameterIuiv                               gl3wGetTexParameterIuiv\n#define glGetTexParameterfv                                 gl3wGetTexParameterfv\n#define glGetTexParameteriv                                 gl3wGetTexParameteriv\n#define glGetTextureHandleARB                               gl3wGetTextureHandleARB\n#define glGetTextureImage                                   gl3wGetTextureImage\n#define glGetTextureLevelParameterfv                        gl3wGetTextureLevelParameterfv\n#define glGetTextureLevelParameteriv                        gl3wGetTextureLevelParameteriv\n#define glGetTextureParameterIiv                            gl3wGetTextureParameterIiv\n#define glGetTextureParameterIuiv                           gl3wGetTextureParameterIuiv\n#define glGetTextureParameterfv                             gl3wGetTextureParameterfv\n#define glGetTextureParameteriv                             gl3wGetTextureParameteriv\n#define glGetTextureSamplerHandleARB                        gl3wGetTextureSamplerHandleARB\n#define glGetTextureSubImage                                gl3wGetTextureSubImage\n#define glGetTransformFeedbackVarying                       gl3wGetTransformFeedbackVarying\n#define glGetTransformFeedbacki64_v                         gl3wGetTransformFeedbacki64_v\n#define glGetTransformFeedbacki_v                           gl3wGetTransformFeedbacki_v\n#define glGetTransformFeedbackiv                            gl3wGetTransformFeedbackiv\n#define glGetUniformBlockIndex                              gl3wGetUniformBlockIndex\n#define glGetUniformIndices                                 gl3wGetUniformIndices\n#define glGetUniformLocation                                gl3wGetUniformLocation\n#define glGetUniformSubroutineuiv                           gl3wGetUniformSubroutineuiv\n#define glGetUniformdv                                      gl3wGetUniformdv\n#define glGetUniformfv                                      gl3wGetUniformfv\n#define glGetUniformiv                                      gl3wGetUniformiv\n#define glGetUniformuiv                                     gl3wGetUniformuiv\n#define glGetVertexArrayIndexed64iv                         gl3wGetVertexArrayIndexed64iv\n#define glGetVertexArrayIndexediv                           gl3wGetVertexArrayIndexediv\n#define glGetVertexArrayiv                                  gl3wGetVertexArrayiv\n#define glGetVertexAttribIiv                                gl3wGetVertexAttribIiv\n#define glGetVertexAttribIuiv                               gl3wGetVertexAttribIuiv\n#define glGetVertexAttribLdv                                gl3wGetVertexAttribLdv\n#define glGetVertexAttribLui64vARB                          gl3wGetVertexAttribLui64vARB\n#define glGetVertexAttribPointerv                           gl3wGetVertexAttribPointerv\n#define glGetVertexAttribdv                                 gl3wGetVertexAttribdv\n#define glGetVertexAttribfv                                 gl3wGetVertexAttribfv\n#define glGetVertexAttribiv                                 gl3wGetVertexAttribiv\n#define glGetnCompressedTexImage                            gl3wGetnCompressedTexImage\n#define glGetnCompressedTexImageARB                         gl3wGetnCompressedTexImageARB\n#define glGetnTexImage                                      gl3wGetnTexImage\n#define glGetnTexImageARB                                   gl3wGetnTexImageARB\n#define glGetnUniformdv                                     gl3wGetnUniformdv\n#define glGetnUniformdvARB                                  gl3wGetnUniformdvARB\n#define glGetnUniformfv                                     gl3wGetnUniformfv\n#define glGetnUniformfvARB                                  gl3wGetnUniformfvARB\n#define glGetnUniformiv                                     gl3wGetnUniformiv\n#define glGetnUniformivARB                                  gl3wGetnUniformivARB\n#define glGetnUniformuiv                                    gl3wGetnUniformuiv\n#define glGetnUniformuivARB                                 gl3wGetnUniformuivARB\n#define glHint                                              gl3wHint\n#define glInvalidateBufferData                              gl3wInvalidateBufferData\n#define glInvalidateBufferSubData                           gl3wInvalidateBufferSubData\n#define glInvalidateFramebuffer                             gl3wInvalidateFramebuffer\n#define glInvalidateNamedFramebufferData                    gl3wInvalidateNamedFramebufferData\n#define glInvalidateNamedFramebufferSubData                 gl3wInvalidateNamedFramebufferSubData\n#define glInvalidateSubFramebuffer                          gl3wInvalidateSubFramebuffer\n#define glInvalidateTexImage                                gl3wInvalidateTexImage\n#define glInvalidateTexSubImage                             gl3wInvalidateTexSubImage\n#define glIsBuffer                                          gl3wIsBuffer\n#define glIsEnabled                                         gl3wIsEnabled\n#define glIsEnabledi                                        gl3wIsEnabledi\n#define glIsFramebuffer                                     gl3wIsFramebuffer\n#define glIsImageHandleResidentARB                          gl3wIsImageHandleResidentARB\n#define glIsNamedStringARB                                  gl3wIsNamedStringARB\n#define glIsProgram                                         gl3wIsProgram\n#define glIsProgramPipeline                                 gl3wIsProgramPipeline\n#define glIsQuery                                           gl3wIsQuery\n#define glIsRenderbuffer                                    gl3wIsRenderbuffer\n#define glIsSampler                                         gl3wIsSampler\n#define glIsShader                                          gl3wIsShader\n#define glIsSync                                            gl3wIsSync\n#define glIsTexture                                         gl3wIsTexture\n#define glIsTextureHandleResidentARB                        gl3wIsTextureHandleResidentARB\n#define glIsTransformFeedback                               gl3wIsTransformFeedback\n#define glIsVertexArray                                     gl3wIsVertexArray\n#define glLineWidth                                         gl3wLineWidth\n#define glLinkProgram                                       gl3wLinkProgram\n#define glLogicOp                                           gl3wLogicOp\n#define glMakeImageHandleNonResidentARB                     gl3wMakeImageHandleNonResidentARB\n#define glMakeImageHandleResidentARB                        gl3wMakeImageHandleResidentARB\n#define glMakeTextureHandleNonResidentARB                   gl3wMakeTextureHandleNonResidentARB\n#define glMakeTextureHandleResidentARB                      gl3wMakeTextureHandleResidentARB\n#define glMapBuffer                                         gl3wMapBuffer\n#define glMapBufferRange                                    gl3wMapBufferRange\n#define glMapNamedBuffer                                    gl3wMapNamedBuffer\n#define glMapNamedBufferRange                               gl3wMapNamedBufferRange\n#define glMemoryBarrier                                     gl3wMemoryBarrier\n#define glMemoryBarrierByRegion                             gl3wMemoryBarrierByRegion\n#define glMinSampleShading                                  gl3wMinSampleShading\n#define glMinSampleShadingARB                               gl3wMinSampleShadingARB\n#define glMultiDrawArrays                                   gl3wMultiDrawArrays\n#define glMultiDrawArraysIndirect                           gl3wMultiDrawArraysIndirect\n#define glMultiDrawArraysIndirectCountARB                   gl3wMultiDrawArraysIndirectCountARB\n#define glMultiDrawElements                                 gl3wMultiDrawElements\n#define glMultiDrawElementsBaseVertex                       gl3wMultiDrawElementsBaseVertex\n#define glMultiDrawElementsIndirect                         gl3wMultiDrawElementsIndirect\n#define glMultiDrawElementsIndirectCountARB                 gl3wMultiDrawElementsIndirectCountARB\n#define glNamedBufferData                                   gl3wNamedBufferData\n#define glNamedBufferPageCommitmentARB                      gl3wNamedBufferPageCommitmentARB\n#define glNamedBufferPageCommitmentEXT                      gl3wNamedBufferPageCommitmentEXT\n#define glNamedBufferStorage                                gl3wNamedBufferStorage\n#define glNamedBufferSubData                                gl3wNamedBufferSubData\n#define glNamedFramebufferDrawBuffer                        gl3wNamedFramebufferDrawBuffer\n#define glNamedFramebufferDrawBuffers                       gl3wNamedFramebufferDrawBuffers\n#define glNamedFramebufferParameteri                        gl3wNamedFramebufferParameteri\n#define glNamedFramebufferReadBuffer                        gl3wNamedFramebufferReadBuffer\n#define glNamedFramebufferRenderbuffer                      gl3wNamedFramebufferRenderbuffer\n#define glNamedFramebufferTexture                           gl3wNamedFramebufferTexture\n#define glNamedFramebufferTextureLayer                      gl3wNamedFramebufferTextureLayer\n#define glNamedRenderbufferStorage                          gl3wNamedRenderbufferStorage\n#define glNamedRenderbufferStorageMultisample               gl3wNamedRenderbufferStorageMultisample\n#define glNamedStringARB                                    gl3wNamedStringARB\n#define glObjectLabel                                       gl3wObjectLabel\n#define glObjectPtrLabel                                    gl3wObjectPtrLabel\n#define glPatchParameterfv                                  gl3wPatchParameterfv\n#define glPatchParameteri                                   gl3wPatchParameteri\n#define glPauseTransformFeedback                            gl3wPauseTransformFeedback\n#define glPixelStoref                                       gl3wPixelStoref\n#define glPixelStorei                                       gl3wPixelStorei\n#define glPointParameterf                                   gl3wPointParameterf\n#define glPointParameterfv                                  gl3wPointParameterfv\n#define glPointParameteri                                   gl3wPointParameteri\n#define glPointParameteriv                                  gl3wPointParameteriv\n#define glPointSize                                         gl3wPointSize\n#define glPolygonMode                                       gl3wPolygonMode\n#define glPolygonOffset                                     gl3wPolygonOffset\n#define glPopDebugGroup                                     gl3wPopDebugGroup\n#define glPrimitiveRestartIndex                             gl3wPrimitiveRestartIndex\n#define glProgramBinary                                     gl3wProgramBinary\n#define glProgramParameteri                                 gl3wProgramParameteri\n#define glProgramUniform1d                                  gl3wProgramUniform1d\n#define glProgramUniform1dv                                 gl3wProgramUniform1dv\n#define glProgramUniform1f                                  gl3wProgramUniform1f\n#define glProgramUniform1fv                                 gl3wProgramUniform1fv\n#define glProgramUniform1i                                  gl3wProgramUniform1i\n#define glProgramUniform1iv                                 gl3wProgramUniform1iv\n#define glProgramUniform1ui                                 gl3wProgramUniform1ui\n#define glProgramUniform1uiv                                gl3wProgramUniform1uiv\n#define glProgramUniform2d                                  gl3wProgramUniform2d\n#define glProgramUniform2dv                                 gl3wProgramUniform2dv\n#define glProgramUniform2f                                  gl3wProgramUniform2f\n#define glProgramUniform2fv                                 gl3wProgramUniform2fv\n#define glProgramUniform2i                                  gl3wProgramUniform2i\n#define glProgramUniform2iv                                 gl3wProgramUniform2iv\n#define glProgramUniform2ui                                 gl3wProgramUniform2ui\n#define glProgramUniform2uiv                                gl3wProgramUniform2uiv\n#define glProgramUniform3d                                  gl3wProgramUniform3d\n#define glProgramUniform3dv                                 gl3wProgramUniform3dv\n#define glProgramUniform3f                                  gl3wProgramUniform3f\n#define glProgramUniform3fv                                 gl3wProgramUniform3fv\n#define glProgramUniform3i                                  gl3wProgramUniform3i\n#define glProgramUniform3iv                                 gl3wProgramUniform3iv\n#define glProgramUniform3ui                                 gl3wProgramUniform3ui\n#define glProgramUniform3uiv                                gl3wProgramUniform3uiv\n#define glProgramUniform4d                                  gl3wProgramUniform4d\n#define glProgramUniform4dv                                 gl3wProgramUniform4dv\n#define glProgramUniform4f                                  gl3wProgramUniform4f\n#define glProgramUniform4fv                                 gl3wProgramUniform4fv\n#define glProgramUniform4i                                  gl3wProgramUniform4i\n#define glProgramUniform4iv                                 gl3wProgramUniform4iv\n#define glProgramUniform4ui                                 gl3wProgramUniform4ui\n#define glProgramUniform4uiv                                gl3wProgramUniform4uiv\n#define glProgramUniformHandleui64ARB                       gl3wProgramUniformHandleui64ARB\n#define glProgramUniformHandleui64vARB                      gl3wProgramUniformHandleui64vARB\n#define glProgramUniformMatrix2dv                           gl3wProgramUniformMatrix2dv\n#define glProgramUniformMatrix2fv                           gl3wProgramUniformMatrix2fv\n#define glProgramUniformMatrix2x3dv                         gl3wProgramUniformMatrix2x3dv\n#define glProgramUniformMatrix2x3fv                         gl3wProgramUniformMatrix2x3fv\n#define glProgramUniformMatrix2x4dv                         gl3wProgramUniformMatrix2x4dv\n#define glProgramUniformMatrix2x4fv                         gl3wProgramUniformMatrix2x4fv\n#define glProgramUniformMatrix3dv                           gl3wProgramUniformMatrix3dv\n#define glProgramUniformMatrix3fv                           gl3wProgramUniformMatrix3fv\n#define glProgramUniformMatrix3x2dv                         gl3wProgramUniformMatrix3x2dv\n#define glProgramUniformMatrix3x2fv                         gl3wProgramUniformMatrix3x2fv\n#define glProgramUniformMatrix3x4dv                         gl3wProgramUniformMatrix3x4dv\n#define glProgramUniformMatrix3x4fv                         gl3wProgramUniformMatrix3x4fv\n#define glProgramUniformMatrix4dv                           gl3wProgramUniformMatrix4dv\n#define glProgramUniformMatrix4fv                           gl3wProgramUniformMatrix4fv\n#define glProgramUniformMatrix4x2dv                         gl3wProgramUniformMatrix4x2dv\n#define glProgramUniformMatrix4x2fv                         gl3wProgramUniformMatrix4x2fv\n#define glProgramUniformMatrix4x3dv                         gl3wProgramUniformMatrix4x3dv\n#define glProgramUniformMatrix4x3fv                         gl3wProgramUniformMatrix4x3fv\n#define glProvokingVertex                                   gl3wProvokingVertex\n#define glPushDebugGroup                                    gl3wPushDebugGroup\n#define glQueryCounter                                      gl3wQueryCounter\n#define glReadBuffer                                        gl3wReadBuffer\n#define glReadPixels                                        gl3wReadPixels\n#define glReadnPixels                                       gl3wReadnPixels\n#define glReadnPixelsARB                                    gl3wReadnPixelsARB\n#define glReleaseShaderCompiler                             gl3wReleaseShaderCompiler\n#define glRenderbufferStorage                               gl3wRenderbufferStorage\n#define glRenderbufferStorageMultisample                    gl3wRenderbufferStorageMultisample\n#define glResumeTransformFeedback                           gl3wResumeTransformFeedback\n#define glSampleCoverage                                    gl3wSampleCoverage\n#define glSampleMaski                                       gl3wSampleMaski\n#define glSamplerParameterIiv                               gl3wSamplerParameterIiv\n#define glSamplerParameterIuiv                              gl3wSamplerParameterIuiv\n#define glSamplerParameterf                                 gl3wSamplerParameterf\n#define glSamplerParameterfv                                gl3wSamplerParameterfv\n#define glSamplerParameteri                                 gl3wSamplerParameteri\n#define glSamplerParameteriv                                gl3wSamplerParameteriv\n#define glScissor                                           gl3wScissor\n#define glScissorArrayv                                     gl3wScissorArrayv\n#define glScissorIndexed                                    gl3wScissorIndexed\n#define glScissorIndexedv                                   gl3wScissorIndexedv\n#define glShaderBinary                                      gl3wShaderBinary\n#define glShaderSource                                      gl3wShaderSource\n#define glShaderStorageBlockBinding                         gl3wShaderStorageBlockBinding\n#define glStencilFunc                                       gl3wStencilFunc\n#define glStencilFuncSeparate                               gl3wStencilFuncSeparate\n#define glStencilMask                                       gl3wStencilMask\n#define glStencilMaskSeparate                               gl3wStencilMaskSeparate\n#define glStencilOp                                         gl3wStencilOp\n#define glStencilOpSeparate                                 gl3wStencilOpSeparate\n#define glTexBuffer                                         gl3wTexBuffer\n#define glTexBufferRange                                    gl3wTexBufferRange\n#define glTexImage1D                                        gl3wTexImage1D\n#define glTexImage2D                                        gl3wTexImage2D\n#define glTexImage2DMultisample                             gl3wTexImage2DMultisample\n#define glTexImage3D                                        gl3wTexImage3D\n#define glTexImage3DMultisample                             gl3wTexImage3DMultisample\n#define glTexPageCommitmentARB                              gl3wTexPageCommitmentARB\n#define glTexParameterIiv                                   gl3wTexParameterIiv\n#define glTexParameterIuiv                                  gl3wTexParameterIuiv\n#define glTexParameterf                                     gl3wTexParameterf\n#define glTexParameterfv                                    gl3wTexParameterfv\n#define glTexParameteri                                     gl3wTexParameteri\n#define glTexParameteriv                                    gl3wTexParameteriv\n#define glTexStorage1D                                      gl3wTexStorage1D\n#define glTexStorage2D                                      gl3wTexStorage2D\n#define glTexStorage2DMultisample                           gl3wTexStorage2DMultisample\n#define glTexStorage3D                                      gl3wTexStorage3D\n#define glTexStorage3DMultisample                           gl3wTexStorage3DMultisample\n#define glTexSubImage1D                                     gl3wTexSubImage1D\n#define glTexSubImage2D                                     gl3wTexSubImage2D\n#define glTexSubImage3D                                     gl3wTexSubImage3D\n#define glTextureBarrier                                    gl3wTextureBarrier\n#define glTextureBuffer                                     gl3wTextureBuffer\n#define glTextureBufferRange                                gl3wTextureBufferRange\n#define glTextureParameterIiv                               gl3wTextureParameterIiv\n#define glTextureParameterIuiv                              gl3wTextureParameterIuiv\n#define glTextureParameterf                                 gl3wTextureParameterf\n#define glTextureParameterfv                                gl3wTextureParameterfv\n#define glTextureParameteri                                 gl3wTextureParameteri\n#define glTextureParameteriv                                gl3wTextureParameteriv\n#define glTextureStorage1D                                  gl3wTextureStorage1D\n#define glTextureStorage2D                                  gl3wTextureStorage2D\n#define glTextureStorage2DMultisample                       gl3wTextureStorage2DMultisample\n#define glTextureStorage3D                                  gl3wTextureStorage3D\n#define glTextureStorage3DMultisample                       gl3wTextureStorage3DMultisample\n#define glTextureSubImage1D                                 gl3wTextureSubImage1D\n#define glTextureSubImage2D                                 gl3wTextureSubImage2D\n#define glTextureSubImage3D                                 gl3wTextureSubImage3D\n#define glTextureView                                       gl3wTextureView\n#define glTransformFeedbackBufferBase                       gl3wTransformFeedbackBufferBase\n#define glTransformFeedbackBufferRange                      gl3wTransformFeedbackBufferRange\n#define glTransformFeedbackVaryings                         gl3wTransformFeedbackVaryings\n#define glUniform1d                                         gl3wUniform1d\n#define glUniform1dv                                        gl3wUniform1dv\n#define glUniform1f                                         gl3wUniform1f\n#define glUniform1fv                                        gl3wUniform1fv\n#define glUniform1i                                         gl3wUniform1i\n#define glUniform1iv                                        gl3wUniform1iv\n#define glUniform1ui                                        gl3wUniform1ui\n#define glUniform1uiv                                       gl3wUniform1uiv\n#define glUniform2d                                         gl3wUniform2d\n#define glUniform2dv                                        gl3wUniform2dv\n#define glUniform2f                                         gl3wUniform2f\n#define glUniform2fv                                        gl3wUniform2fv\n#define glUniform2i                                         gl3wUniform2i\n#define glUniform2iv                                        gl3wUniform2iv\n#define glUniform2ui                                        gl3wUniform2ui\n#define glUniform2uiv                                       gl3wUniform2uiv\n#define glUniform3d                                         gl3wUniform3d\n#define glUniform3dv                                        gl3wUniform3dv\n#define glUniform3f                                         gl3wUniform3f\n#define glUniform3fv                                        gl3wUniform3fv\n#define glUniform3i                                         gl3wUniform3i\n#define glUniform3iv                                        gl3wUniform3iv\n#define glUniform3ui                                        gl3wUniform3ui\n#define glUniform3uiv                                       gl3wUniform3uiv\n#define glUniform4d                                         gl3wUniform4d\n#define glUniform4dv                                        gl3wUniform4dv\n#define glUniform4f                                         gl3wUniform4f\n#define glUniform4fv                                        gl3wUniform4fv\n#define glUniform4i                                         gl3wUniform4i\n#define glUniform4iv                                        gl3wUniform4iv\n#define glUniform4ui                                        gl3wUniform4ui\n#define glUniform4uiv                                       gl3wUniform4uiv\n#define glUniformBlockBinding                               gl3wUniformBlockBinding\n#define glUniformHandleui64ARB                              gl3wUniformHandleui64ARB\n#define glUniformHandleui64vARB                             gl3wUniformHandleui64vARB\n#define glUniformMatrix2dv                                  gl3wUniformMatrix2dv\n#define glUniformMatrix2fv                                  gl3wUniformMatrix2fv\n#define glUniformMatrix2x3dv                                gl3wUniformMatrix2x3dv\n#define glUniformMatrix2x3fv                                gl3wUniformMatrix2x3fv\n#define glUniformMatrix2x4dv                                gl3wUniformMatrix2x4dv\n#define glUniformMatrix2x4fv                                gl3wUniformMatrix2x4fv\n#define glUniformMatrix3dv                                  gl3wUniformMatrix3dv\n#define glUniformMatrix3fv                                  gl3wUniformMatrix3fv\n#define glUniformMatrix3x2dv                                gl3wUniformMatrix3x2dv\n#define glUniformMatrix3x2fv                                gl3wUniformMatrix3x2fv\n#define glUniformMatrix3x4dv                                gl3wUniformMatrix3x4dv\n#define glUniformMatrix3x4fv                                gl3wUniformMatrix3x4fv\n#define glUniformMatrix4dv                                  gl3wUniformMatrix4dv\n#define glUniformMatrix4fv                                  gl3wUniformMatrix4fv\n#define glUniformMatrix4x2dv                                gl3wUniformMatrix4x2dv\n#define glUniformMatrix4x2fv                                gl3wUniformMatrix4x2fv\n#define glUniformMatrix4x3dv                                gl3wUniformMatrix4x3dv\n#define glUniformMatrix4x3fv                                gl3wUniformMatrix4x3fv\n#define glUniformSubroutinesuiv                             gl3wUniformSubroutinesuiv\n#define glUnmapBuffer                                       gl3wUnmapBuffer\n#define glUnmapNamedBuffer                                  gl3wUnmapNamedBuffer\n#define glUseProgram                                        gl3wUseProgram\n#define glUseProgramStages                                  gl3wUseProgramStages\n#define glValidateProgram                                   gl3wValidateProgram\n#define glValidateProgramPipeline                           gl3wValidateProgramPipeline\n#define glVertexArrayAttribBinding                          gl3wVertexArrayAttribBinding\n#define glVertexArrayAttribFormat                           gl3wVertexArrayAttribFormat\n#define glVertexArrayAttribIFormat                          gl3wVertexArrayAttribIFormat\n#define glVertexArrayAttribLFormat                          gl3wVertexArrayAttribLFormat\n#define glVertexArrayBindingDivisor                         gl3wVertexArrayBindingDivisor\n#define glVertexArrayElementBuffer                          gl3wVertexArrayElementBuffer\n#define glVertexArrayVertexBuffer                           gl3wVertexArrayVertexBuffer\n#define glVertexArrayVertexBuffers                          gl3wVertexArrayVertexBuffers\n#define glVertexAttrib1d                                    gl3wVertexAttrib1d\n#define glVertexAttrib1dv                                   gl3wVertexAttrib1dv\n#define glVertexAttrib1f                                    gl3wVertexAttrib1f\n#define glVertexAttrib1fv                                   gl3wVertexAttrib1fv\n#define glVertexAttrib1s                                    gl3wVertexAttrib1s\n#define glVertexAttrib1sv                                   gl3wVertexAttrib1sv\n#define glVertexAttrib2d                                    gl3wVertexAttrib2d\n#define glVertexAttrib2dv                                   gl3wVertexAttrib2dv\n#define glVertexAttrib2f                                    gl3wVertexAttrib2f\n#define glVertexAttrib2fv                                   gl3wVertexAttrib2fv\n#define glVertexAttrib2s                                    gl3wVertexAttrib2s\n#define glVertexAttrib2sv                                   gl3wVertexAttrib2sv\n#define glVertexAttrib3d                                    gl3wVertexAttrib3d\n#define glVertexAttrib3dv                                   gl3wVertexAttrib3dv\n#define glVertexAttrib3f                                    gl3wVertexAttrib3f\n#define glVertexAttrib3fv                                   gl3wVertexAttrib3fv\n#define glVertexAttrib3s                                    gl3wVertexAttrib3s\n#define glVertexAttrib3sv                                   gl3wVertexAttrib3sv\n#define glVertexAttrib4Nbv                                  gl3wVertexAttrib4Nbv\n#define glVertexAttrib4Niv                                  gl3wVertexAttrib4Niv\n#define glVertexAttrib4Nsv                                  gl3wVertexAttrib4Nsv\n#define glVertexAttrib4Nub                                  gl3wVertexAttrib4Nub\n#define glVertexAttrib4Nubv                                 gl3wVertexAttrib4Nubv\n#define glVertexAttrib4Nuiv                                 gl3wVertexAttrib4Nuiv\n#define glVertexAttrib4Nusv                                 gl3wVertexAttrib4Nusv\n#define glVertexAttrib4bv                                   gl3wVertexAttrib4bv\n#define glVertexAttrib4d                                    gl3wVertexAttrib4d\n#define glVertexAttrib4dv                                   gl3wVertexAttrib4dv\n#define glVertexAttrib4f                                    gl3wVertexAttrib4f\n#define glVertexAttrib4fv                                   gl3wVertexAttrib4fv\n#define glVertexAttrib4iv                                   gl3wVertexAttrib4iv\n#define glVertexAttrib4s                                    gl3wVertexAttrib4s\n#define glVertexAttrib4sv                                   gl3wVertexAttrib4sv\n#define glVertexAttrib4ubv                                  gl3wVertexAttrib4ubv\n#define glVertexAttrib4uiv                                  gl3wVertexAttrib4uiv\n#define glVertexAttrib4usv                                  gl3wVertexAttrib4usv\n#define glVertexAttribBinding                               gl3wVertexAttribBinding\n#define glVertexAttribDivisor                               gl3wVertexAttribDivisor\n#define glVertexAttribFormat                                gl3wVertexAttribFormat\n#define glVertexAttribI1i                                   gl3wVertexAttribI1i\n#define glVertexAttribI1iv                                  gl3wVertexAttribI1iv\n#define glVertexAttribI1ui                                  gl3wVertexAttribI1ui\n#define glVertexAttribI1uiv                                 gl3wVertexAttribI1uiv\n#define glVertexAttribI2i                                   gl3wVertexAttribI2i\n#define glVertexAttribI2iv                                  gl3wVertexAttribI2iv\n#define glVertexAttribI2ui                                  gl3wVertexAttribI2ui\n#define glVertexAttribI2uiv                                 gl3wVertexAttribI2uiv\n#define glVertexAttribI3i                                   gl3wVertexAttribI3i\n#define glVertexAttribI3iv                                  gl3wVertexAttribI3iv\n#define glVertexAttribI3ui                                  gl3wVertexAttribI3ui\n#define glVertexAttribI3uiv                                 gl3wVertexAttribI3uiv\n#define glVertexAttribI4bv                                  gl3wVertexAttribI4bv\n#define glVertexAttribI4i                                   gl3wVertexAttribI4i\n#define glVertexAttribI4iv                                  gl3wVertexAttribI4iv\n#define glVertexAttribI4sv                                  gl3wVertexAttribI4sv\n#define glVertexAttribI4ubv                                 gl3wVertexAttribI4ubv\n#define glVertexAttribI4ui                                  gl3wVertexAttribI4ui\n#define glVertexAttribI4uiv                                 gl3wVertexAttribI4uiv\n#define glVertexAttribI4usv                                 gl3wVertexAttribI4usv\n#define glVertexAttribIFormat                               gl3wVertexAttribIFormat\n#define glVertexAttribIPointer                              gl3wVertexAttribIPointer\n#define glVertexAttribL1d                                   gl3wVertexAttribL1d\n#define glVertexAttribL1dv                                  gl3wVertexAttribL1dv\n#define glVertexAttribL1ui64ARB                             gl3wVertexAttribL1ui64ARB\n#define glVertexAttribL1ui64vARB                            gl3wVertexAttribL1ui64vARB\n#define glVertexAttribL2d                                   gl3wVertexAttribL2d\n#define glVertexAttribL2dv                                  gl3wVertexAttribL2dv\n#define glVertexAttribL3d                                   gl3wVertexAttribL3d\n#define glVertexAttribL3dv                                  gl3wVertexAttribL3dv\n#define glVertexAttribL4d                                   gl3wVertexAttribL4d\n#define glVertexAttribL4dv                                  gl3wVertexAttribL4dv\n#define glVertexAttribLFormat                               gl3wVertexAttribLFormat\n#define glVertexAttribLPointer                              gl3wVertexAttribLPointer\n#define glVertexAttribP1ui                                  gl3wVertexAttribP1ui\n#define glVertexAttribP1uiv                                 gl3wVertexAttribP1uiv\n#define glVertexAttribP2ui                                  gl3wVertexAttribP2ui\n#define glVertexAttribP2uiv                                 gl3wVertexAttribP2uiv\n#define glVertexAttribP3ui                                  gl3wVertexAttribP3ui\n#define glVertexAttribP3uiv                                 gl3wVertexAttribP3uiv\n#define glVertexAttribP4ui                                  gl3wVertexAttribP4ui\n#define glVertexAttribP4uiv                                 gl3wVertexAttribP4uiv\n#define glVertexAttribPointer                               gl3wVertexAttribPointer\n#define glVertexBindingDivisor                              gl3wVertexBindingDivisor\n#define glViewport                                          gl3wViewport\n#define glViewportArrayv                                    gl3wViewportArrayv\n#define glViewportIndexedf                                  gl3wViewportIndexedf\n#define glViewportIndexedfv                                 gl3wViewportIndexedfv\n#define glWaitSync                                          gl3wWaitSync\n\n#endif // __gl3w_h_\n"
  },
  {
    "path": "samples/gl3w/include/GL/glcorearb.h",
    "content": "#ifndef __glcorearb_h_\n#define __glcorearb_h_ 1\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n** Copyright (c) 2013-2015 The Khronos Group Inc.\n**\n** Permission is hereby granted, free of charge, to any person obtaining a\n** copy of this software and/or associated documentation files (the\n** \"Materials\"), to deal in the Materials without restriction, including\n** without limitation the rights to use, copy, modify, merge, publish,\n** distribute, sublicense, and/or sell copies of the Materials, and to\n** permit persons to whom the Materials are furnished to do so, subject to\n** the following conditions:\n**\n** The above copyright notice and this permission notice shall be included\n** in all copies or substantial portions of the Materials.\n**\n** THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.\n*/\n/*\n** This header is generated from the Khronos OpenGL / OpenGL ES XML\n** API Registry. The current version of the Registry, generator scripts\n** used to make the header, and the header can be found at\n**   http://www.opengl.org/registry/\n**\n** Khronos $Revision: 31597 $ on $Date: 2015-06-25 16:32:35 -0400 (Thu, 25 Jun 2015) $\n*/\n\n#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN 1\n#endif\n#include <windows.h>\n#endif\n\n#ifndef APIENTRY\n#define APIENTRY\n#endif\n#ifndef APIENTRYP\n#define APIENTRYP APIENTRY *\n#endif\n#ifndef GLAPI\n#define GLAPI extern\n#endif\n\n/* glcorearb.h is for use with OpenGL core profile implementations.\n** It should should be placed in the same directory as gl.h and\n** included as <GL/glcorearb.h>.\n**\n** glcorearb.h includes only APIs in the latest OpenGL core profile\n** implementation together with APIs in newer ARB extensions which \n** can be supported by the core profile. It does not, and never will\n** include functionality removed from the core profile, such as\n** fixed-function vertex and fragment processing.\n**\n** Do not #include both <GL/glcorearb.h> and either of <GL/gl.h> or\n** <GL/glext.h> in the same source file.\n*/\n\n/* Generated C header for:\n * API: gl\n * Profile: core\n * Versions considered: .*\n * Versions emitted: .*\n * Default extensions included: glcore\n * Additional extensions included: _nomatch_^\n * Extensions removed: _nomatch_^\n */\n\n#ifndef GL_VERSION_1_0\n#define GL_VERSION_1_0 1\ntypedef void GLvoid;\ntypedef unsigned int GLenum;\ntypedef float GLfloat;\ntypedef int GLint;\ntypedef int GLsizei;\ntypedef unsigned int GLbitfield;\ntypedef double GLdouble;\ntypedef unsigned int GLuint;\ntypedef unsigned char GLboolean;\ntypedef unsigned char GLubyte;\ntypedef void (APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);\ntypedef void (APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);\ntypedef void (APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size);\ntypedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);\ntypedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf);\ntypedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);\ntypedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\ntypedef void (APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);\ntypedef void (APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble depth);\ntypedef void (APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);\ntypedef void (APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);\ntypedef void (APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);\ntypedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);\ntypedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);\ntypedef void (APIENTRYP PFNGLFINISHPROC) (void);\ntypedef void (APIENTRYP PFNGLFLUSHPROC) (void);\ntypedef void (APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);\ntypedef void (APIENTRYP PFNGLLOGICOPPROC) (GLenum opcode);\ntypedef void (APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);\ntypedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);\ntypedef void (APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);\ntypedef void (APIENTRYP PFNGLPIXELSTOREFPROC) (GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLREADBUFFERPROC) (GLenum src);\ntypedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);\ntypedef void (APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);\ntypedef void (APIENTRYP PFNGLGETDOUBLEVPROC) (GLenum pname, GLdouble *data);\ntypedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);\ntypedef void (APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);\ntypedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);\ntypedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);\ntypedef void (APIENTRYP PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params);\ntypedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEPROC) (GLdouble near, GLdouble far);\ntypedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glCullFace (GLenum mode);\nGLAPI void APIENTRY glFrontFace (GLenum mode);\nGLAPI void APIENTRY glHint (GLenum target, GLenum mode);\nGLAPI void APIENTRY glLineWidth (GLfloat width);\nGLAPI void APIENTRY glPointSize (GLfloat size);\nGLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);\nGLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glDrawBuffer (GLenum buf);\nGLAPI void APIENTRY glClear (GLbitfield mask);\nGLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\nGLAPI void APIENTRY glClearStencil (GLint s);\nGLAPI void APIENTRY glClearDepth (GLdouble depth);\nGLAPI void APIENTRY glStencilMask (GLuint mask);\nGLAPI void APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);\nGLAPI void APIENTRY glDepthMask (GLboolean flag);\nGLAPI void APIENTRY glDisable (GLenum cap);\nGLAPI void APIENTRY glEnable (GLenum cap);\nGLAPI void APIENTRY glFinish (void);\nGLAPI void APIENTRY glFlush (void);\nGLAPI void APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);\nGLAPI void APIENTRY glLogicOp (GLenum opcode);\nGLAPI void APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);\nGLAPI void APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);\nGLAPI void APIENTRY glDepthFunc (GLenum func);\nGLAPI void APIENTRY glPixelStoref (GLenum pname, GLfloat param);\nGLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param);\nGLAPI void APIENTRY glReadBuffer (GLenum src);\nGLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);\nGLAPI void APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);\nGLAPI void APIENTRY glGetDoublev (GLenum pname, GLdouble *data);\nGLAPI GLenum APIENTRY glGetError (void);\nGLAPI void APIENTRY glGetFloatv (GLenum pname, GLfloat *data);\nGLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data);\nGLAPI const GLubyte *APIENTRY glGetString (GLenum name);\nGLAPI void APIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\nGLAPI void APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);\nGLAPI GLboolean APIENTRY glIsEnabled (GLenum cap);\nGLAPI void APIENTRY glDepthRange (GLdouble near, GLdouble far);\nGLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);\n#endif\n#endif /* GL_VERSION_1_0 */\n\n#ifndef GL_VERSION_1_1\n#define GL_VERSION_1_1 1\ntypedef float GLclampf;\ntypedef double GLclampd;\n#define GL_DEPTH_BUFFER_BIT               0x00000100\n#define GL_STENCIL_BUFFER_BIT             0x00000400\n#define GL_COLOR_BUFFER_BIT               0x00004000\n#define GL_FALSE                          0\n#define GL_TRUE                           1\n#define GL_POINTS                         0x0000\n#define GL_LINES                          0x0001\n#define GL_LINE_LOOP                      0x0002\n#define GL_LINE_STRIP                     0x0003\n#define GL_TRIANGLES                      0x0004\n#define GL_TRIANGLE_STRIP                 0x0005\n#define GL_TRIANGLE_FAN                   0x0006\n#define GL_QUADS                          0x0007\n#define GL_NEVER                          0x0200\n#define GL_LESS                           0x0201\n#define GL_EQUAL                          0x0202\n#define GL_LEQUAL                         0x0203\n#define GL_GREATER                        0x0204\n#define GL_NOTEQUAL                       0x0205\n#define GL_GEQUAL                         0x0206\n#define GL_ALWAYS                         0x0207\n#define GL_ZERO                           0\n#define GL_ONE                            1\n#define GL_SRC_COLOR                      0x0300\n#define GL_ONE_MINUS_SRC_COLOR            0x0301\n#define GL_SRC_ALPHA                      0x0302\n#define GL_ONE_MINUS_SRC_ALPHA            0x0303\n#define GL_DST_ALPHA                      0x0304\n#define GL_ONE_MINUS_DST_ALPHA            0x0305\n#define GL_DST_COLOR                      0x0306\n#define GL_ONE_MINUS_DST_COLOR            0x0307\n#define GL_SRC_ALPHA_SATURATE             0x0308\n#define GL_NONE                           0\n#define GL_FRONT_LEFT                     0x0400\n#define GL_FRONT_RIGHT                    0x0401\n#define GL_BACK_LEFT                      0x0402\n#define GL_BACK_RIGHT                     0x0403\n#define GL_FRONT                          0x0404\n#define GL_BACK                           0x0405\n#define GL_LEFT                           0x0406\n#define GL_RIGHT                          0x0407\n#define GL_FRONT_AND_BACK                 0x0408\n#define GL_NO_ERROR                       0\n#define GL_INVALID_ENUM                   0x0500\n#define GL_INVALID_VALUE                  0x0501\n#define GL_INVALID_OPERATION              0x0502\n#define GL_OUT_OF_MEMORY                  0x0505\n#define GL_CW                             0x0900\n#define GL_CCW                            0x0901\n#define GL_POINT_SIZE                     0x0B11\n#define GL_POINT_SIZE_RANGE               0x0B12\n#define GL_POINT_SIZE_GRANULARITY         0x0B13\n#define GL_LINE_SMOOTH                    0x0B20\n#define GL_LINE_WIDTH                     0x0B21\n#define GL_LINE_WIDTH_RANGE               0x0B22\n#define GL_LINE_WIDTH_GRANULARITY         0x0B23\n#define GL_POLYGON_MODE                   0x0B40\n#define GL_POLYGON_SMOOTH                 0x0B41\n#define GL_CULL_FACE                      0x0B44\n#define GL_CULL_FACE_MODE                 0x0B45\n#define GL_FRONT_FACE                     0x0B46\n#define GL_DEPTH_RANGE                    0x0B70\n#define GL_DEPTH_TEST                     0x0B71\n#define GL_DEPTH_WRITEMASK                0x0B72\n#define GL_DEPTH_CLEAR_VALUE              0x0B73\n#define GL_DEPTH_FUNC                     0x0B74\n#define GL_STENCIL_TEST                   0x0B90\n#define GL_STENCIL_CLEAR_VALUE            0x0B91\n#define GL_STENCIL_FUNC                   0x0B92\n#define GL_STENCIL_VALUE_MASK             0x0B93\n#define GL_STENCIL_FAIL                   0x0B94\n#define GL_STENCIL_PASS_DEPTH_FAIL        0x0B95\n#define GL_STENCIL_PASS_DEPTH_PASS        0x0B96\n#define GL_STENCIL_REF                    0x0B97\n#define GL_STENCIL_WRITEMASK              0x0B98\n#define GL_VIEWPORT                       0x0BA2\n#define GL_DITHER                         0x0BD0\n#define GL_BLEND_DST                      0x0BE0\n#define GL_BLEND_SRC                      0x0BE1\n#define GL_BLEND                          0x0BE2\n#define GL_LOGIC_OP_MODE                  0x0BF0\n#define GL_COLOR_LOGIC_OP                 0x0BF2\n#define GL_DRAW_BUFFER                    0x0C01\n#define GL_READ_BUFFER                    0x0C02\n#define GL_SCISSOR_BOX                    0x0C10\n#define GL_SCISSOR_TEST                   0x0C11\n#define GL_COLOR_CLEAR_VALUE              0x0C22\n#define GL_COLOR_WRITEMASK                0x0C23\n#define GL_DOUBLEBUFFER                   0x0C32\n#define GL_STEREO                         0x0C33\n#define GL_LINE_SMOOTH_HINT               0x0C52\n#define GL_POLYGON_SMOOTH_HINT            0x0C53\n#define GL_UNPACK_SWAP_BYTES              0x0CF0\n#define GL_UNPACK_LSB_FIRST               0x0CF1\n#define GL_UNPACK_ROW_LENGTH              0x0CF2\n#define GL_UNPACK_SKIP_ROWS               0x0CF3\n#define GL_UNPACK_SKIP_PIXELS             0x0CF4\n#define GL_UNPACK_ALIGNMENT               0x0CF5\n#define GL_PACK_SWAP_BYTES                0x0D00\n#define GL_PACK_LSB_FIRST                 0x0D01\n#define GL_PACK_ROW_LENGTH                0x0D02\n#define GL_PACK_SKIP_ROWS                 0x0D03\n#define GL_PACK_SKIP_PIXELS               0x0D04\n#define GL_PACK_ALIGNMENT                 0x0D05\n#define GL_MAX_TEXTURE_SIZE               0x0D33\n#define GL_MAX_VIEWPORT_DIMS              0x0D3A\n#define GL_SUBPIXEL_BITS                  0x0D50\n#define GL_TEXTURE_1D                     0x0DE0\n#define GL_TEXTURE_2D                     0x0DE1\n#define GL_POLYGON_OFFSET_UNITS           0x2A00\n#define GL_POLYGON_OFFSET_POINT           0x2A01\n#define GL_POLYGON_OFFSET_LINE            0x2A02\n#define GL_POLYGON_OFFSET_FILL            0x8037\n#define GL_POLYGON_OFFSET_FACTOR          0x8038\n#define GL_TEXTURE_BINDING_1D             0x8068\n#define GL_TEXTURE_BINDING_2D             0x8069\n#define GL_TEXTURE_WIDTH                  0x1000\n#define GL_TEXTURE_HEIGHT                 0x1001\n#define GL_TEXTURE_INTERNAL_FORMAT        0x1003\n#define GL_TEXTURE_BORDER_COLOR           0x1004\n#define GL_TEXTURE_RED_SIZE               0x805C\n#define GL_TEXTURE_GREEN_SIZE             0x805D\n#define GL_TEXTURE_BLUE_SIZE              0x805E\n#define GL_TEXTURE_ALPHA_SIZE             0x805F\n#define GL_DONT_CARE                      0x1100\n#define GL_FASTEST                        0x1101\n#define GL_NICEST                         0x1102\n#define GL_BYTE                           0x1400\n#define GL_UNSIGNED_BYTE                  0x1401\n#define GL_SHORT                          0x1402\n#define GL_UNSIGNED_SHORT                 0x1403\n#define GL_INT                            0x1404\n#define GL_UNSIGNED_INT                   0x1405\n#define GL_FLOAT                          0x1406\n#define GL_DOUBLE                         0x140A\n#define GL_STACK_OVERFLOW                 0x0503\n#define GL_STACK_UNDERFLOW                0x0504\n#define GL_CLEAR                          0x1500\n#define GL_AND                            0x1501\n#define GL_AND_REVERSE                    0x1502\n#define GL_COPY                           0x1503\n#define GL_AND_INVERTED                   0x1504\n#define GL_NOOP                           0x1505\n#define GL_XOR                            0x1506\n#define GL_OR                             0x1507\n#define GL_NOR                            0x1508\n#define GL_EQUIV                          0x1509\n#define GL_INVERT                         0x150A\n#define GL_OR_REVERSE                     0x150B\n#define GL_COPY_INVERTED                  0x150C\n#define GL_OR_INVERTED                    0x150D\n#define GL_NAND                           0x150E\n#define GL_SET                            0x150F\n#define GL_TEXTURE                        0x1702\n#define GL_COLOR                          0x1800\n#define GL_DEPTH                          0x1801\n#define GL_STENCIL                        0x1802\n#define GL_STENCIL_INDEX                  0x1901\n#define GL_DEPTH_COMPONENT                0x1902\n#define GL_RED                            0x1903\n#define GL_GREEN                          0x1904\n#define GL_BLUE                           0x1905\n#define GL_ALPHA                          0x1906\n#define GL_RGB                            0x1907\n#define GL_RGBA                           0x1908\n#define GL_POINT                          0x1B00\n#define GL_LINE                           0x1B01\n#define GL_FILL                           0x1B02\n#define GL_KEEP                           0x1E00\n#define GL_REPLACE                        0x1E01\n#define GL_INCR                           0x1E02\n#define GL_DECR                           0x1E03\n#define GL_VENDOR                         0x1F00\n#define GL_RENDERER                       0x1F01\n#define GL_VERSION                        0x1F02\n#define GL_EXTENSIONS                     0x1F03\n#define GL_NEAREST                        0x2600\n#define GL_LINEAR                         0x2601\n#define GL_NEAREST_MIPMAP_NEAREST         0x2700\n#define GL_LINEAR_MIPMAP_NEAREST          0x2701\n#define GL_NEAREST_MIPMAP_LINEAR          0x2702\n#define GL_LINEAR_MIPMAP_LINEAR           0x2703\n#define GL_TEXTURE_MAG_FILTER             0x2800\n#define GL_TEXTURE_MIN_FILTER             0x2801\n#define GL_TEXTURE_WRAP_S                 0x2802\n#define GL_TEXTURE_WRAP_T                 0x2803\n#define GL_PROXY_TEXTURE_1D               0x8063\n#define GL_PROXY_TEXTURE_2D               0x8064\n#define GL_REPEAT                         0x2901\n#define GL_R3_G3_B2                       0x2A10\n#define GL_RGB4                           0x804F\n#define GL_RGB5                           0x8050\n#define GL_RGB8                           0x8051\n#define GL_RGB10                          0x8052\n#define GL_RGB12                          0x8053\n#define GL_RGB16                          0x8054\n#define GL_RGBA2                          0x8055\n#define GL_RGBA4                          0x8056\n#define GL_RGB5_A1                        0x8057\n#define GL_RGBA8                          0x8058\n#define GL_RGB10_A2                       0x8059\n#define GL_RGBA12                         0x805A\n#define GL_RGBA16                         0x805B\n#define GL_VERTEX_ARRAY                   0x8074\ntypedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);\ntypedef void (APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params);\ntypedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);\ntypedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\ntypedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);\ntypedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);\ntypedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);\ntypedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);\nGLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);\nGLAPI void APIENTRY glGetPointerv (GLenum pname, void **params);\nGLAPI void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);\nGLAPI void APIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\nGLAPI void APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\nGLAPI void APIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\nGLAPI void APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);\nGLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);\nGLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);\nGLAPI GLboolean APIENTRY glIsTexture (GLuint texture);\n#endif\n#endif /* GL_VERSION_1_1 */\n\n#ifndef GL_VERSION_1_2\n#define GL_VERSION_1_2 1\n#define GL_UNSIGNED_BYTE_3_3_2            0x8032\n#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033\n#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034\n#define GL_UNSIGNED_INT_8_8_8_8           0x8035\n#define GL_UNSIGNED_INT_10_10_10_2        0x8036\n#define GL_TEXTURE_BINDING_3D             0x806A\n#define GL_PACK_SKIP_IMAGES               0x806B\n#define GL_PACK_IMAGE_HEIGHT              0x806C\n#define GL_UNPACK_SKIP_IMAGES             0x806D\n#define GL_UNPACK_IMAGE_HEIGHT            0x806E\n#define GL_TEXTURE_3D                     0x806F\n#define GL_PROXY_TEXTURE_3D               0x8070\n#define GL_TEXTURE_DEPTH                  0x8071\n#define GL_TEXTURE_WRAP_R                 0x8072\n#define GL_MAX_3D_TEXTURE_SIZE            0x8073\n#define GL_UNSIGNED_BYTE_2_3_3_REV        0x8362\n#define GL_UNSIGNED_SHORT_5_6_5           0x8363\n#define GL_UNSIGNED_SHORT_5_6_5_REV       0x8364\n#define GL_UNSIGNED_SHORT_4_4_4_4_REV     0x8365\n#define GL_UNSIGNED_SHORT_1_5_5_5_REV     0x8366\n#define GL_UNSIGNED_INT_8_8_8_8_REV       0x8367\n#define GL_UNSIGNED_INT_2_10_10_10_REV    0x8368\n#define GL_BGR                            0x80E0\n#define GL_BGRA                           0x80E1\n#define GL_MAX_ELEMENTS_VERTICES          0x80E8\n#define GL_MAX_ELEMENTS_INDICES           0x80E9\n#define GL_CLAMP_TO_EDGE                  0x812F\n#define GL_TEXTURE_MIN_LOD                0x813A\n#define GL_TEXTURE_MAX_LOD                0x813B\n#define GL_TEXTURE_BASE_LEVEL             0x813C\n#define GL_TEXTURE_MAX_LEVEL              0x813D\n#define GL_SMOOTH_POINT_SIZE_RANGE        0x0B12\n#define GL_SMOOTH_POINT_SIZE_GRANULARITY  0x0B13\n#define GL_SMOOTH_LINE_WIDTH_RANGE        0x0B22\n#define GL_SMOOTH_LINE_WIDTH_GRANULARITY  0x0B23\n#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E\ntypedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);\ntypedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);\nGLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\n#endif\n#endif /* GL_VERSION_1_2 */\n\n#ifndef GL_VERSION_1_3\n#define GL_VERSION_1_3 1\n#define GL_TEXTURE0                       0x84C0\n#define GL_TEXTURE1                       0x84C1\n#define GL_TEXTURE2                       0x84C2\n#define GL_TEXTURE3                       0x84C3\n#define GL_TEXTURE4                       0x84C4\n#define GL_TEXTURE5                       0x84C5\n#define GL_TEXTURE6                       0x84C6\n#define GL_TEXTURE7                       0x84C7\n#define GL_TEXTURE8                       0x84C8\n#define GL_TEXTURE9                       0x84C9\n#define GL_TEXTURE10                      0x84CA\n#define GL_TEXTURE11                      0x84CB\n#define GL_TEXTURE12                      0x84CC\n#define GL_TEXTURE13                      0x84CD\n#define GL_TEXTURE14                      0x84CE\n#define GL_TEXTURE15                      0x84CF\n#define GL_TEXTURE16                      0x84D0\n#define GL_TEXTURE17                      0x84D1\n#define GL_TEXTURE18                      0x84D2\n#define GL_TEXTURE19                      0x84D3\n#define GL_TEXTURE20                      0x84D4\n#define GL_TEXTURE21                      0x84D5\n#define GL_TEXTURE22                      0x84D6\n#define GL_TEXTURE23                      0x84D7\n#define GL_TEXTURE24                      0x84D8\n#define GL_TEXTURE25                      0x84D9\n#define GL_TEXTURE26                      0x84DA\n#define GL_TEXTURE27                      0x84DB\n#define GL_TEXTURE28                      0x84DC\n#define GL_TEXTURE29                      0x84DD\n#define GL_TEXTURE30                      0x84DE\n#define GL_TEXTURE31                      0x84DF\n#define GL_ACTIVE_TEXTURE                 0x84E0\n#define GL_MULTISAMPLE                    0x809D\n#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E\n#define GL_SAMPLE_ALPHA_TO_ONE            0x809F\n#define GL_SAMPLE_COVERAGE                0x80A0\n#define GL_SAMPLE_BUFFERS                 0x80A8\n#define GL_SAMPLES                        0x80A9\n#define GL_SAMPLE_COVERAGE_VALUE          0x80AA\n#define GL_SAMPLE_COVERAGE_INVERT         0x80AB\n#define GL_TEXTURE_CUBE_MAP               0x8513\n#define GL_TEXTURE_BINDING_CUBE_MAP       0x8514\n#define GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515\n#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516\n#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y    0x8517\n#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    0x8518\n#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z    0x8519\n#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    0x851A\n#define GL_PROXY_TEXTURE_CUBE_MAP         0x851B\n#define GL_MAX_CUBE_MAP_TEXTURE_SIZE      0x851C\n#define GL_COMPRESSED_RGB                 0x84ED\n#define GL_COMPRESSED_RGBA                0x84EE\n#define GL_TEXTURE_COMPRESSION_HINT       0x84EF\n#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE  0x86A0\n#define GL_TEXTURE_COMPRESSED             0x86A1\n#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2\n#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3\n#define GL_CLAMP_TO_BORDER                0x812D\ntypedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);\ntypedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glActiveTexture (GLenum texture);\nGLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);\nGLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img);\n#endif\n#endif /* GL_VERSION_1_3 */\n\n#ifndef GL_VERSION_1_4\n#define GL_VERSION_1_4 1\n#define GL_BLEND_DST_RGB                  0x80C8\n#define GL_BLEND_SRC_RGB                  0x80C9\n#define GL_BLEND_DST_ALPHA                0x80CA\n#define GL_BLEND_SRC_ALPHA                0x80CB\n#define GL_POINT_FADE_THRESHOLD_SIZE      0x8128\n#define GL_DEPTH_COMPONENT16              0x81A5\n#define GL_DEPTH_COMPONENT24              0x81A6\n#define GL_DEPTH_COMPONENT32              0x81A7\n#define GL_MIRRORED_REPEAT                0x8370\n#define GL_MAX_TEXTURE_LOD_BIAS           0x84FD\n#define GL_TEXTURE_LOD_BIAS               0x8501\n#define GL_INCR_WRAP                      0x8507\n#define GL_DECR_WRAP                      0x8508\n#define GL_TEXTURE_DEPTH_SIZE             0x884A\n#define GL_TEXTURE_COMPARE_MODE           0x884C\n#define GL_TEXTURE_COMPARE_FUNC           0x884D\n#define GL_FUNC_ADD                       0x8006\n#define GL_FUNC_SUBTRACT                  0x800A\n#define GL_FUNC_REVERSE_SUBTRACT          0x800B\n#define GL_MIN                            0x8007\n#define GL_MAX                            0x8008\n#define GL_CONSTANT_COLOR                 0x8001\n#define GL_ONE_MINUS_CONSTANT_COLOR       0x8002\n#define GL_CONSTANT_ALPHA                 0x8003\n#define GL_ONE_MINUS_CONSTANT_ALPHA       0x8004\ntypedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);\nGLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);\nGLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);\nGLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);\nGLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);\nGLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);\nGLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\nGLAPI void APIENTRY glBlendEquation (GLenum mode);\n#endif\n#endif /* GL_VERSION_1_4 */\n\n#ifndef GL_VERSION_1_5\n#define GL_VERSION_1_5 1\n#include <stddef.h>\ntypedef ptrdiff_t GLsizeiptr;\ntypedef ptrdiff_t GLintptr;\n#define GL_BUFFER_SIZE                    0x8764\n#define GL_BUFFER_USAGE                   0x8765\n#define GL_QUERY_COUNTER_BITS             0x8864\n#define GL_CURRENT_QUERY                  0x8865\n#define GL_QUERY_RESULT                   0x8866\n#define GL_QUERY_RESULT_AVAILABLE         0x8867\n#define GL_ARRAY_BUFFER                   0x8892\n#define GL_ELEMENT_ARRAY_BUFFER           0x8893\n#define GL_ARRAY_BUFFER_BINDING           0x8894\n#define GL_ELEMENT_ARRAY_BUFFER_BINDING   0x8895\n#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F\n#define GL_READ_ONLY                      0x88B8\n#define GL_WRITE_ONLY                     0x88B9\n#define GL_READ_WRITE                     0x88BA\n#define GL_BUFFER_ACCESS                  0x88BB\n#define GL_BUFFER_MAPPED                  0x88BC\n#define GL_BUFFER_MAP_POINTER             0x88BD\n#define GL_STREAM_DRAW                    0x88E0\n#define GL_STREAM_READ                    0x88E1\n#define GL_STREAM_COPY                    0x88E2\n#define GL_STATIC_DRAW                    0x88E4\n#define GL_STATIC_READ                    0x88E5\n#define GL_STATIC_COPY                    0x88E6\n#define GL_DYNAMIC_DRAW                   0x88E8\n#define GL_DYNAMIC_READ                   0x88E9\n#define GL_DYNAMIC_COPY                   0x88EA\n#define GL_SAMPLES_PASSED                 0x8914\n#define GL_SRC1_ALPHA                     0x8589\ntypedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);\ntypedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);\ntypedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);\ntypedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);\ntypedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);\ntypedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);\ntypedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);\ntypedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);\ntypedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);\ntypedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data);\ntypedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);\ntypedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids);\nGLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);\nGLAPI GLboolean APIENTRY glIsQuery (GLuint id);\nGLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id);\nGLAPI void APIENTRY glEndQuery (GLenum target);\nGLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);\nGLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);\nGLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);\nGLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer);\nGLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);\nGLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);\nGLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data);\nGLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access);\nGLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target);\nGLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params);\n#endif\n#endif /* GL_VERSION_1_5 */\n\n#ifndef GL_VERSION_2_0\n#define GL_VERSION_2_0 1\ntypedef char GLchar;\ntypedef short GLshort;\ntypedef signed char GLbyte;\ntypedef unsigned short GLushort;\n#define GL_BLEND_EQUATION_RGB             0x8009\n#define GL_VERTEX_ATTRIB_ARRAY_ENABLED    0x8622\n#define GL_VERTEX_ATTRIB_ARRAY_SIZE       0x8623\n#define GL_VERTEX_ATTRIB_ARRAY_STRIDE     0x8624\n#define GL_VERTEX_ATTRIB_ARRAY_TYPE       0x8625\n#define GL_CURRENT_VERTEX_ATTRIB          0x8626\n#define GL_VERTEX_PROGRAM_POINT_SIZE      0x8642\n#define GL_VERTEX_ATTRIB_ARRAY_POINTER    0x8645\n#define GL_STENCIL_BACK_FUNC              0x8800\n#define GL_STENCIL_BACK_FAIL              0x8801\n#define GL_STENCIL_BACK_PASS_DEPTH_FAIL   0x8802\n#define GL_STENCIL_BACK_PASS_DEPTH_PASS   0x8803\n#define GL_MAX_DRAW_BUFFERS               0x8824\n#define GL_DRAW_BUFFER0                   0x8825\n#define GL_DRAW_BUFFER1                   0x8826\n#define GL_DRAW_BUFFER2                   0x8827\n#define GL_DRAW_BUFFER3                   0x8828\n#define GL_DRAW_BUFFER4                   0x8829\n#define GL_DRAW_BUFFER5                   0x882A\n#define GL_DRAW_BUFFER6                   0x882B\n#define GL_DRAW_BUFFER7                   0x882C\n#define GL_DRAW_BUFFER8                   0x882D\n#define GL_DRAW_BUFFER9                   0x882E\n#define GL_DRAW_BUFFER10                  0x882F\n#define GL_DRAW_BUFFER11                  0x8830\n#define GL_DRAW_BUFFER12                  0x8831\n#define GL_DRAW_BUFFER13                  0x8832\n#define GL_DRAW_BUFFER14                  0x8833\n#define GL_DRAW_BUFFER15                  0x8834\n#define GL_BLEND_EQUATION_ALPHA           0x883D\n#define GL_MAX_VERTEX_ATTRIBS             0x8869\n#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A\n#define GL_MAX_TEXTURE_IMAGE_UNITS        0x8872\n#define GL_FRAGMENT_SHADER                0x8B30\n#define GL_VERTEX_SHADER                  0x8B31\n#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49\n#define GL_MAX_VERTEX_UNIFORM_COMPONENTS  0x8B4A\n#define GL_MAX_VARYING_FLOATS             0x8B4B\n#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C\n#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D\n#define GL_SHADER_TYPE                    0x8B4F\n#define GL_FLOAT_VEC2                     0x8B50\n#define GL_FLOAT_VEC3                     0x8B51\n#define GL_FLOAT_VEC4                     0x8B52\n#define GL_INT_VEC2                       0x8B53\n#define GL_INT_VEC3                       0x8B54\n#define GL_INT_VEC4                       0x8B55\n#define GL_BOOL                           0x8B56\n#define GL_BOOL_VEC2                      0x8B57\n#define GL_BOOL_VEC3                      0x8B58\n#define GL_BOOL_VEC4                      0x8B59\n#define GL_FLOAT_MAT2                     0x8B5A\n#define GL_FLOAT_MAT3                     0x8B5B\n#define GL_FLOAT_MAT4                     0x8B5C\n#define GL_SAMPLER_1D                     0x8B5D\n#define GL_SAMPLER_2D                     0x8B5E\n#define GL_SAMPLER_3D                     0x8B5F\n#define GL_SAMPLER_CUBE                   0x8B60\n#define GL_SAMPLER_1D_SHADOW              0x8B61\n#define GL_SAMPLER_2D_SHADOW              0x8B62\n#define GL_DELETE_STATUS                  0x8B80\n#define GL_COMPILE_STATUS                 0x8B81\n#define GL_LINK_STATUS                    0x8B82\n#define GL_VALIDATE_STATUS                0x8B83\n#define GL_INFO_LOG_LENGTH                0x8B84\n#define GL_ATTACHED_SHADERS               0x8B85\n#define GL_ACTIVE_UNIFORMS                0x8B86\n#define GL_ACTIVE_UNIFORM_MAX_LENGTH      0x8B87\n#define GL_SHADER_SOURCE_LENGTH           0x8B88\n#define GL_ACTIVE_ATTRIBUTES              0x8B89\n#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH    0x8B8A\n#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B\n#define GL_SHADING_LANGUAGE_VERSION       0x8B8C\n#define GL_CURRENT_PROGRAM                0x8B8D\n#define GL_POINT_SPRITE_COORD_ORIGIN      0x8CA0\n#define GL_LOWER_LEFT                     0x8CA1\n#define GL_UPPER_LEFT                     0x8CA2\n#define GL_STENCIL_BACK_REF               0x8CA3\n#define GL_STENCIL_BACK_VALUE_MASK        0x8CA4\n#define GL_STENCIL_BACK_WRITEMASK         0x8CA5\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);\ntypedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);\ntypedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);\ntypedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);\ntypedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);\ntypedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);\ntypedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);\ntypedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);\ntypedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);\ntypedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);\ntypedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);\ntypedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);\ntypedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);\ntypedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);\ntypedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);\ntypedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\ntypedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\ntypedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);\ntypedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);\ntypedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);\ntypedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);\ntypedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);\ntypedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);\ntypedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);\ntypedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\ntypedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\ntypedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);\ntypedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);\ntypedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);\ntypedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\ntypedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);\nGLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);\nGLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);\nGLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);\nGLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);\nGLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);\nGLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);\nGLAPI void APIENTRY glCompileShader (GLuint shader);\nGLAPI GLuint APIENTRY glCreateProgram (void);\nGLAPI GLuint APIENTRY glCreateShader (GLenum type);\nGLAPI void APIENTRY glDeleteProgram (GLuint program);\nGLAPI void APIENTRY glDeleteShader (GLuint shader);\nGLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);\nGLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);\nGLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);\nGLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\nGLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\nGLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);\nGLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\nGLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\nGLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);\nGLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);\nGLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);\nGLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params);\nGLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);\nGLAPI GLboolean APIENTRY glIsProgram (GLuint program);\nGLAPI GLboolean APIENTRY glIsShader (GLuint shader);\nGLAPI void APIENTRY glLinkProgram (GLuint program);\nGLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);\nGLAPI void APIENTRY glUseProgram (GLuint program);\nGLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);\nGLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);\nGLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\nGLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\nGLAPI void APIENTRY glUniform1i (GLint location, GLint v0);\nGLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);\nGLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);\nGLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\nGLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glValidateProgram (GLuint program);\nGLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x);\nGLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);\nGLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x);\nGLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);\nGLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y);\nGLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);\nGLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z);\nGLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v);\nGLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);\nGLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v);\nGLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v);\nGLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v);\nGLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);\nGLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);\nGLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v);\nGLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v);\nGLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);\n#endif\n#endif /* GL_VERSION_2_0 */\n\n#ifndef GL_VERSION_2_1\n#define GL_VERSION_2_1 1\n#define GL_PIXEL_PACK_BUFFER              0x88EB\n#define GL_PIXEL_UNPACK_BUFFER            0x88EC\n#define GL_PIXEL_PACK_BUFFER_BINDING      0x88ED\n#define GL_PIXEL_UNPACK_BUFFER_BINDING    0x88EF\n#define GL_FLOAT_MAT2x3                   0x8B65\n#define GL_FLOAT_MAT2x4                   0x8B66\n#define GL_FLOAT_MAT3x2                   0x8B67\n#define GL_FLOAT_MAT3x4                   0x8B68\n#define GL_FLOAT_MAT4x2                   0x8B69\n#define GL_FLOAT_MAT4x3                   0x8B6A\n#define GL_SRGB                           0x8C40\n#define GL_SRGB8                          0x8C41\n#define GL_SRGB_ALPHA                     0x8C42\n#define GL_SRGB8_ALPHA8                   0x8C43\n#define GL_COMPRESSED_SRGB                0x8C48\n#define GL_COMPRESSED_SRGB_ALPHA          0x8C49\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\n#endif\n#endif /* GL_VERSION_2_1 */\n\n#ifndef GL_VERSION_3_0\n#define GL_VERSION_3_0 1\ntypedef unsigned short GLhalf;\n#define GL_COMPARE_REF_TO_TEXTURE         0x884E\n#define GL_CLIP_DISTANCE0                 0x3000\n#define GL_CLIP_DISTANCE1                 0x3001\n#define GL_CLIP_DISTANCE2                 0x3002\n#define GL_CLIP_DISTANCE3                 0x3003\n#define GL_CLIP_DISTANCE4                 0x3004\n#define GL_CLIP_DISTANCE5                 0x3005\n#define GL_CLIP_DISTANCE6                 0x3006\n#define GL_CLIP_DISTANCE7                 0x3007\n#define GL_MAX_CLIP_DISTANCES             0x0D32\n#define GL_MAJOR_VERSION                  0x821B\n#define GL_MINOR_VERSION                  0x821C\n#define GL_NUM_EXTENSIONS                 0x821D\n#define GL_CONTEXT_FLAGS                  0x821E\n#define GL_COMPRESSED_RED                 0x8225\n#define GL_COMPRESSED_RG                  0x8226\n#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001\n#define GL_RGBA32F                        0x8814\n#define GL_RGB32F                         0x8815\n#define GL_RGBA16F                        0x881A\n#define GL_RGB16F                         0x881B\n#define GL_VERTEX_ATTRIB_ARRAY_INTEGER    0x88FD\n#define GL_MAX_ARRAY_TEXTURE_LAYERS       0x88FF\n#define GL_MIN_PROGRAM_TEXEL_OFFSET       0x8904\n#define GL_MAX_PROGRAM_TEXEL_OFFSET       0x8905\n#define GL_CLAMP_READ_COLOR               0x891C\n#define GL_FIXED_ONLY                     0x891D\n#define GL_MAX_VARYING_COMPONENTS         0x8B4B\n#define GL_TEXTURE_1D_ARRAY               0x8C18\n#define GL_PROXY_TEXTURE_1D_ARRAY         0x8C19\n#define GL_TEXTURE_2D_ARRAY               0x8C1A\n#define GL_PROXY_TEXTURE_2D_ARRAY         0x8C1B\n#define GL_TEXTURE_BINDING_1D_ARRAY       0x8C1C\n#define GL_TEXTURE_BINDING_2D_ARRAY       0x8C1D\n#define GL_R11F_G11F_B10F                 0x8C3A\n#define GL_UNSIGNED_INT_10F_11F_11F_REV   0x8C3B\n#define GL_RGB9_E5                        0x8C3D\n#define GL_UNSIGNED_INT_5_9_9_9_REV       0x8C3E\n#define GL_TEXTURE_SHARED_SIZE            0x8C3F\n#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76\n#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F\n#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80\n#define GL_TRANSFORM_FEEDBACK_VARYINGS    0x8C83\n#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84\n#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85\n#define GL_PRIMITIVES_GENERATED           0x8C87\n#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88\n#define GL_RASTERIZER_DISCARD             0x8C89\n#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A\n#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B\n#define GL_INTERLEAVED_ATTRIBS            0x8C8C\n#define GL_SEPARATE_ATTRIBS               0x8C8D\n#define GL_TRANSFORM_FEEDBACK_BUFFER      0x8C8E\n#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F\n#define GL_RGBA32UI                       0x8D70\n#define GL_RGB32UI                        0x8D71\n#define GL_RGBA16UI                       0x8D76\n#define GL_RGB16UI                        0x8D77\n#define GL_RGBA8UI                        0x8D7C\n#define GL_RGB8UI                         0x8D7D\n#define GL_RGBA32I                        0x8D82\n#define GL_RGB32I                         0x8D83\n#define GL_RGBA16I                        0x8D88\n#define GL_RGB16I                         0x8D89\n#define GL_RGBA8I                         0x8D8E\n#define GL_RGB8I                          0x8D8F\n#define GL_RED_INTEGER                    0x8D94\n#define GL_GREEN_INTEGER                  0x8D95\n#define GL_BLUE_INTEGER                   0x8D96\n#define GL_RGB_INTEGER                    0x8D98\n#define GL_RGBA_INTEGER                   0x8D99\n#define GL_BGR_INTEGER                    0x8D9A\n#define GL_BGRA_INTEGER                   0x8D9B\n#define GL_SAMPLER_1D_ARRAY               0x8DC0\n#define GL_SAMPLER_2D_ARRAY               0x8DC1\n#define GL_SAMPLER_1D_ARRAY_SHADOW        0x8DC3\n#define GL_SAMPLER_2D_ARRAY_SHADOW        0x8DC4\n#define GL_SAMPLER_CUBE_SHADOW            0x8DC5\n#define GL_UNSIGNED_INT_VEC2              0x8DC6\n#define GL_UNSIGNED_INT_VEC3              0x8DC7\n#define GL_UNSIGNED_INT_VEC4              0x8DC8\n#define GL_INT_SAMPLER_1D                 0x8DC9\n#define GL_INT_SAMPLER_2D                 0x8DCA\n#define GL_INT_SAMPLER_3D                 0x8DCB\n#define GL_INT_SAMPLER_CUBE               0x8DCC\n#define GL_INT_SAMPLER_1D_ARRAY           0x8DCE\n#define GL_INT_SAMPLER_2D_ARRAY           0x8DCF\n#define GL_UNSIGNED_INT_SAMPLER_1D        0x8DD1\n#define GL_UNSIGNED_INT_SAMPLER_2D        0x8DD2\n#define GL_UNSIGNED_INT_SAMPLER_3D        0x8DD3\n#define GL_UNSIGNED_INT_SAMPLER_CUBE      0x8DD4\n#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY  0x8DD6\n#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY  0x8DD7\n#define GL_QUERY_WAIT                     0x8E13\n#define GL_QUERY_NO_WAIT                  0x8E14\n#define GL_QUERY_BY_REGION_WAIT           0x8E15\n#define GL_QUERY_BY_REGION_NO_WAIT        0x8E16\n#define GL_BUFFER_ACCESS_FLAGS            0x911F\n#define GL_BUFFER_MAP_LENGTH              0x9120\n#define GL_BUFFER_MAP_OFFSET              0x9121\n#define GL_DEPTH_COMPONENT32F             0x8CAC\n#define GL_DEPTH32F_STENCIL8              0x8CAD\n#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD\n#define GL_INVALID_FRAMEBUFFER_OPERATION  0x0506\n#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210\n#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211\n#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212\n#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213\n#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214\n#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215\n#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216\n#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217\n#define GL_FRAMEBUFFER_DEFAULT            0x8218\n#define GL_FRAMEBUFFER_UNDEFINED          0x8219\n#define GL_DEPTH_STENCIL_ATTACHMENT       0x821A\n#define GL_MAX_RENDERBUFFER_SIZE          0x84E8\n#define GL_DEPTH_STENCIL                  0x84F9\n#define GL_UNSIGNED_INT_24_8              0x84FA\n#define GL_DEPTH24_STENCIL8               0x88F0\n#define GL_TEXTURE_STENCIL_SIZE           0x88F1\n#define GL_TEXTURE_RED_TYPE               0x8C10\n#define GL_TEXTURE_GREEN_TYPE             0x8C11\n#define GL_TEXTURE_BLUE_TYPE              0x8C12\n#define GL_TEXTURE_ALPHA_TYPE             0x8C13\n#define GL_TEXTURE_DEPTH_TYPE             0x8C16\n#define GL_UNSIGNED_NORMALIZED            0x8C17\n#define GL_FRAMEBUFFER_BINDING            0x8CA6\n#define GL_DRAW_FRAMEBUFFER_BINDING       0x8CA6\n#define GL_RENDERBUFFER_BINDING           0x8CA7\n#define GL_READ_FRAMEBUFFER               0x8CA8\n#define GL_DRAW_FRAMEBUFFER               0x8CA9\n#define GL_READ_FRAMEBUFFER_BINDING       0x8CAA\n#define GL_RENDERBUFFER_SAMPLES           0x8CAB\n#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0\n#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4\n#define GL_FRAMEBUFFER_COMPLETE           0x8CD5\n#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6\n#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7\n#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB\n#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC\n#define GL_FRAMEBUFFER_UNSUPPORTED        0x8CDD\n#define GL_MAX_COLOR_ATTACHMENTS          0x8CDF\n#define GL_COLOR_ATTACHMENT0              0x8CE0\n#define GL_COLOR_ATTACHMENT1              0x8CE1\n#define GL_COLOR_ATTACHMENT2              0x8CE2\n#define GL_COLOR_ATTACHMENT3              0x8CE3\n#define GL_COLOR_ATTACHMENT4              0x8CE4\n#define GL_COLOR_ATTACHMENT5              0x8CE5\n#define GL_COLOR_ATTACHMENT6              0x8CE6\n#define GL_COLOR_ATTACHMENT7              0x8CE7\n#define GL_COLOR_ATTACHMENT8              0x8CE8\n#define GL_COLOR_ATTACHMENT9              0x8CE9\n#define GL_COLOR_ATTACHMENT10             0x8CEA\n#define GL_COLOR_ATTACHMENT11             0x8CEB\n#define GL_COLOR_ATTACHMENT12             0x8CEC\n#define GL_COLOR_ATTACHMENT13             0x8CED\n#define GL_COLOR_ATTACHMENT14             0x8CEE\n#define GL_COLOR_ATTACHMENT15             0x8CEF\n#define GL_COLOR_ATTACHMENT16             0x8CF0\n#define GL_COLOR_ATTACHMENT17             0x8CF1\n#define GL_COLOR_ATTACHMENT18             0x8CF2\n#define GL_COLOR_ATTACHMENT19             0x8CF3\n#define GL_COLOR_ATTACHMENT20             0x8CF4\n#define GL_COLOR_ATTACHMENT21             0x8CF5\n#define GL_COLOR_ATTACHMENT22             0x8CF6\n#define GL_COLOR_ATTACHMENT23             0x8CF7\n#define GL_COLOR_ATTACHMENT24             0x8CF8\n#define GL_COLOR_ATTACHMENT25             0x8CF9\n#define GL_COLOR_ATTACHMENT26             0x8CFA\n#define GL_COLOR_ATTACHMENT27             0x8CFB\n#define GL_COLOR_ATTACHMENT28             0x8CFC\n#define GL_COLOR_ATTACHMENT29             0x8CFD\n#define GL_COLOR_ATTACHMENT30             0x8CFE\n#define GL_COLOR_ATTACHMENT31             0x8CFF\n#define GL_DEPTH_ATTACHMENT               0x8D00\n#define GL_STENCIL_ATTACHMENT             0x8D20\n#define GL_FRAMEBUFFER                    0x8D40\n#define GL_RENDERBUFFER                   0x8D41\n#define GL_RENDERBUFFER_WIDTH             0x8D42\n#define GL_RENDERBUFFER_HEIGHT            0x8D43\n#define GL_RENDERBUFFER_INTERNAL_FORMAT   0x8D44\n#define GL_STENCIL_INDEX1                 0x8D46\n#define GL_STENCIL_INDEX4                 0x8D47\n#define GL_STENCIL_INDEX8                 0x8D48\n#define GL_STENCIL_INDEX16                0x8D49\n#define GL_RENDERBUFFER_RED_SIZE          0x8D50\n#define GL_RENDERBUFFER_GREEN_SIZE        0x8D51\n#define GL_RENDERBUFFER_BLUE_SIZE         0x8D52\n#define GL_RENDERBUFFER_ALPHA_SIZE        0x8D53\n#define GL_RENDERBUFFER_DEPTH_SIZE        0x8D54\n#define GL_RENDERBUFFER_STENCIL_SIZE      0x8D55\n#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56\n#define GL_MAX_SAMPLES                    0x8D57\n#define GL_FRAMEBUFFER_SRGB               0x8DB9\n#define GL_HALF_FLOAT                     0x140B\n#define GL_MAP_READ_BIT                   0x0001\n#define GL_MAP_WRITE_BIT                  0x0002\n#define GL_MAP_INVALIDATE_RANGE_BIT       0x0004\n#define GL_MAP_INVALIDATE_BUFFER_BIT      0x0008\n#define GL_MAP_FLUSH_EXPLICIT_BIT         0x0010\n#define GL_MAP_UNSYNCHRONIZED_BIT         0x0020\n#define GL_COMPRESSED_RED_RGTC1           0x8DBB\n#define GL_COMPRESSED_SIGNED_RED_RGTC1    0x8DBC\n#define GL_COMPRESSED_RG_RGTC2            0x8DBD\n#define GL_COMPRESSED_SIGNED_RG_RGTC2     0x8DBE\n#define GL_RG                             0x8227\n#define GL_RG_INTEGER                     0x8228\n#define GL_R8                             0x8229\n#define GL_R16                            0x822A\n#define GL_RG8                            0x822B\n#define GL_RG16                           0x822C\n#define GL_R16F                           0x822D\n#define GL_R32F                           0x822E\n#define GL_RG16F                          0x822F\n#define GL_RG32F                          0x8230\n#define GL_R8I                            0x8231\n#define GL_R8UI                           0x8232\n#define GL_R16I                           0x8233\n#define GL_R16UI                          0x8234\n#define GL_R32I                           0x8235\n#define GL_R32UI                          0x8236\n#define GL_RG8I                           0x8237\n#define GL_RG8UI                          0x8238\n#define GL_RG16I                          0x8239\n#define GL_RG16UI                         0x823A\n#define GL_RG32I                          0x823B\n#define GL_RG32UI                         0x823C\n#define GL_VERTEX_ARRAY_BINDING           0x85B5\ntypedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);\ntypedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);\ntypedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);\ntypedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);\ntypedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);\ntypedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);\ntypedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);\ntypedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);\ntypedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);\ntypedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);\ntypedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);\ntypedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);\ntypedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);\ntypedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);\ntypedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);\ntypedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\ntypedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);\ntypedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);\ntypedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);\ntypedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);\ntypedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);\ntypedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);\ntypedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);\ntypedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);\ntypedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\ntypedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);\ntypedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);\ntypedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);\ntypedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);\ntypedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);\ntypedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);\nGLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);\nGLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);\nGLAPI void APIENTRY glEnablei (GLenum target, GLuint index);\nGLAPI void APIENTRY glDisablei (GLenum target, GLuint index);\nGLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index);\nGLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode);\nGLAPI void APIENTRY glEndTransformFeedback (void);\nGLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);\nGLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);\nGLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);\nGLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);\nGLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);\nGLAPI void APIENTRY glEndConditionalRender (void);\nGLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\nGLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x);\nGLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y);\nGLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z);\nGLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);\nGLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x);\nGLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y);\nGLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z);\nGLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);\nGLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v);\nGLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v);\nGLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v);\nGLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);\nGLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name);\nGLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0);\nGLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);\nGLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);\nGLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\nGLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);\nGLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);\nGLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);\nGLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);\nGLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);\nGLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index);\nGLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer);\nGLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);\nGLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);\nGLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);\nGLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer);\nGLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);\nGLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);\nGLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);\nGLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target);\nGLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\nGLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\nGLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);\nGLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\nGLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGenerateMipmap (GLenum target);\nGLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\nGLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);\nGLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);\nGLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glBindVertexArray (GLuint array);\nGLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);\nGLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);\nGLAPI GLboolean APIENTRY glIsVertexArray (GLuint array);\n#endif\n#endif /* GL_VERSION_3_0 */\n\n#ifndef GL_VERSION_3_1\n#define GL_VERSION_3_1 1\n#define GL_SAMPLER_2D_RECT                0x8B63\n#define GL_SAMPLER_2D_RECT_SHADOW         0x8B64\n#define GL_SAMPLER_BUFFER                 0x8DC2\n#define GL_INT_SAMPLER_2D_RECT            0x8DCD\n#define GL_INT_SAMPLER_BUFFER             0x8DD0\n#define GL_UNSIGNED_INT_SAMPLER_2D_RECT   0x8DD5\n#define GL_UNSIGNED_INT_SAMPLER_BUFFER    0x8DD8\n#define GL_TEXTURE_BUFFER                 0x8C2A\n#define GL_MAX_TEXTURE_BUFFER_SIZE        0x8C2B\n#define GL_TEXTURE_BINDING_BUFFER         0x8C2C\n#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D\n#define GL_TEXTURE_RECTANGLE              0x84F5\n#define GL_TEXTURE_BINDING_RECTANGLE      0x84F6\n#define GL_PROXY_TEXTURE_RECTANGLE        0x84F7\n#define GL_MAX_RECTANGLE_TEXTURE_SIZE     0x84F8\n#define GL_R8_SNORM                       0x8F94\n#define GL_RG8_SNORM                      0x8F95\n#define GL_RGB8_SNORM                     0x8F96\n#define GL_RGBA8_SNORM                    0x8F97\n#define GL_R16_SNORM                      0x8F98\n#define GL_RG16_SNORM                     0x8F99\n#define GL_RGB16_SNORM                    0x8F9A\n#define GL_RGBA16_SNORM                   0x8F9B\n#define GL_SIGNED_NORMALIZED              0x8F9C\n#define GL_PRIMITIVE_RESTART              0x8F9D\n#define GL_PRIMITIVE_RESTART_INDEX        0x8F9E\n#define GL_COPY_READ_BUFFER               0x8F36\n#define GL_COPY_WRITE_BUFFER              0x8F37\n#define GL_UNIFORM_BUFFER                 0x8A11\n#define GL_UNIFORM_BUFFER_BINDING         0x8A28\n#define GL_UNIFORM_BUFFER_START           0x8A29\n#define GL_UNIFORM_BUFFER_SIZE            0x8A2A\n#define GL_MAX_VERTEX_UNIFORM_BLOCKS      0x8A2B\n#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS    0x8A2C\n#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS    0x8A2D\n#define GL_MAX_COMBINED_UNIFORM_BLOCKS    0x8A2E\n#define GL_MAX_UNIFORM_BUFFER_BINDINGS    0x8A2F\n#define GL_MAX_UNIFORM_BLOCK_SIZE         0x8A30\n#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31\n#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32\n#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33\n#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34\n#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35\n#define GL_ACTIVE_UNIFORM_BLOCKS          0x8A36\n#define GL_UNIFORM_TYPE                   0x8A37\n#define GL_UNIFORM_SIZE                   0x8A38\n#define GL_UNIFORM_NAME_LENGTH            0x8A39\n#define GL_UNIFORM_BLOCK_INDEX            0x8A3A\n#define GL_UNIFORM_OFFSET                 0x8A3B\n#define GL_UNIFORM_ARRAY_STRIDE           0x8A3C\n#define GL_UNIFORM_MATRIX_STRIDE          0x8A3D\n#define GL_UNIFORM_IS_ROW_MAJOR           0x8A3E\n#define GL_UNIFORM_BLOCK_BINDING          0x8A3F\n#define GL_UNIFORM_BLOCK_DATA_SIZE        0x8A40\n#define GL_UNIFORM_BLOCK_NAME_LENGTH      0x8A41\n#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS  0x8A42\n#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46\n#define GL_INVALID_INDEX                  0xFFFFFFFFu\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);\ntypedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);\ntypedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);\ntypedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);\ntypedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);\ntypedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);\nGLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);\nGLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);\nGLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);\nGLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\nGLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);\nGLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);\nGLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);\nGLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);\nGLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);\n#endif\n#endif /* GL_VERSION_3_1 */\n\n#ifndef GL_VERSION_3_2\n#define GL_VERSION_3_2 1\ntypedef struct __GLsync *GLsync;\n#ifndef GLEXT_64_TYPES_DEFINED\n/* This code block is duplicated in glxext.h, so must be protected */\n#define GLEXT_64_TYPES_DEFINED\n/* Define int32_t, int64_t, and uint64_t types for UST/MSC */\n/* (as used in the GL_EXT_timer_query extension). */\n#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n#include <inttypes.h>\n#elif defined(__sun__) || defined(__digital__)\n#include <inttypes.h>\n#if defined(__STDC__)\n#if defined(__arch64__) || defined(_LP64)\ntypedef long int int64_t;\ntypedef unsigned long int uint64_t;\n#else\ntypedef long long int int64_t;\ntypedef unsigned long long int uint64_t;\n#endif /* __arch64__ */\n#endif /* __STDC__ */\n#elif defined( __VMS ) || defined(__sgi)\n#include <inttypes.h>\n#elif defined(__SCO__) || defined(__USLC__)\n#include <stdint.h>\n#elif defined(__UNIXOS2__) || defined(__SOL64__)\ntypedef long int int32_t;\ntypedef long long int int64_t;\ntypedef unsigned long long int uint64_t;\n#elif defined(_WIN32) && defined(__GNUC__)\n#include <stdint.h>\n#elif defined(_WIN32)\ntypedef __int32 int32_t;\ntypedef __int64 int64_t;\ntypedef unsigned __int64 uint64_t;\n#else\n/* Fallback if nothing above works */\n#include <inttypes.h>\n#endif\n#endif\ntypedef uint64_t GLuint64;\ntypedef int64_t GLint64;\n#define GL_CONTEXT_CORE_PROFILE_BIT       0x00000001\n#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002\n#define GL_LINES_ADJACENCY                0x000A\n#define GL_LINE_STRIP_ADJACENCY           0x000B\n#define GL_TRIANGLES_ADJACENCY            0x000C\n#define GL_TRIANGLE_STRIP_ADJACENCY       0x000D\n#define GL_PROGRAM_POINT_SIZE             0x8642\n#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29\n#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7\n#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8\n#define GL_GEOMETRY_SHADER                0x8DD9\n#define GL_GEOMETRY_VERTICES_OUT          0x8916\n#define GL_GEOMETRY_INPUT_TYPE            0x8917\n#define GL_GEOMETRY_OUTPUT_TYPE           0x8918\n#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF\n#define GL_MAX_GEOMETRY_OUTPUT_VERTICES   0x8DE0\n#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1\n#define GL_MAX_VERTEX_OUTPUT_COMPONENTS   0x9122\n#define GL_MAX_GEOMETRY_INPUT_COMPONENTS  0x9123\n#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124\n#define GL_MAX_FRAGMENT_INPUT_COMPONENTS  0x9125\n#define GL_CONTEXT_PROFILE_MASK           0x9126\n#define GL_DEPTH_CLAMP                    0x864F\n#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C\n#define GL_FIRST_VERTEX_CONVENTION        0x8E4D\n#define GL_LAST_VERTEX_CONVENTION         0x8E4E\n#define GL_PROVOKING_VERTEX               0x8E4F\n#define GL_TEXTURE_CUBE_MAP_SEAMLESS      0x884F\n#define GL_MAX_SERVER_WAIT_TIMEOUT        0x9111\n#define GL_OBJECT_TYPE                    0x9112\n#define GL_SYNC_CONDITION                 0x9113\n#define GL_SYNC_STATUS                    0x9114\n#define GL_SYNC_FLAGS                     0x9115\n#define GL_SYNC_FENCE                     0x9116\n#define GL_SYNC_GPU_COMMANDS_COMPLETE     0x9117\n#define GL_UNSIGNALED                     0x9118\n#define GL_SIGNALED                       0x9119\n#define GL_ALREADY_SIGNALED               0x911A\n#define GL_TIMEOUT_EXPIRED                0x911B\n#define GL_CONDITION_SATISFIED            0x911C\n#define GL_WAIT_FAILED                    0x911D\n#define GL_TIMEOUT_IGNORED                0xFFFFFFFFFFFFFFFFull\n#define GL_SYNC_FLUSH_COMMANDS_BIT        0x00000001\n#define GL_SAMPLE_POSITION                0x8E50\n#define GL_SAMPLE_MASK                    0x8E51\n#define GL_SAMPLE_MASK_VALUE              0x8E52\n#define GL_MAX_SAMPLE_MASK_WORDS          0x8E59\n#define GL_TEXTURE_2D_MULTISAMPLE         0x9100\n#define GL_PROXY_TEXTURE_2D_MULTISAMPLE   0x9101\n#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY   0x9102\n#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103\n#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104\n#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105\n#define GL_TEXTURE_SAMPLES                0x9106\n#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107\n#define GL_SAMPLER_2D_MULTISAMPLE         0x9108\n#define GL_INT_SAMPLER_2D_MULTISAMPLE     0x9109\n#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A\n#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY   0x910B\n#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C\n#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D\n#define GL_MAX_COLOR_TEXTURE_SAMPLES      0x910E\n#define GL_MAX_DEPTH_TEXTURE_SAMPLES      0x910F\n#define GL_MAX_INTEGER_SAMPLES            0x9110\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);\ntypedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);\ntypedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);\ntypedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);\ntypedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);\ntypedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);\ntypedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);\ntypedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);\ntypedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data);\ntypedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);\ntypedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);\ntypedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);\ntypedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);\nGLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);\nGLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);\nGLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);\nGLAPI void APIENTRY glProvokingVertex (GLenum mode);\nGLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags);\nGLAPI GLboolean APIENTRY glIsSync (GLsync sync);\nGLAPI void APIENTRY glDeleteSync (GLsync sync);\nGLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);\nGLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);\nGLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);\nGLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);\nGLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);\nGLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);\nGLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);\nGLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);\nGLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask);\n#endif\n#endif /* GL_VERSION_3_2 */\n\n#ifndef GL_VERSION_3_3\n#define GL_VERSION_3_3 1\n#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR    0x88FE\n#define GL_SRC1_COLOR                     0x88F9\n#define GL_ONE_MINUS_SRC1_COLOR           0x88FA\n#define GL_ONE_MINUS_SRC1_ALPHA           0x88FB\n#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS   0x88FC\n#define GL_ANY_SAMPLES_PASSED             0x8C2F\n#define GL_SAMPLER_BINDING                0x8919\n#define GL_RGB10_A2UI                     0x906F\n#define GL_TEXTURE_SWIZZLE_R              0x8E42\n#define GL_TEXTURE_SWIZZLE_G              0x8E43\n#define GL_TEXTURE_SWIZZLE_B              0x8E44\n#define GL_TEXTURE_SWIZZLE_A              0x8E45\n#define GL_TEXTURE_SWIZZLE_RGBA           0x8E46\n#define GL_TIME_ELAPSED                   0x88BF\n#define GL_TIMESTAMP                      0x8E28\n#define GL_INT_2_10_10_10_REV             0x8D9F\ntypedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);\ntypedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);\ntypedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);\ntypedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);\ntypedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);\nGLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);\nGLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);\nGLAPI GLboolean APIENTRY glIsSampler (GLuint sampler);\nGLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);\nGLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);\nGLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);\nGLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);\nGLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);\nGLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);\nGLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target);\nGLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params);\nGLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params);\nGLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);\nGLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\nGLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\nGLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\nGLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\n#endif\n#endif /* GL_VERSION_3_3 */\n\n#ifndef GL_VERSION_4_0\n#define GL_VERSION_4_0 1\n#define GL_SAMPLE_SHADING                 0x8C36\n#define GL_MIN_SAMPLE_SHADING_VALUE       0x8C37\n#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E\n#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F\n#define GL_TEXTURE_CUBE_MAP_ARRAY         0x9009\n#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A\n#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY   0x900B\n#define GL_SAMPLER_CUBE_MAP_ARRAY         0x900C\n#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW  0x900D\n#define GL_INT_SAMPLER_CUBE_MAP_ARRAY     0x900E\n#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F\n#define GL_DRAW_INDIRECT_BUFFER           0x8F3F\n#define GL_DRAW_INDIRECT_BUFFER_BINDING   0x8F43\n#define GL_GEOMETRY_SHADER_INVOCATIONS    0x887F\n#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A\n#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B\n#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C\n#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D\n#define GL_MAX_VERTEX_STREAMS             0x8E71\n#define GL_DOUBLE_VEC2                    0x8FFC\n#define GL_DOUBLE_VEC3                    0x8FFD\n#define GL_DOUBLE_VEC4                    0x8FFE\n#define GL_DOUBLE_MAT2                    0x8F46\n#define GL_DOUBLE_MAT3                    0x8F47\n#define GL_DOUBLE_MAT4                    0x8F48\n#define GL_DOUBLE_MAT2x3                  0x8F49\n#define GL_DOUBLE_MAT2x4                  0x8F4A\n#define GL_DOUBLE_MAT3x2                  0x8F4B\n#define GL_DOUBLE_MAT3x4                  0x8F4C\n#define GL_DOUBLE_MAT4x2                  0x8F4D\n#define GL_DOUBLE_MAT4x3                  0x8F4E\n#define GL_ACTIVE_SUBROUTINES             0x8DE5\n#define GL_ACTIVE_SUBROUTINE_UNIFORMS     0x8DE6\n#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47\n#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH   0x8E48\n#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49\n#define GL_MAX_SUBROUTINES                0x8DE7\n#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8\n#define GL_NUM_COMPATIBLE_SUBROUTINES     0x8E4A\n#define GL_COMPATIBLE_SUBROUTINES         0x8E4B\n#define GL_PATCHES                        0x000E\n#define GL_PATCH_VERTICES                 0x8E72\n#define GL_PATCH_DEFAULT_INNER_LEVEL      0x8E73\n#define GL_PATCH_DEFAULT_OUTER_LEVEL      0x8E74\n#define GL_TESS_CONTROL_OUTPUT_VERTICES   0x8E75\n#define GL_TESS_GEN_MODE                  0x8E76\n#define GL_TESS_GEN_SPACING               0x8E77\n#define GL_TESS_GEN_VERTEX_ORDER          0x8E78\n#define GL_TESS_GEN_POINT_MODE            0x8E79\n#define GL_ISOLINES                       0x8E7A\n#define GL_FRACTIONAL_ODD                 0x8E7B\n#define GL_FRACTIONAL_EVEN                0x8E7C\n#define GL_MAX_PATCH_VERTICES             0x8E7D\n#define GL_MAX_TESS_GEN_LEVEL             0x8E7E\n#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F\n#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80\n#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81\n#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82\n#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83\n#define GL_MAX_TESS_PATCH_COMPONENTS      0x8E84\n#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85\n#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86\n#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89\n#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A\n#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C\n#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D\n#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E\n#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1\n#define GL_TESS_EVALUATION_SHADER         0x8E87\n#define GL_TESS_CONTROL_SHADER            0x8E88\n#define GL_TRANSFORM_FEEDBACK             0x8E22\n#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23\n#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24\n#define GL_TRANSFORM_FEEDBACK_BINDING     0x8E25\n#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70\ntypedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\ntypedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);\ntypedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect);\ntypedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);\ntypedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params);\ntypedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);\ntypedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);\ntypedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);\ntypedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);\ntypedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);\ntypedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);\ntypedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values);\ntypedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);\ntypedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);\ntypedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);\ntypedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);\ntypedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);\ntypedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);\ntypedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);\ntypedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMinSampleShading (GLfloat value);\nGLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);\nGLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\nGLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);\nGLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\nGLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect);\nGLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect);\nGLAPI void APIENTRY glUniform1d (GLint location, GLdouble x);\nGLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params);\nGLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);\nGLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);\nGLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);\nGLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);\nGLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);\nGLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);\nGLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);\nGLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);\nGLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value);\nGLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values);\nGLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id);\nGLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);\nGLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);\nGLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id);\nGLAPI void APIENTRY glPauseTransformFeedback (void);\nGLAPI void APIENTRY glResumeTransformFeedback (void);\nGLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id);\nGLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream);\nGLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id);\nGLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index);\nGLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params);\n#endif\n#endif /* GL_VERSION_4_0 */\n\n#ifndef GL_VERSION_4_1\n#define GL_VERSION_4_1 1\n#define GL_FIXED                          0x140C\n#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A\n#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B\n#define GL_LOW_FLOAT                      0x8DF0\n#define GL_MEDIUM_FLOAT                   0x8DF1\n#define GL_HIGH_FLOAT                     0x8DF2\n#define GL_LOW_INT                        0x8DF3\n#define GL_MEDIUM_INT                     0x8DF4\n#define GL_HIGH_INT                       0x8DF5\n#define GL_SHADER_COMPILER                0x8DFA\n#define GL_SHADER_BINARY_FORMATS          0x8DF8\n#define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9\n#define GL_MAX_VERTEX_UNIFORM_VECTORS     0x8DFB\n#define GL_MAX_VARYING_VECTORS            0x8DFC\n#define GL_MAX_FRAGMENT_UNIFORM_VECTORS   0x8DFD\n#define GL_RGB565                         0x8D62\n#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257\n#define GL_PROGRAM_BINARY_LENGTH          0x8741\n#define GL_NUM_PROGRAM_BINARY_FORMATS     0x87FE\n#define GL_PROGRAM_BINARY_FORMATS         0x87FF\n#define GL_VERTEX_SHADER_BIT              0x00000001\n#define GL_FRAGMENT_SHADER_BIT            0x00000002\n#define GL_GEOMETRY_SHADER_BIT            0x00000004\n#define GL_TESS_CONTROL_SHADER_BIT        0x00000008\n#define GL_TESS_EVALUATION_SHADER_BIT     0x00000010\n#define GL_ALL_SHADER_BITS                0xFFFFFFFF\n#define GL_PROGRAM_SEPARABLE              0x8258\n#define GL_ACTIVE_PROGRAM                 0x8259\n#define GL_PROGRAM_PIPELINE_BINDING       0x825A\n#define GL_MAX_VIEWPORTS                  0x825B\n#define GL_VIEWPORT_SUBPIXEL_BITS         0x825C\n#define GL_VIEWPORT_BOUNDS_RANGE          0x825D\n#define GL_LAYER_PROVOKING_VERTEX         0x825E\n#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F\n#define GL_UNDEFINED_VERTEX               0x8260\ntypedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);\ntypedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);\ntypedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);\ntypedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);\ntypedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);\ntypedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);\ntypedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);\ntypedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);\ntypedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings);\ntypedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);\ntypedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);\ntypedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);\ntypedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);\ntypedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);\ntypedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params);\ntypedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);\ntypedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);\ntypedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f);\ntypedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);\ntypedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glReleaseShaderCompiler (void);\nGLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);\nGLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);\nGLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f);\nGLAPI void APIENTRY glClearDepthf (GLfloat d);\nGLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);\nGLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);\nGLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);\nGLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);\nGLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);\nGLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings);\nGLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);\nGLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);\nGLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);\nGLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline);\nGLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);\nGLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);\nGLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);\nGLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0);\nGLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);\nGLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);\nGLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);\nGLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1);\nGLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);\nGLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);\nGLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\nGLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);\nGLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);\nGLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\nGLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\nGLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);\nGLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\nGLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline);\nGLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\nGLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x);\nGLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\nGLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params);\nGLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v);\nGLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);\nGLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);\nGLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v);\nGLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f);\nGLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);\nGLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);\n#endif\n#endif /* GL_VERSION_4_1 */\n\n#ifndef GL_VERSION_4_2\n#define GL_VERSION_4_2 1\n#define GL_COPY_READ_BUFFER_BINDING       0x8F36\n#define GL_COPY_WRITE_BUFFER_BINDING      0x8F37\n#define GL_TRANSFORM_FEEDBACK_ACTIVE      0x8E24\n#define GL_TRANSFORM_FEEDBACK_PAUSED      0x8E23\n#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH  0x9127\n#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128\n#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH  0x9129\n#define GL_UNPACK_COMPRESSED_BLOCK_SIZE   0x912A\n#define GL_PACK_COMPRESSED_BLOCK_WIDTH    0x912B\n#define GL_PACK_COMPRESSED_BLOCK_HEIGHT   0x912C\n#define GL_PACK_COMPRESSED_BLOCK_DEPTH    0x912D\n#define GL_PACK_COMPRESSED_BLOCK_SIZE     0x912E\n#define GL_NUM_SAMPLE_COUNTS              0x9380\n#define GL_MIN_MAP_BUFFER_ALIGNMENT       0x90BC\n#define GL_ATOMIC_COUNTER_BUFFER          0x92C0\n#define GL_ATOMIC_COUNTER_BUFFER_BINDING  0x92C1\n#define GL_ATOMIC_COUNTER_BUFFER_START    0x92C2\n#define GL_ATOMIC_COUNTER_BUFFER_SIZE     0x92C3\n#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4\n#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5\n#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB\n#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC\n#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD\n#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE\n#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF\n#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0\n#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1\n#define GL_MAX_VERTEX_ATOMIC_COUNTERS     0x92D2\n#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3\n#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4\n#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS   0x92D5\n#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS   0x92D6\n#define GL_MAX_COMBINED_ATOMIC_COUNTERS   0x92D7\n#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8\n#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC\n#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS  0x92D9\n#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA\n#define GL_UNSIGNED_INT_ATOMIC_COUNTER    0x92DB\n#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001\n#define GL_ELEMENT_ARRAY_BARRIER_BIT      0x00000002\n#define GL_UNIFORM_BARRIER_BIT            0x00000004\n#define GL_TEXTURE_FETCH_BARRIER_BIT      0x00000008\n#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020\n#define GL_COMMAND_BARRIER_BIT            0x00000040\n#define GL_PIXEL_BUFFER_BARRIER_BIT       0x00000080\n#define GL_TEXTURE_UPDATE_BARRIER_BIT     0x00000100\n#define GL_BUFFER_UPDATE_BARRIER_BIT      0x00000200\n#define GL_FRAMEBUFFER_BARRIER_BIT        0x00000400\n#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800\n#define GL_ATOMIC_COUNTER_BARRIER_BIT     0x00001000\n#define GL_ALL_BARRIER_BITS               0xFFFFFFFF\n#define GL_MAX_IMAGE_UNITS                0x8F38\n#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39\n#define GL_IMAGE_BINDING_NAME             0x8F3A\n#define GL_IMAGE_BINDING_LEVEL            0x8F3B\n#define GL_IMAGE_BINDING_LAYERED          0x8F3C\n#define GL_IMAGE_BINDING_LAYER            0x8F3D\n#define GL_IMAGE_BINDING_ACCESS           0x8F3E\n#define GL_IMAGE_1D                       0x904C\n#define GL_IMAGE_2D                       0x904D\n#define GL_IMAGE_3D                       0x904E\n#define GL_IMAGE_2D_RECT                  0x904F\n#define GL_IMAGE_CUBE                     0x9050\n#define GL_IMAGE_BUFFER                   0x9051\n#define GL_IMAGE_1D_ARRAY                 0x9052\n#define GL_IMAGE_2D_ARRAY                 0x9053\n#define GL_IMAGE_CUBE_MAP_ARRAY           0x9054\n#define GL_IMAGE_2D_MULTISAMPLE           0x9055\n#define GL_IMAGE_2D_MULTISAMPLE_ARRAY     0x9056\n#define GL_INT_IMAGE_1D                   0x9057\n#define GL_INT_IMAGE_2D                   0x9058\n#define GL_INT_IMAGE_3D                   0x9059\n#define GL_INT_IMAGE_2D_RECT              0x905A\n#define GL_INT_IMAGE_CUBE                 0x905B\n#define GL_INT_IMAGE_BUFFER               0x905C\n#define GL_INT_IMAGE_1D_ARRAY             0x905D\n#define GL_INT_IMAGE_2D_ARRAY             0x905E\n#define GL_INT_IMAGE_CUBE_MAP_ARRAY       0x905F\n#define GL_INT_IMAGE_2D_MULTISAMPLE       0x9060\n#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061\n#define GL_UNSIGNED_INT_IMAGE_1D          0x9062\n#define GL_UNSIGNED_INT_IMAGE_2D          0x9063\n#define GL_UNSIGNED_INT_IMAGE_3D          0x9064\n#define GL_UNSIGNED_INT_IMAGE_2D_RECT     0x9065\n#define GL_UNSIGNED_INT_IMAGE_CUBE        0x9066\n#define GL_UNSIGNED_INT_IMAGE_BUFFER      0x9067\n#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY    0x9068\n#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY    0x9069\n#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A\n#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B\n#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C\n#define GL_MAX_IMAGE_SAMPLES              0x906D\n#define GL_IMAGE_BINDING_FORMAT           0x906E\n#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7\n#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8\n#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9\n#define GL_MAX_VERTEX_IMAGE_UNIFORMS      0x90CA\n#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB\n#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC\n#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS    0x90CD\n#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS    0x90CE\n#define GL_MAX_COMBINED_IMAGE_UNIFORMS    0x90CF\n#define GL_COMPRESSED_RGBA_BPTC_UNORM     0x8E8C\n#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D\n#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E\n#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F\n#define GL_TEXTURE_IMMUTABLE_FORMAT       0x912F\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);\ntypedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);\ntypedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);\ntypedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);\nGLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);\nGLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);\nGLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);\nGLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);\nGLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);\nGLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers);\nGLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\nGLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount);\nGLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);\n#endif\n#endif /* GL_VERSION_4_2 */\n\n#ifndef GL_VERSION_4_3\n#define GL_VERSION_4_3 1\ntypedef void (APIENTRY  *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);\n#define GL_NUM_SHADING_LANGUAGE_VERSIONS  0x82E9\n#define GL_VERTEX_ATTRIB_ARRAY_LONG       0x874E\n#define GL_COMPRESSED_RGB8_ETC2           0x9274\n#define GL_COMPRESSED_SRGB8_ETC2          0x9275\n#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276\n#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277\n#define GL_COMPRESSED_RGBA8_ETC2_EAC      0x9278\n#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279\n#define GL_COMPRESSED_R11_EAC             0x9270\n#define GL_COMPRESSED_SIGNED_R11_EAC      0x9271\n#define GL_COMPRESSED_RG11_EAC            0x9272\n#define GL_COMPRESSED_SIGNED_RG11_EAC     0x9273\n#define GL_PRIMITIVE_RESTART_FIXED_INDEX  0x8D69\n#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A\n#define GL_MAX_ELEMENT_INDEX              0x8D6B\n#define GL_COMPUTE_SHADER                 0x91B9\n#define GL_MAX_COMPUTE_UNIFORM_BLOCKS     0x91BB\n#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC\n#define GL_MAX_COMPUTE_IMAGE_UNIFORMS     0x91BD\n#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262\n#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263\n#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264\n#define GL_MAX_COMPUTE_ATOMIC_COUNTERS    0x8265\n#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266\n#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB\n#define GL_MAX_COMPUTE_WORK_GROUP_COUNT   0x91BE\n#define GL_MAX_COMPUTE_WORK_GROUP_SIZE    0x91BF\n#define GL_COMPUTE_WORK_GROUP_SIZE        0x8267\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED\n#define GL_DISPATCH_INDIRECT_BUFFER       0x90EE\n#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF\n#define GL_COMPUTE_SHADER_BIT             0x00000020\n#define GL_DEBUG_OUTPUT_SYNCHRONOUS       0x8242\n#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243\n#define GL_DEBUG_CALLBACK_FUNCTION        0x8244\n#define GL_DEBUG_CALLBACK_USER_PARAM      0x8245\n#define GL_DEBUG_SOURCE_API               0x8246\n#define GL_DEBUG_SOURCE_WINDOW_SYSTEM     0x8247\n#define GL_DEBUG_SOURCE_SHADER_COMPILER   0x8248\n#define GL_DEBUG_SOURCE_THIRD_PARTY       0x8249\n#define GL_DEBUG_SOURCE_APPLICATION       0x824A\n#define GL_DEBUG_SOURCE_OTHER             0x824B\n#define GL_DEBUG_TYPE_ERROR               0x824C\n#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D\n#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR  0x824E\n#define GL_DEBUG_TYPE_PORTABILITY         0x824F\n#define GL_DEBUG_TYPE_PERFORMANCE         0x8250\n#define GL_DEBUG_TYPE_OTHER               0x8251\n#define GL_MAX_DEBUG_MESSAGE_LENGTH       0x9143\n#define GL_MAX_DEBUG_LOGGED_MESSAGES      0x9144\n#define GL_DEBUG_LOGGED_MESSAGES          0x9145\n#define GL_DEBUG_SEVERITY_HIGH            0x9146\n#define GL_DEBUG_SEVERITY_MEDIUM          0x9147\n#define GL_DEBUG_SEVERITY_LOW             0x9148\n#define GL_DEBUG_TYPE_MARKER              0x8268\n#define GL_DEBUG_TYPE_PUSH_GROUP          0x8269\n#define GL_DEBUG_TYPE_POP_GROUP           0x826A\n#define GL_DEBUG_SEVERITY_NOTIFICATION    0x826B\n#define GL_MAX_DEBUG_GROUP_STACK_DEPTH    0x826C\n#define GL_DEBUG_GROUP_STACK_DEPTH        0x826D\n#define GL_BUFFER                         0x82E0\n#define GL_SHADER                         0x82E1\n#define GL_PROGRAM                        0x82E2\n#define GL_QUERY                          0x82E3\n#define GL_PROGRAM_PIPELINE               0x82E4\n#define GL_SAMPLER                        0x82E6\n#define GL_MAX_LABEL_LENGTH               0x82E8\n#define GL_DEBUG_OUTPUT                   0x92E0\n#define GL_CONTEXT_FLAG_DEBUG_BIT         0x00000002\n#define GL_MAX_UNIFORM_LOCATIONS          0x826E\n#define GL_FRAMEBUFFER_DEFAULT_WIDTH      0x9310\n#define GL_FRAMEBUFFER_DEFAULT_HEIGHT     0x9311\n#define GL_FRAMEBUFFER_DEFAULT_LAYERS     0x9312\n#define GL_FRAMEBUFFER_DEFAULT_SAMPLES    0x9313\n#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314\n#define GL_MAX_FRAMEBUFFER_WIDTH          0x9315\n#define GL_MAX_FRAMEBUFFER_HEIGHT         0x9316\n#define GL_MAX_FRAMEBUFFER_LAYERS         0x9317\n#define GL_MAX_FRAMEBUFFER_SAMPLES        0x9318\n#define GL_INTERNALFORMAT_SUPPORTED       0x826F\n#define GL_INTERNALFORMAT_PREFERRED       0x8270\n#define GL_INTERNALFORMAT_RED_SIZE        0x8271\n#define GL_INTERNALFORMAT_GREEN_SIZE      0x8272\n#define GL_INTERNALFORMAT_BLUE_SIZE       0x8273\n#define GL_INTERNALFORMAT_ALPHA_SIZE      0x8274\n#define GL_INTERNALFORMAT_DEPTH_SIZE      0x8275\n#define GL_INTERNALFORMAT_STENCIL_SIZE    0x8276\n#define GL_INTERNALFORMAT_SHARED_SIZE     0x8277\n#define GL_INTERNALFORMAT_RED_TYPE        0x8278\n#define GL_INTERNALFORMAT_GREEN_TYPE      0x8279\n#define GL_INTERNALFORMAT_BLUE_TYPE       0x827A\n#define GL_INTERNALFORMAT_ALPHA_TYPE      0x827B\n#define GL_INTERNALFORMAT_DEPTH_TYPE      0x827C\n#define GL_INTERNALFORMAT_STENCIL_TYPE    0x827D\n#define GL_MAX_WIDTH                      0x827E\n#define GL_MAX_HEIGHT                     0x827F\n#define GL_MAX_DEPTH                      0x8280\n#define GL_MAX_LAYERS                     0x8281\n#define GL_MAX_COMBINED_DIMENSIONS        0x8282\n#define GL_COLOR_COMPONENTS               0x8283\n#define GL_DEPTH_COMPONENTS               0x8284\n#define GL_STENCIL_COMPONENTS             0x8285\n#define GL_COLOR_RENDERABLE               0x8286\n#define GL_DEPTH_RENDERABLE               0x8287\n#define GL_STENCIL_RENDERABLE             0x8288\n#define GL_FRAMEBUFFER_RENDERABLE         0x8289\n#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A\n#define GL_FRAMEBUFFER_BLEND              0x828B\n#define GL_READ_PIXELS                    0x828C\n#define GL_READ_PIXELS_FORMAT             0x828D\n#define GL_READ_PIXELS_TYPE               0x828E\n#define GL_TEXTURE_IMAGE_FORMAT           0x828F\n#define GL_TEXTURE_IMAGE_TYPE             0x8290\n#define GL_GET_TEXTURE_IMAGE_FORMAT       0x8291\n#define GL_GET_TEXTURE_IMAGE_TYPE         0x8292\n#define GL_MIPMAP                         0x8293\n#define GL_MANUAL_GENERATE_MIPMAP         0x8294\n#define GL_AUTO_GENERATE_MIPMAP           0x8295\n#define GL_COLOR_ENCODING                 0x8296\n#define GL_SRGB_READ                      0x8297\n#define GL_SRGB_WRITE                     0x8298\n#define GL_FILTER                         0x829A\n#define GL_VERTEX_TEXTURE                 0x829B\n#define GL_TESS_CONTROL_TEXTURE           0x829C\n#define GL_TESS_EVALUATION_TEXTURE        0x829D\n#define GL_GEOMETRY_TEXTURE               0x829E\n#define GL_FRAGMENT_TEXTURE               0x829F\n#define GL_COMPUTE_TEXTURE                0x82A0\n#define GL_TEXTURE_SHADOW                 0x82A1\n#define GL_TEXTURE_GATHER                 0x82A2\n#define GL_TEXTURE_GATHER_SHADOW          0x82A3\n#define GL_SHADER_IMAGE_LOAD              0x82A4\n#define GL_SHADER_IMAGE_STORE             0x82A5\n#define GL_SHADER_IMAGE_ATOMIC            0x82A6\n#define GL_IMAGE_TEXEL_SIZE               0x82A7\n#define GL_IMAGE_COMPATIBILITY_CLASS      0x82A8\n#define GL_IMAGE_PIXEL_FORMAT             0x82A9\n#define GL_IMAGE_PIXEL_TYPE               0x82AA\n#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC\n#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD\n#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE\n#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF\n#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1\n#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2\n#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE  0x82B3\n#define GL_CLEAR_BUFFER                   0x82B4\n#define GL_TEXTURE_VIEW                   0x82B5\n#define GL_VIEW_COMPATIBILITY_CLASS       0x82B6\n#define GL_FULL_SUPPORT                   0x82B7\n#define GL_CAVEAT_SUPPORT                 0x82B8\n#define GL_IMAGE_CLASS_4_X_32             0x82B9\n#define GL_IMAGE_CLASS_2_X_32             0x82BA\n#define GL_IMAGE_CLASS_1_X_32             0x82BB\n#define GL_IMAGE_CLASS_4_X_16             0x82BC\n#define GL_IMAGE_CLASS_2_X_16             0x82BD\n#define GL_IMAGE_CLASS_1_X_16             0x82BE\n#define GL_IMAGE_CLASS_4_X_8              0x82BF\n#define GL_IMAGE_CLASS_2_X_8              0x82C0\n#define GL_IMAGE_CLASS_1_X_8              0x82C1\n#define GL_IMAGE_CLASS_11_11_10           0x82C2\n#define GL_IMAGE_CLASS_10_10_10_2         0x82C3\n#define GL_VIEW_CLASS_128_BITS            0x82C4\n#define GL_VIEW_CLASS_96_BITS             0x82C5\n#define GL_VIEW_CLASS_64_BITS             0x82C6\n#define GL_VIEW_CLASS_48_BITS             0x82C7\n#define GL_VIEW_CLASS_32_BITS             0x82C8\n#define GL_VIEW_CLASS_24_BITS             0x82C9\n#define GL_VIEW_CLASS_16_BITS             0x82CA\n#define GL_VIEW_CLASS_8_BITS              0x82CB\n#define GL_VIEW_CLASS_S3TC_DXT1_RGB       0x82CC\n#define GL_VIEW_CLASS_S3TC_DXT1_RGBA      0x82CD\n#define GL_VIEW_CLASS_S3TC_DXT3_RGBA      0x82CE\n#define GL_VIEW_CLASS_S3TC_DXT5_RGBA      0x82CF\n#define GL_VIEW_CLASS_RGTC1_RED           0x82D0\n#define GL_VIEW_CLASS_RGTC2_RG            0x82D1\n#define GL_VIEW_CLASS_BPTC_UNORM          0x82D2\n#define GL_VIEW_CLASS_BPTC_FLOAT          0x82D3\n#define GL_UNIFORM                        0x92E1\n#define GL_UNIFORM_BLOCK                  0x92E2\n#define GL_PROGRAM_INPUT                  0x92E3\n#define GL_PROGRAM_OUTPUT                 0x92E4\n#define GL_BUFFER_VARIABLE                0x92E5\n#define GL_SHADER_STORAGE_BLOCK           0x92E6\n#define GL_VERTEX_SUBROUTINE              0x92E8\n#define GL_TESS_CONTROL_SUBROUTINE        0x92E9\n#define GL_TESS_EVALUATION_SUBROUTINE     0x92EA\n#define GL_GEOMETRY_SUBROUTINE            0x92EB\n#define GL_FRAGMENT_SUBROUTINE            0x92EC\n#define GL_COMPUTE_SUBROUTINE             0x92ED\n#define GL_VERTEX_SUBROUTINE_UNIFORM      0x92EE\n#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF\n#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0\n#define GL_GEOMETRY_SUBROUTINE_UNIFORM    0x92F1\n#define GL_FRAGMENT_SUBROUTINE_UNIFORM    0x92F2\n#define GL_COMPUTE_SUBROUTINE_UNIFORM     0x92F3\n#define GL_TRANSFORM_FEEDBACK_VARYING     0x92F4\n#define GL_ACTIVE_RESOURCES               0x92F5\n#define GL_MAX_NAME_LENGTH                0x92F6\n#define GL_MAX_NUM_ACTIVE_VARIABLES       0x92F7\n#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8\n#define GL_NAME_LENGTH                    0x92F9\n#define GL_TYPE                           0x92FA\n#define GL_ARRAY_SIZE                     0x92FB\n#define GL_OFFSET                         0x92FC\n#define GL_BLOCK_INDEX                    0x92FD\n#define GL_ARRAY_STRIDE                   0x92FE\n#define GL_MATRIX_STRIDE                  0x92FF\n#define GL_IS_ROW_MAJOR                   0x9300\n#define GL_ATOMIC_COUNTER_BUFFER_INDEX    0x9301\n#define GL_BUFFER_BINDING                 0x9302\n#define GL_BUFFER_DATA_SIZE               0x9303\n#define GL_NUM_ACTIVE_VARIABLES           0x9304\n#define GL_ACTIVE_VARIABLES               0x9305\n#define GL_REFERENCED_BY_VERTEX_SHADER    0x9306\n#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307\n#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308\n#define GL_REFERENCED_BY_GEOMETRY_SHADER  0x9309\n#define GL_REFERENCED_BY_FRAGMENT_SHADER  0x930A\n#define GL_REFERENCED_BY_COMPUTE_SHADER   0x930B\n#define GL_TOP_LEVEL_ARRAY_SIZE           0x930C\n#define GL_TOP_LEVEL_ARRAY_STRIDE         0x930D\n#define GL_LOCATION                       0x930E\n#define GL_LOCATION_INDEX                 0x930F\n#define GL_IS_PER_PATCH                   0x92E7\n#define GL_SHADER_STORAGE_BUFFER          0x90D2\n#define GL_SHADER_STORAGE_BUFFER_BINDING  0x90D3\n#define GL_SHADER_STORAGE_BUFFER_START    0x90D4\n#define GL_SHADER_STORAGE_BUFFER_SIZE     0x90D5\n#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6\n#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7\n#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8\n#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9\n#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA\n#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB\n#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC\n#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD\n#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE  0x90DE\n#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF\n#define GL_SHADER_STORAGE_BARRIER_BIT     0x00002000\n#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39\n#define GL_DEPTH_STENCIL_TEXTURE_MODE     0x90EA\n#define GL_TEXTURE_BUFFER_OFFSET          0x919D\n#define GL_TEXTURE_BUFFER_SIZE            0x919E\n#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F\n#define GL_TEXTURE_VIEW_MIN_LEVEL         0x82DB\n#define GL_TEXTURE_VIEW_NUM_LEVELS        0x82DC\n#define GL_TEXTURE_VIEW_MIN_LAYER         0x82DD\n#define GL_TEXTURE_VIEW_NUM_LAYERS        0x82DE\n#define GL_TEXTURE_IMMUTABLE_LEVELS       0x82DF\n#define GL_VERTEX_ATTRIB_BINDING          0x82D4\n#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET  0x82D5\n#define GL_VERTEX_BINDING_DIVISOR         0x82D6\n#define GL_VERTEX_BINDING_OFFSET          0x82D7\n#define GL_VERTEX_BINDING_STRIDE          0x82D8\n#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9\n#define GL_MAX_VERTEX_ATTRIB_BINDINGS     0x82DA\n#define GL_VERTEX_BINDING_BUFFER          0x8F4F\ntypedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);\ntypedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);\ntypedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params);\ntypedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);\ntypedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params);\ntypedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);\ntypedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);\ntypedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);\ntypedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);\ntypedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);\ntypedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);\ntypedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);\ntypedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\ntypedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);\ntypedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);\ntypedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);\ntypedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);\ntypedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);\ntypedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);\nGLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect);\nGLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);\nGLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params);\nGLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level);\nGLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glInvalidateBufferData (GLuint buffer);\nGLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);\nGLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);\nGLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);\nGLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params);\nGLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name);\nGLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\nGLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);\nGLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name);\nGLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name);\nGLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);\nGLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);\nGLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\nGLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex);\nGLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor);\nGLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\nGLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\nGLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);\nGLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\nGLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);\nGLAPI void APIENTRY glPopDebugGroup (void);\nGLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);\nGLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);\nGLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);\nGLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);\n#endif\n#endif /* GL_VERSION_4_3 */\n\n#ifndef GL_VERSION_4_4\n#define GL_VERSION_4_4 1\n#define GL_MAX_VERTEX_ATTRIB_STRIDE       0x82E5\n#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221\n#define GL_TEXTURE_BUFFER_BINDING         0x8C2A\n#define GL_MAP_PERSISTENT_BIT             0x0040\n#define GL_MAP_COHERENT_BIT               0x0080\n#define GL_DYNAMIC_STORAGE_BIT            0x0100\n#define GL_CLIENT_STORAGE_BIT             0x0200\n#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000\n#define GL_BUFFER_IMMUTABLE_STORAGE       0x821F\n#define GL_BUFFER_STORAGE_FLAGS           0x8220\n#define GL_CLEAR_TEXTURE                  0x9365\n#define GL_LOCATION_COMPONENT             0x934A\n#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B\n#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C\n#define GL_QUERY_BUFFER                   0x9192\n#define GL_QUERY_BUFFER_BARRIER_BIT       0x00008000\n#define GL_QUERY_BUFFER_BINDING           0x9193\n#define GL_QUERY_RESULT_NO_WAIT           0x9194\n#define GL_MIRROR_CLAMP_TO_EDGE           0x8743\ntypedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);\ntypedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers);\ntypedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes);\ntypedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);\ntypedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers);\ntypedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);\ntypedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);\nGLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers);\nGLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes);\nGLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures);\nGLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers);\nGLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures);\nGLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\n#endif\n#endif /* GL_VERSION_4_4 */\n\n#ifndef GL_VERSION_4_5\n#define GL_VERSION_4_5 1\n#define GL_CONTEXT_LOST                   0x0507\n#define GL_NEGATIVE_ONE_TO_ONE            0x935E\n#define GL_ZERO_TO_ONE                    0x935F\n#define GL_CLIP_ORIGIN                    0x935C\n#define GL_CLIP_DEPTH_MODE                0x935D\n#define GL_QUERY_WAIT_INVERTED            0x8E17\n#define GL_QUERY_NO_WAIT_INVERTED         0x8E18\n#define GL_QUERY_BY_REGION_WAIT_INVERTED  0x8E19\n#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A\n#define GL_MAX_CULL_DISTANCES             0x82F9\n#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA\n#define GL_TEXTURE_TARGET                 0x1006\n#define GL_QUERY_TARGET                   0x82EA\n#define GL_GUILTY_CONTEXT_RESET           0x8253\n#define GL_INNOCENT_CONTEXT_RESET         0x8254\n#define GL_UNKNOWN_CONTEXT_RESET          0x8255\n#define GL_RESET_NOTIFICATION_STRATEGY    0x8256\n#define GL_LOSE_CONTEXT_ON_RESET          0x8252\n#define GL_NO_RESET_NOTIFICATION          0x8261\n#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004\n#define GL_CONTEXT_RELEASE_BEHAVIOR       0x82FB\n#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC\ntypedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth);\ntypedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);\ntypedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);\ntypedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);\ntypedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\ntypedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access);\ntypedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);\ntypedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);\ntypedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src);\ntypedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments);\ntypedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil);\ntypedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\ntypedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target);\ntypedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures);\ntypedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param);\ntypedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture);\ntypedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture);\ntypedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);\ntypedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index);\ntypedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param);\ntypedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers);\ntypedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);\ntypedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers);\ntypedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels);\ntypedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void);\ntypedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\ntypedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\ntypedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth);\nGLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids);\nGLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer);\nGLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param);\nGLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);\nGLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers);\nGLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);\nGLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);\nGLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);\nGLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\nGLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\nGLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access);\nGLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);\nGLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer);\nGLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params);\nGLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params);\nGLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);\nGLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers);\nGLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\nGLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param);\nGLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);\nGLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);\nGLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf);\nGLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs);\nGLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src);\nGLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments);\nGLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);\nGLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);\nGLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);\nGLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil);\nGLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\nGLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target);\nGLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);\nGLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers);\nGLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures);\nGLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer);\nGLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);\nGLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\nGLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param);\nGLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param);\nGLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params);\nGLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param);\nGLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture);\nGLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture);\nGLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params);\nGLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays);\nGLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index);\nGLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index);\nGLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer);\nGLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\nGLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\nGLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex);\nGLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor);\nGLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param);\nGLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers);\nGLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines);\nGLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids);\nGLAPI void APIENTRY glGetQueryBufferObjecti64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glGetQueryBufferObjectiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glGetQueryBufferObjectui64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glGetQueryBufferObjectuiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers);\nGLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels);\nGLAPI GLenum APIENTRY glGetGraphicsResetStatus (void);\nGLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\nGLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\nGLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params);\nGLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\nGLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\nGLAPI void APIENTRY glTextureBarrier (void);\n#endif\n#endif /* GL_VERSION_4_5 */\n\n#ifndef GL_ARB_ES2_compatibility\n#define GL_ARB_ES2_compatibility 1\n#endif /* GL_ARB_ES2_compatibility */\n\n#ifndef GL_ARB_ES3_1_compatibility\n#define GL_ARB_ES3_1_compatibility 1\n#endif /* GL_ARB_ES3_1_compatibility */\n\n#ifndef GL_ARB_ES3_compatibility\n#define GL_ARB_ES3_compatibility 1\n#endif /* GL_ARB_ES3_compatibility */\n\n#ifndef GL_ARB_arrays_of_arrays\n#define GL_ARB_arrays_of_arrays 1\n#endif /* GL_ARB_arrays_of_arrays */\n\n#ifndef GL_ARB_base_instance\n#define GL_ARB_base_instance 1\n#endif /* GL_ARB_base_instance */\n\n#ifndef GL_ARB_bindless_texture\n#define GL_ARB_bindless_texture 1\ntypedef uint64_t GLuint64EXT;\n#define GL_UNSIGNED_INT64_ARB             0x140F\ntypedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture);\ntypedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler);\ntypedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle);\ntypedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);\ntypedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access);\ntypedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value);\ntypedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);\ntypedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);\ntypedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture);\nGLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler);\nGLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle);\nGLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle);\nGLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);\nGLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access);\nGLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle);\nGLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value);\nGLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value);\nGLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values);\nGLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle);\nGLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle);\nGLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x);\nGLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v);\nGLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params);\n#endif\n#endif /* GL_ARB_bindless_texture */\n\n#ifndef GL_ARB_blend_func_extended\n#define GL_ARB_blend_func_extended 1\n#endif /* GL_ARB_blend_func_extended */\n\n#ifndef GL_ARB_buffer_storage\n#define GL_ARB_buffer_storage 1\n#endif /* GL_ARB_buffer_storage */\n\n#ifndef GL_ARB_cl_event\n#define GL_ARB_cl_event 1\nstruct _cl_context;\nstruct _cl_event;\n#define GL_SYNC_CL_EVENT_ARB              0x8240\n#define GL_SYNC_CL_EVENT_COMPLETE_ARB     0x8241\ntypedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags);\n#endif\n#endif /* GL_ARB_cl_event */\n\n#ifndef GL_ARB_clear_buffer_object\n#define GL_ARB_clear_buffer_object 1\n#endif /* GL_ARB_clear_buffer_object */\n\n#ifndef GL_ARB_clear_texture\n#define GL_ARB_clear_texture 1\n#endif /* GL_ARB_clear_texture */\n\n#ifndef GL_ARB_clip_control\n#define GL_ARB_clip_control 1\n#endif /* GL_ARB_clip_control */\n\n#ifndef GL_ARB_compressed_texture_pixel_storage\n#define GL_ARB_compressed_texture_pixel_storage 1\n#endif /* GL_ARB_compressed_texture_pixel_storage */\n\n#ifndef GL_ARB_compute_shader\n#define GL_ARB_compute_shader 1\n#endif /* GL_ARB_compute_shader */\n\n#ifndef GL_ARB_compute_variable_group_size\n#define GL_ARB_compute_variable_group_size 1\n#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344\n#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB\n#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345\n#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF\ntypedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z);\n#endif\n#endif /* GL_ARB_compute_variable_group_size */\n\n#ifndef GL_ARB_conditional_render_inverted\n#define GL_ARB_conditional_render_inverted 1\n#endif /* GL_ARB_conditional_render_inverted */\n\n#ifndef GL_ARB_conservative_depth\n#define GL_ARB_conservative_depth 1\n#endif /* GL_ARB_conservative_depth */\n\n#ifndef GL_ARB_copy_buffer\n#define GL_ARB_copy_buffer 1\n#endif /* GL_ARB_copy_buffer */\n\n#ifndef GL_ARB_copy_image\n#define GL_ARB_copy_image 1\n#endif /* GL_ARB_copy_image */\n\n#ifndef GL_ARB_cull_distance\n#define GL_ARB_cull_distance 1\n#endif /* GL_ARB_cull_distance */\n\n#ifndef GL_ARB_debug_output\n#define GL_ARB_debug_output 1\ntypedef void (APIENTRY  *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);\n#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB   0x8242\n#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243\n#define GL_DEBUG_CALLBACK_FUNCTION_ARB    0x8244\n#define GL_DEBUG_CALLBACK_USER_PARAM_ARB  0x8245\n#define GL_DEBUG_SOURCE_API_ARB           0x8246\n#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247\n#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248\n#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB   0x8249\n#define GL_DEBUG_SOURCE_APPLICATION_ARB   0x824A\n#define GL_DEBUG_SOURCE_OTHER_ARB         0x824B\n#define GL_DEBUG_TYPE_ERROR_ARB           0x824C\n#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D\n#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E\n#define GL_DEBUG_TYPE_PORTABILITY_ARB     0x824F\n#define GL_DEBUG_TYPE_PERFORMANCE_ARB     0x8250\n#define GL_DEBUG_TYPE_OTHER_ARB           0x8251\n#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB   0x9143\n#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB  0x9144\n#define GL_DEBUG_LOGGED_MESSAGES_ARB      0x9145\n#define GL_DEBUG_SEVERITY_HIGH_ARB        0x9146\n#define GL_DEBUG_SEVERITY_MEDIUM_ARB      0x9147\n#define GL_DEBUG_SEVERITY_LOW_ARB         0x9148\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam);\ntypedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\nGLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\nGLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam);\nGLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\n#endif\n#endif /* GL_ARB_debug_output */\n\n#ifndef GL_ARB_depth_buffer_float\n#define GL_ARB_depth_buffer_float 1\n#endif /* GL_ARB_depth_buffer_float */\n\n#ifndef GL_ARB_depth_clamp\n#define GL_ARB_depth_clamp 1\n#endif /* GL_ARB_depth_clamp */\n\n#ifndef GL_ARB_derivative_control\n#define GL_ARB_derivative_control 1\n#endif /* GL_ARB_derivative_control */\n\n#ifndef GL_ARB_direct_state_access\n#define GL_ARB_direct_state_access 1\n#endif /* GL_ARB_direct_state_access */\n\n#ifndef GL_ARB_draw_buffers_blend\n#define GL_ARB_draw_buffers_blend 1\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\ntypedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);\ntypedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode);\nGLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\nGLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst);\nGLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\n#endif\n#endif /* GL_ARB_draw_buffers_blend */\n\n#ifndef GL_ARB_draw_elements_base_vertex\n#define GL_ARB_draw_elements_base_vertex 1\n#endif /* GL_ARB_draw_elements_base_vertex */\n\n#ifndef GL_ARB_draw_indirect\n#define GL_ARB_draw_indirect 1\n#endif /* GL_ARB_draw_indirect */\n\n#ifndef GL_ARB_enhanced_layouts\n#define GL_ARB_enhanced_layouts 1\n#endif /* GL_ARB_enhanced_layouts */\n\n#ifndef GL_ARB_explicit_attrib_location\n#define GL_ARB_explicit_attrib_location 1\n#endif /* GL_ARB_explicit_attrib_location */\n\n#ifndef GL_ARB_explicit_uniform_location\n#define GL_ARB_explicit_uniform_location 1\n#endif /* GL_ARB_explicit_uniform_location */\n\n#ifndef GL_ARB_fragment_coord_conventions\n#define GL_ARB_fragment_coord_conventions 1\n#endif /* GL_ARB_fragment_coord_conventions */\n\n#ifndef GL_ARB_fragment_layer_viewport\n#define GL_ARB_fragment_layer_viewport 1\n#endif /* GL_ARB_fragment_layer_viewport */\n\n#ifndef GL_ARB_framebuffer_no_attachments\n#define GL_ARB_framebuffer_no_attachments 1\n#endif /* GL_ARB_framebuffer_no_attachments */\n\n#ifndef GL_ARB_framebuffer_object\n#define GL_ARB_framebuffer_object 1\n#endif /* GL_ARB_framebuffer_object */\n\n#ifndef GL_ARB_framebuffer_sRGB\n#define GL_ARB_framebuffer_sRGB 1\n#endif /* GL_ARB_framebuffer_sRGB */\n\n#ifndef GL_ARB_get_program_binary\n#define GL_ARB_get_program_binary 1\n#endif /* GL_ARB_get_program_binary */\n\n#ifndef GL_ARB_get_texture_sub_image\n#define GL_ARB_get_texture_sub_image 1\n#endif /* GL_ARB_get_texture_sub_image */\n\n#ifndef GL_ARB_gpu_shader5\n#define GL_ARB_gpu_shader5 1\n#endif /* GL_ARB_gpu_shader5 */\n\n#ifndef GL_ARB_gpu_shader_fp64\n#define GL_ARB_gpu_shader_fp64 1\n#endif /* GL_ARB_gpu_shader_fp64 */\n\n#ifndef GL_ARB_half_float_vertex\n#define GL_ARB_half_float_vertex 1\n#endif /* GL_ARB_half_float_vertex */\n\n#ifndef GL_ARB_imaging\n#define GL_ARB_imaging 1\n#define GL_BLEND_COLOR                    0x8005\n#define GL_BLEND_EQUATION                 0x8009\n#endif /* GL_ARB_imaging */\n\n#ifndef GL_ARB_indirect_parameters\n#define GL_ARB_indirect_parameters 1\n#define GL_PARAMETER_BUFFER_ARB           0x80EE\n#define GL_PARAMETER_BUFFER_BINDING_ARB   0x80EF\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\nGLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\n#endif\n#endif /* GL_ARB_indirect_parameters */\n\n#ifndef GL_ARB_internalformat_query\n#define GL_ARB_internalformat_query 1\n#endif /* GL_ARB_internalformat_query */\n\n#ifndef GL_ARB_internalformat_query2\n#define GL_ARB_internalformat_query2 1\n#define GL_SRGB_DECODE_ARB                0x8299\n#endif /* GL_ARB_internalformat_query2 */\n\n#ifndef GL_ARB_invalidate_subdata\n#define GL_ARB_invalidate_subdata 1\n#endif /* GL_ARB_invalidate_subdata */\n\n#ifndef GL_ARB_map_buffer_alignment\n#define GL_ARB_map_buffer_alignment 1\n#endif /* GL_ARB_map_buffer_alignment */\n\n#ifndef GL_ARB_map_buffer_range\n#define GL_ARB_map_buffer_range 1\n#endif /* GL_ARB_map_buffer_range */\n\n#ifndef GL_ARB_multi_bind\n#define GL_ARB_multi_bind 1\n#endif /* GL_ARB_multi_bind */\n\n#ifndef GL_ARB_multi_draw_indirect\n#define GL_ARB_multi_draw_indirect 1\n#endif /* GL_ARB_multi_draw_indirect */\n\n#ifndef GL_ARB_occlusion_query2\n#define GL_ARB_occlusion_query2 1\n#endif /* GL_ARB_occlusion_query2 */\n\n#ifndef GL_ARB_pipeline_statistics_query\n#define GL_ARB_pipeline_statistics_query 1\n#define GL_VERTICES_SUBMITTED_ARB         0x82EE\n#define GL_PRIMITIVES_SUBMITTED_ARB       0x82EF\n#define GL_VERTEX_SHADER_INVOCATIONS_ARB  0x82F0\n#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1\n#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2\n#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3\n#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4\n#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5\n#define GL_CLIPPING_INPUT_PRIMITIVES_ARB  0x82F6\n#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7\n#endif /* GL_ARB_pipeline_statistics_query */\n\n#ifndef GL_ARB_program_interface_query\n#define GL_ARB_program_interface_query 1\n#endif /* GL_ARB_program_interface_query */\n\n#ifndef GL_ARB_provoking_vertex\n#define GL_ARB_provoking_vertex 1\n#endif /* GL_ARB_provoking_vertex */\n\n#ifndef GL_ARB_query_buffer_object\n#define GL_ARB_query_buffer_object 1\n#endif /* GL_ARB_query_buffer_object */\n\n#ifndef GL_ARB_robust_buffer_access_behavior\n#define GL_ARB_robust_buffer_access_behavior 1\n#endif /* GL_ARB_robust_buffer_access_behavior */\n\n#ifndef GL_ARB_robustness\n#define GL_ARB_robustness 1\n#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004\n#define GL_LOSE_CONTEXT_ON_RESET_ARB      0x8252\n#define GL_GUILTY_CONTEXT_RESET_ARB       0x8253\n#define GL_INNOCENT_CONTEXT_RESET_ARB     0x8254\n#define GL_UNKNOWN_CONTEXT_RESET_ARB      0x8255\n#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256\n#define GL_NO_RESET_NOTIFICATION_ARB      0x8261\ntypedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);\ntypedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img);\ntypedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\ntypedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void);\nGLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img);\nGLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\nGLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img);\nGLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\nGLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params);\nGLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\nGLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\n#endif\n#endif /* GL_ARB_robustness */\n\n#ifndef GL_ARB_robustness_isolation\n#define GL_ARB_robustness_isolation 1\n#endif /* GL_ARB_robustness_isolation */\n\n#ifndef GL_ARB_sample_shading\n#define GL_ARB_sample_shading 1\n#define GL_SAMPLE_SHADING_ARB             0x8C36\n#define GL_MIN_SAMPLE_SHADING_VALUE_ARB   0x8C37\ntypedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMinSampleShadingARB (GLfloat value);\n#endif\n#endif /* GL_ARB_sample_shading */\n\n#ifndef GL_ARB_sampler_objects\n#define GL_ARB_sampler_objects 1\n#endif /* GL_ARB_sampler_objects */\n\n#ifndef GL_ARB_seamless_cube_map\n#define GL_ARB_seamless_cube_map 1\n#endif /* GL_ARB_seamless_cube_map */\n\n#ifndef GL_ARB_seamless_cubemap_per_texture\n#define GL_ARB_seamless_cubemap_per_texture 1\n#endif /* GL_ARB_seamless_cubemap_per_texture */\n\n#ifndef GL_ARB_separate_shader_objects\n#define GL_ARB_separate_shader_objects 1\n#endif /* GL_ARB_separate_shader_objects */\n\n#ifndef GL_ARB_shader_atomic_counters\n#define GL_ARB_shader_atomic_counters 1\n#endif /* GL_ARB_shader_atomic_counters */\n\n#ifndef GL_ARB_shader_bit_encoding\n#define GL_ARB_shader_bit_encoding 1\n#endif /* GL_ARB_shader_bit_encoding */\n\n#ifndef GL_ARB_shader_draw_parameters\n#define GL_ARB_shader_draw_parameters 1\n#endif /* GL_ARB_shader_draw_parameters */\n\n#ifndef GL_ARB_shader_group_vote\n#define GL_ARB_shader_group_vote 1\n#endif /* GL_ARB_shader_group_vote */\n\n#ifndef GL_ARB_shader_image_load_store\n#define GL_ARB_shader_image_load_store 1\n#endif /* GL_ARB_shader_image_load_store */\n\n#ifndef GL_ARB_shader_image_size\n#define GL_ARB_shader_image_size 1\n#endif /* GL_ARB_shader_image_size */\n\n#ifndef GL_ARB_shader_precision\n#define GL_ARB_shader_precision 1\n#endif /* GL_ARB_shader_precision */\n\n#ifndef GL_ARB_shader_stencil_export\n#define GL_ARB_shader_stencil_export 1\n#endif /* GL_ARB_shader_stencil_export */\n\n#ifndef GL_ARB_shader_storage_buffer_object\n#define GL_ARB_shader_storage_buffer_object 1\n#endif /* GL_ARB_shader_storage_buffer_object */\n\n#ifndef GL_ARB_shader_subroutine\n#define GL_ARB_shader_subroutine 1\n#endif /* GL_ARB_shader_subroutine */\n\n#ifndef GL_ARB_shader_texture_image_samples\n#define GL_ARB_shader_texture_image_samples 1\n#endif /* GL_ARB_shader_texture_image_samples */\n\n#ifndef GL_ARB_shading_language_420pack\n#define GL_ARB_shading_language_420pack 1\n#endif /* GL_ARB_shading_language_420pack */\n\n#ifndef GL_ARB_shading_language_include\n#define GL_ARB_shading_language_include 1\n#define GL_SHADER_INCLUDE_ARB             0x8DAE\n#define GL_NAMED_STRING_LENGTH_ARB        0x8DE9\n#define GL_NAMED_STRING_TYPE_ARB          0x8DEA\ntypedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);\ntypedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);\ntypedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length);\ntypedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);\ntypedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);\nGLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name);\nGLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length);\nGLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name);\nGLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);\nGLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params);\n#endif\n#endif /* GL_ARB_shading_language_include */\n\n#ifndef GL_ARB_shading_language_packing\n#define GL_ARB_shading_language_packing 1\n#endif /* GL_ARB_shading_language_packing */\n\n#ifndef GL_ARB_sparse_buffer\n#define GL_ARB_sparse_buffer 1\n#define GL_SPARSE_STORAGE_BIT_ARB         0x0400\n#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB    0x82F8\ntypedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit);\nGLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\nGLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\n#endif\n#endif /* GL_ARB_sparse_buffer */\n\n#ifndef GL_ARB_sparse_texture\n#define GL_ARB_sparse_texture 1\n#define GL_TEXTURE_SPARSE_ARB             0x91A6\n#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB    0x91A7\n#define GL_NUM_SPARSE_LEVELS_ARB          0x91AA\n#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB     0x91A8\n#define GL_VIRTUAL_PAGE_SIZE_X_ARB        0x9195\n#define GL_VIRTUAL_PAGE_SIZE_Y_ARB        0x9196\n#define GL_VIRTUAL_PAGE_SIZE_Z_ARB        0x9197\n#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB    0x9198\n#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199\n#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A\n#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9\ntypedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);\n#endif\n#endif /* GL_ARB_sparse_texture */\n\n#ifndef GL_ARB_stencil_texturing\n#define GL_ARB_stencil_texturing 1\n#endif /* GL_ARB_stencil_texturing */\n\n#ifndef GL_ARB_sync\n#define GL_ARB_sync 1\n#endif /* GL_ARB_sync */\n\n#ifndef GL_ARB_tessellation_shader\n#define GL_ARB_tessellation_shader 1\n#endif /* GL_ARB_tessellation_shader */\n\n#ifndef GL_ARB_texture_barrier\n#define GL_ARB_texture_barrier 1\n#endif /* GL_ARB_texture_barrier */\n\n#ifndef GL_ARB_texture_buffer_object_rgb32\n#define GL_ARB_texture_buffer_object_rgb32 1\n#endif /* GL_ARB_texture_buffer_object_rgb32 */\n\n#ifndef GL_ARB_texture_buffer_range\n#define GL_ARB_texture_buffer_range 1\n#endif /* GL_ARB_texture_buffer_range */\n\n#ifndef GL_ARB_texture_compression_bptc\n#define GL_ARB_texture_compression_bptc 1\n#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C\n#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D\n#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E\n#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F\n#endif /* GL_ARB_texture_compression_bptc */\n\n#ifndef GL_ARB_texture_compression_rgtc\n#define GL_ARB_texture_compression_rgtc 1\n#endif /* GL_ARB_texture_compression_rgtc */\n\n#ifndef GL_ARB_texture_cube_map_array\n#define GL_ARB_texture_cube_map_array 1\n#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB     0x9009\n#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A\n#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B\n#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB     0x900C\n#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D\n#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E\n#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F\n#endif /* GL_ARB_texture_cube_map_array */\n\n#ifndef GL_ARB_texture_gather\n#define GL_ARB_texture_gather 1\n#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E\n#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F\n#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F\n#endif /* GL_ARB_texture_gather */\n\n#ifndef GL_ARB_texture_mirror_clamp_to_edge\n#define GL_ARB_texture_mirror_clamp_to_edge 1\n#endif /* GL_ARB_texture_mirror_clamp_to_edge */\n\n#ifndef GL_ARB_texture_multisample\n#define GL_ARB_texture_multisample 1\n#endif /* GL_ARB_texture_multisample */\n\n#ifndef GL_ARB_texture_query_levels\n#define GL_ARB_texture_query_levels 1\n#endif /* GL_ARB_texture_query_levels */\n\n#ifndef GL_ARB_texture_query_lod\n#define GL_ARB_texture_query_lod 1\n#endif /* GL_ARB_texture_query_lod */\n\n#ifndef GL_ARB_texture_rg\n#define GL_ARB_texture_rg 1\n#endif /* GL_ARB_texture_rg */\n\n#ifndef GL_ARB_texture_rgb10_a2ui\n#define GL_ARB_texture_rgb10_a2ui 1\n#endif /* GL_ARB_texture_rgb10_a2ui */\n\n#ifndef GL_ARB_texture_stencil8\n#define GL_ARB_texture_stencil8 1\n#endif /* GL_ARB_texture_stencil8 */\n\n#ifndef GL_ARB_texture_storage\n#define GL_ARB_texture_storage 1\n#endif /* GL_ARB_texture_storage */\n\n#ifndef GL_ARB_texture_storage_multisample\n#define GL_ARB_texture_storage_multisample 1\n#endif /* GL_ARB_texture_storage_multisample */\n\n#ifndef GL_ARB_texture_swizzle\n#define GL_ARB_texture_swizzle 1\n#endif /* GL_ARB_texture_swizzle */\n\n#ifndef GL_ARB_texture_view\n#define GL_ARB_texture_view 1\n#endif /* GL_ARB_texture_view */\n\n#ifndef GL_ARB_timer_query\n#define GL_ARB_timer_query 1\n#endif /* GL_ARB_timer_query */\n\n#ifndef GL_ARB_transform_feedback2\n#define GL_ARB_transform_feedback2 1\n#endif /* GL_ARB_transform_feedback2 */\n\n#ifndef GL_ARB_transform_feedback3\n#define GL_ARB_transform_feedback3 1\n#endif /* GL_ARB_transform_feedback3 */\n\n#ifndef GL_ARB_transform_feedback_instanced\n#define GL_ARB_transform_feedback_instanced 1\n#endif /* GL_ARB_transform_feedback_instanced */\n\n#ifndef GL_ARB_transform_feedback_overflow_query\n#define GL_ARB_transform_feedback_overflow_query 1\n#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC\n#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED\n#endif /* GL_ARB_transform_feedback_overflow_query */\n\n#ifndef GL_ARB_uniform_buffer_object\n#define GL_ARB_uniform_buffer_object 1\n#endif /* GL_ARB_uniform_buffer_object */\n\n#ifndef GL_ARB_vertex_array_bgra\n#define GL_ARB_vertex_array_bgra 1\n#endif /* GL_ARB_vertex_array_bgra */\n\n#ifndef GL_ARB_vertex_array_object\n#define GL_ARB_vertex_array_object 1\n#endif /* GL_ARB_vertex_array_object */\n\n#ifndef GL_ARB_vertex_attrib_64bit\n#define GL_ARB_vertex_attrib_64bit 1\n#endif /* GL_ARB_vertex_attrib_64bit */\n\n#ifndef GL_ARB_vertex_attrib_binding\n#define GL_ARB_vertex_attrib_binding 1\n#endif /* GL_ARB_vertex_attrib_binding */\n\n#ifndef GL_ARB_vertex_type_10f_11f_11f_rev\n#define GL_ARB_vertex_type_10f_11f_11f_rev 1\n#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */\n\n#ifndef GL_ARB_vertex_type_2_10_10_10_rev\n#define GL_ARB_vertex_type_2_10_10_10_rev 1\n#endif /* GL_ARB_vertex_type_2_10_10_10_rev */\n\n#ifndef GL_ARB_viewport_array\n#define GL_ARB_viewport_array 1\n#endif /* GL_ARB_viewport_array */\n\n#ifndef GL_KHR_context_flush_control\n#define GL_KHR_context_flush_control 1\n#endif /* GL_KHR_context_flush_control */\n\n#ifndef GL_KHR_debug\n#define GL_KHR_debug 1\n#endif /* GL_KHR_debug */\n\n#ifndef GL_KHR_no_error\n#define GL_KHR_no_error 1\n#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR  0x00000008\n#endif /* GL_KHR_no_error */\n\n#ifndef GL_KHR_robust_buffer_access_behavior\n#define GL_KHR_robust_buffer_access_behavior 1\n#endif /* GL_KHR_robust_buffer_access_behavior */\n\n#ifndef GL_KHR_robustness\n#define GL_KHR_robustness 1\n#define GL_CONTEXT_ROBUST_ACCESS          0x90F3\n#endif /* GL_KHR_robustness */\n\n#ifndef GL_KHR_texture_compression_astc_hdr\n#define GL_KHR_texture_compression_astc_hdr 1\n#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR   0x93B0\n#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR   0x93B1\n#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR   0x93B2\n#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR   0x93B3\n#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR   0x93B4\n#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR   0x93B5\n#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR   0x93B6\n#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR   0x93B7\n#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR  0x93B8\n#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR  0x93B9\n#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR  0x93BA\n#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB\n#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC\n#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD\n#endif /* GL_KHR_texture_compression_astc_hdr */\n\n#ifndef GL_KHR_texture_compression_astc_ldr\n#define GL_KHR_texture_compression_astc_ldr 1\n#endif /* GL_KHR_texture_compression_astc_ldr */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/gl3w/src/gl3w.cpp",
    "content": "/*\n\n    This file was generated with gl3w_gen.py, part of gl3w\n    (hosted at https://github.com/skaslev/gl3w)\n\n    This is free and unencumbered software released into the public domain.\n\n    Anyone is free to copy, modify, publish, use, compile, sell, or\n    distribute this software, either in source code form or as a compiled\n    binary, for any purpose, commercial or non-commercial, and by any\n    means.\n\n    In jurisdictions that recognize copyright laws, the author or authors\n    of this software dedicate any and all copyright interest in the\n    software to the public domain. We make this dedication for the benefit\n    of the public at large and to the detriment of our heirs and\n    successors. We intend this dedication to be an overt act of\n    relinquishment in perpetuity of all present and future rights to this\n    software under copyright law.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n    IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n    OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n#include <GL/gl3w.h>\n\n/* --------------------------------------------------------------------------------------------- */\n\n#ifdef _WIN32\n\n/* ------------------------------------\n * Windows\n * ------------------------------------ */\n\n#define WIN32_LEAN_AND_MEAN 1\n#include <windows.h>\n\nstatic HMODULE gl3w_libgl = NULL;\n\nstatic int gl3w_open_libgl(void)\n{\n    if (!gl3w_libgl)\n    {\n        gl3w_libgl = LoadLibraryA(\"opengl32.dll\");\n    }\n\n    return gl3w_libgl != NULL;\n}\n\nstatic void gl3w_close_libgl(void)\n{\n    if (gl3w_libgl)\n    {\n        FreeLibrary(gl3w_libgl);\n        gl3w_libgl = NULL;\n    }\n}\n\nstatic GL3WglProc gl3w_fn(const char *proc)\n{\n    GL3WglProc res;\n    res = (GL3WglProc) wglGetProcAddress(proc);\n\n    if (!res)\n    {\n        res = (GL3WglProc) GetProcAddress(gl3w_libgl, proc);\n    }\n\n    return res;\n}\n\n#elif defined(__APPLE__) || defined(__APPLE_CC__)\n\n/* ------------------------------------\n * Mac OS\n * ------------------------------------ */\n\n#include <Carbon/Carbon.h>\n\nstatic CFBundleRef gl3w_cfBundle = NULL;\nstatic CFURLRef gl3w_cfBundleURL = NULL;\n\nstatic int gl3w_open_libgl(void)\n{\n    if (gl3w_cfBundle)\n    {\n        return 1; /* Already init */\n    }\n\n    gl3w_cfBundleURL = CFURLCreateWithFileSystemPath(\n                            kCFAllocatorDefault,\n                            CFSTR(\"/System/Library/Frameworks/OpenGL.framework\"),\n                            kCFURLPOSIXPathStyle, true);\n    if (!gl3w_cfBundleURL)\n    {\n        return 0;\n    }\n\n    gl3w_cfBundle = CFBundleCreate(kCFAllocatorDefault, gl3w_cfBundleURL);\n    if (!gl3w_cfBundle)\n    {\n        CFRelease(gl3w_cfBundleURL);\n        return 0;\n    }\n\n    return 1;\n}\n\nstatic void gl3w_close_libgl(void)\n{\n    if (gl3w_cfBundle)\n    {\n        CFRelease(gl3w_cfBundle);\n        gl3w_cfBundle = NULL;\n    }\n    if (gl3w_cfBundleURL)\n    {\n        CFRelease(gl3w_cfBundleURL);\n        gl3w_cfBundleURL = NULL;\n    }\n}\n\nstatic GL3WglProc gl3w_fn(const char *proc)\n{\n    GL3WglProc res;\n    CFStringRef procName;\n\n    procName = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII);\n    res = (GL3WglProc) CFBundleGetFunctionPointerForName(gl3w_cfBundle, procName);\n    CFRelease(procName);\n\n    return res;\n}\n\n#else\n\n/* ------------------------------------\n * GLX\n * ------------------------------------ */\n\n#include <dlfcn.h>\n#include <GL/glx.h>\n\nstatic void *gl3w_libgl = NULL;\n\nstatic int gl3w_open_libgl(void)\n{\n    if (!gl3w_libgl)\n    {\n        gl3w_libgl = dlopen(\"libGL.so.1\", RTLD_LAZY | RTLD_GLOBAL);\n    }\n\n    return gl3w_libgl != NULL;\n}\n\nstatic void gl3w_close_libgl(void)\n{\n    if (gl3w_libgl)\n    {\n        dlclose(gl3w_libgl);\n        gl3w_libgl = NULL;\n    }\n}\n\nstatic GL3WglProc gl3w_fn(const char *proc)\n{\n    GL3WglProc res;\n    res = (GL3WglProc) glXGetProcAddress((const GLubyte *) proc);\n\n    if (!res)\n    {\n        res = (GL3WglProc) dlsym(gl3w_libgl, proc);\n    }\n\n    return res;\n}\n\n#endif\n\n/* ------------------------------------\n * GL3W API\n * ------------------------------------ */\n\nstatic struct {\n\tint major, minor;\n} gl3w_version;\n\nstatic void gl3w_load_all_functions(void);\n\nstatic int gl3w_parse_version(void)\n{\n    if (!glGetIntegerv)\n    {\n        return 0;\n    }\n\n    glGetIntegerv(GL_MAJOR_VERSION, &gl3w_version.major);\n    glGetIntegerv(GL_MINOR_VERSION, &gl3w_version.minor);\n\n    if (gl3w_version.major < 3)\n    {\n        return 0;\n    }\n\n    return 1;\n}\n\nint gl3wInit(void)\n{\n    if (!gl3w_open_libgl())\n    {\n        return 0;\n    }\n\n    gl3w_load_all_functions();\n    return gl3w_parse_version();\n}\n\nvoid gl3wShutdown(void)\n{\n    gl3w_close_libgl();\n}\n\nint gl3wIsSupported(int major, int minor)\n{\n    if (major < 3)\n    {\n        return 0;\n    }\n    if (gl3w_version.major == major)\n    {\n        return gl3w_version.minor >= minor;\n    }\n    return gl3w_version.major >= major;\n}\n\nGL3WglProc gl3wGetProcAddress(const char *proc)\n{\n    if (!proc)\n    {\n        return NULL;\n    }\n    return gl3w_fn(proc);\n}\n\n/* --------------------------------------------------------------------------------------------- */\n\nPFNGLACTIVESHADERPROGRAMPROC                         gl3wActiveShaderProgram;\nPFNGLACTIVETEXTUREPROC                               gl3wActiveTexture;\nPFNGLATTACHSHADERPROC                                gl3wAttachShader;\nPFNGLBEGINCONDITIONALRENDERPROC                      gl3wBeginConditionalRender;\nPFNGLBEGINQUERYPROC                                  gl3wBeginQuery;\nPFNGLBEGINQUERYINDEXEDPROC                           gl3wBeginQueryIndexed;\nPFNGLBEGINTRANSFORMFEEDBACKPROC                      gl3wBeginTransformFeedback;\nPFNGLBINDATTRIBLOCATIONPROC                          gl3wBindAttribLocation;\nPFNGLBINDBUFFERPROC                                  gl3wBindBuffer;\nPFNGLBINDBUFFERBASEPROC                              gl3wBindBufferBase;\nPFNGLBINDBUFFERRANGEPROC                             gl3wBindBufferRange;\nPFNGLBINDBUFFERSBASEPROC                             gl3wBindBuffersBase;\nPFNGLBINDBUFFERSRANGEPROC                            gl3wBindBuffersRange;\nPFNGLBINDFRAGDATALOCATIONPROC                        gl3wBindFragDataLocation;\nPFNGLBINDFRAGDATALOCATIONINDEXEDPROC                 gl3wBindFragDataLocationIndexed;\nPFNGLBINDFRAMEBUFFERPROC                             gl3wBindFramebuffer;\nPFNGLBINDIMAGETEXTUREPROC                            gl3wBindImageTexture;\nPFNGLBINDIMAGETEXTURESPROC                           gl3wBindImageTextures;\nPFNGLBINDPROGRAMPIPELINEPROC                         gl3wBindProgramPipeline;\nPFNGLBINDRENDERBUFFERPROC                            gl3wBindRenderbuffer;\nPFNGLBINDSAMPLERPROC                                 gl3wBindSampler;\nPFNGLBINDSAMPLERSPROC                                gl3wBindSamplers;\nPFNGLBINDTEXTUREPROC                                 gl3wBindTexture;\nPFNGLBINDTEXTUREUNITPROC                             gl3wBindTextureUnit;\nPFNGLBINDTEXTURESPROC                                gl3wBindTextures;\nPFNGLBINDTRANSFORMFEEDBACKPROC                       gl3wBindTransformFeedback;\nPFNGLBINDVERTEXARRAYPROC                             gl3wBindVertexArray;\nPFNGLBINDVERTEXBUFFERPROC                            gl3wBindVertexBuffer;\nPFNGLBINDVERTEXBUFFERSPROC                           gl3wBindVertexBuffers;\nPFNGLBLENDCOLORPROC                                  gl3wBlendColor;\nPFNGLBLENDEQUATIONPROC                               gl3wBlendEquation;\nPFNGLBLENDEQUATIONSEPARATEPROC                       gl3wBlendEquationSeparate;\nPFNGLBLENDEQUATIONSEPARATEIPROC                      gl3wBlendEquationSeparatei;\nPFNGLBLENDEQUATIONSEPARATEIARBPROC                   gl3wBlendEquationSeparateiARB;\nPFNGLBLENDEQUATIONIPROC                              gl3wBlendEquationi;\nPFNGLBLENDEQUATIONIARBPROC                           gl3wBlendEquationiARB;\nPFNGLBLENDFUNCPROC                                   gl3wBlendFunc;\nPFNGLBLENDFUNCSEPARATEPROC                           gl3wBlendFuncSeparate;\nPFNGLBLENDFUNCSEPARATEIPROC                          gl3wBlendFuncSeparatei;\nPFNGLBLENDFUNCSEPARATEIARBPROC                       gl3wBlendFuncSeparateiARB;\nPFNGLBLENDFUNCIPROC                                  gl3wBlendFunci;\nPFNGLBLENDFUNCIARBPROC                               gl3wBlendFunciARB;\nPFNGLBLITFRAMEBUFFERPROC                             gl3wBlitFramebuffer;\nPFNGLBLITNAMEDFRAMEBUFFERPROC                        gl3wBlitNamedFramebuffer;\nPFNGLBUFFERDATAPROC                                  gl3wBufferData;\nPFNGLBUFFERPAGECOMMITMENTARBPROC                     gl3wBufferPageCommitmentARB;\nPFNGLBUFFERSTORAGEPROC                               gl3wBufferStorage;\nPFNGLBUFFERSUBDATAPROC                               gl3wBufferSubData;\nPFNGLCHECKFRAMEBUFFERSTATUSPROC                      gl3wCheckFramebufferStatus;\nPFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC                 gl3wCheckNamedFramebufferStatus;\nPFNGLCLAMPCOLORPROC                                  gl3wClampColor;\nPFNGLCLEARPROC                                       gl3wClear;\nPFNGLCLEARBUFFERDATAPROC                             gl3wClearBufferData;\nPFNGLCLEARBUFFERSUBDATAPROC                          gl3wClearBufferSubData;\nPFNGLCLEARBUFFERFIPROC                               gl3wClearBufferfi;\nPFNGLCLEARBUFFERFVPROC                               gl3wClearBufferfv;\nPFNGLCLEARBUFFERIVPROC                               gl3wClearBufferiv;\nPFNGLCLEARBUFFERUIVPROC                              gl3wClearBufferuiv;\nPFNGLCLEARCOLORPROC                                  gl3wClearColor;\nPFNGLCLEARDEPTHPROC                                  gl3wClearDepth;\nPFNGLCLEARDEPTHFPROC                                 gl3wClearDepthf;\nPFNGLCLEARNAMEDBUFFERDATAPROC                        gl3wClearNamedBufferData;\nPFNGLCLEARNAMEDBUFFERSUBDATAPROC                     gl3wClearNamedBufferSubData;\nPFNGLCLEARNAMEDFRAMEBUFFERFIPROC                     gl3wClearNamedFramebufferfi;\nPFNGLCLEARNAMEDFRAMEBUFFERFVPROC                     gl3wClearNamedFramebufferfv;\nPFNGLCLEARNAMEDFRAMEBUFFERIVPROC                     gl3wClearNamedFramebufferiv;\nPFNGLCLEARNAMEDFRAMEBUFFERUIVPROC                    gl3wClearNamedFramebufferuiv;\nPFNGLCLEARSTENCILPROC                                gl3wClearStencil;\nPFNGLCLEARTEXIMAGEPROC                               gl3wClearTexImage;\nPFNGLCLEARTEXSUBIMAGEPROC                            gl3wClearTexSubImage;\nPFNGLCLIENTWAITSYNCPROC                              gl3wClientWaitSync;\nPFNGLCLIPCONTROLPROC                                 gl3wClipControl;\nPFNGLCOLORMASKPROC                                   gl3wColorMask;\nPFNGLCOLORMASKIPROC                                  gl3wColorMaski;\nPFNGLCOMPILESHADERPROC                               gl3wCompileShader;\nPFNGLCOMPILESHADERINCLUDEARBPROC                     gl3wCompileShaderIncludeARB;\nPFNGLCOMPRESSEDTEXIMAGE1DPROC                        gl3wCompressedTexImage1D;\nPFNGLCOMPRESSEDTEXIMAGE2DPROC                        gl3wCompressedTexImage2D;\nPFNGLCOMPRESSEDTEXIMAGE3DPROC                        gl3wCompressedTexImage3D;\nPFNGLCOMPRESSEDTEXSUBIMAGE1DPROC                     gl3wCompressedTexSubImage1D;\nPFNGLCOMPRESSEDTEXSUBIMAGE2DPROC                     gl3wCompressedTexSubImage2D;\nPFNGLCOMPRESSEDTEXSUBIMAGE3DPROC                     gl3wCompressedTexSubImage3D;\nPFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC                 gl3wCompressedTextureSubImage1D;\nPFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC                 gl3wCompressedTextureSubImage2D;\nPFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC                 gl3wCompressedTextureSubImage3D;\nPFNGLCOPYBUFFERSUBDATAPROC                           gl3wCopyBufferSubData;\nPFNGLCOPYIMAGESUBDATAPROC                            gl3wCopyImageSubData;\nPFNGLCOPYNAMEDBUFFERSUBDATAPROC                      gl3wCopyNamedBufferSubData;\nPFNGLCOPYTEXIMAGE1DPROC                              gl3wCopyTexImage1D;\nPFNGLCOPYTEXIMAGE2DPROC                              gl3wCopyTexImage2D;\nPFNGLCOPYTEXSUBIMAGE1DPROC                           gl3wCopyTexSubImage1D;\nPFNGLCOPYTEXSUBIMAGE2DPROC                           gl3wCopyTexSubImage2D;\nPFNGLCOPYTEXSUBIMAGE3DPROC                           gl3wCopyTexSubImage3D;\nPFNGLCOPYTEXTURESUBIMAGE1DPROC                       gl3wCopyTextureSubImage1D;\nPFNGLCOPYTEXTURESUBIMAGE2DPROC                       gl3wCopyTextureSubImage2D;\nPFNGLCOPYTEXTURESUBIMAGE3DPROC                       gl3wCopyTextureSubImage3D;\nPFNGLCREATEBUFFERSPROC                               gl3wCreateBuffers;\nPFNGLCREATEFRAMEBUFFERSPROC                          gl3wCreateFramebuffers;\nPFNGLCREATEPROGRAMPROC                               gl3wCreateProgram;\nPFNGLCREATEPROGRAMPIPELINESPROC                      gl3wCreateProgramPipelines;\nPFNGLCREATEQUERIESPROC                               gl3wCreateQueries;\nPFNGLCREATERENDERBUFFERSPROC                         gl3wCreateRenderbuffers;\nPFNGLCREATESAMPLERSPROC                              gl3wCreateSamplers;\nPFNGLCREATESHADERPROC                                gl3wCreateShader;\nPFNGLCREATESHADERPROGRAMVPROC                        gl3wCreateShaderProgramv;\nPFNGLCREATESYNCFROMCLEVENTARBPROC                    gl3wCreateSyncFromCLeventARB;\nPFNGLCREATETEXTURESPROC                              gl3wCreateTextures;\nPFNGLCREATETRANSFORMFEEDBACKSPROC                    gl3wCreateTransformFeedbacks;\nPFNGLCREATEVERTEXARRAYSPROC                          gl3wCreateVertexArrays;\nPFNGLCULLFACEPROC                                    gl3wCullFace;\nPFNGLDEBUGMESSAGECALLBACKPROC                        gl3wDebugMessageCallback;\nPFNGLDEBUGMESSAGECALLBACKARBPROC                     gl3wDebugMessageCallbackARB;\nPFNGLDEBUGMESSAGECONTROLPROC                         gl3wDebugMessageControl;\nPFNGLDEBUGMESSAGECONTROLARBPROC                      gl3wDebugMessageControlARB;\nPFNGLDEBUGMESSAGEINSERTPROC                          gl3wDebugMessageInsert;\nPFNGLDEBUGMESSAGEINSERTARBPROC                       gl3wDebugMessageInsertARB;\nPFNGLDELETEBUFFERSPROC                               gl3wDeleteBuffers;\nPFNGLDELETEFRAMEBUFFERSPROC                          gl3wDeleteFramebuffers;\nPFNGLDELETENAMEDSTRINGARBPROC                        gl3wDeleteNamedStringARB;\nPFNGLDELETEPROGRAMPROC                               gl3wDeleteProgram;\nPFNGLDELETEPROGRAMPIPELINESPROC                      gl3wDeleteProgramPipelines;\nPFNGLDELETEQUERIESPROC                               gl3wDeleteQueries;\nPFNGLDELETERENDERBUFFERSPROC                         gl3wDeleteRenderbuffers;\nPFNGLDELETESAMPLERSPROC                              gl3wDeleteSamplers;\nPFNGLDELETESHADERPROC                                gl3wDeleteShader;\nPFNGLDELETESYNCPROC                                  gl3wDeleteSync;\nPFNGLDELETETEXTURESPROC                              gl3wDeleteTextures;\nPFNGLDELETETRANSFORMFEEDBACKSPROC                    gl3wDeleteTransformFeedbacks;\nPFNGLDELETEVERTEXARRAYSPROC                          gl3wDeleteVertexArrays;\nPFNGLDEPTHFUNCPROC                                   gl3wDepthFunc;\nPFNGLDEPTHMASKPROC                                   gl3wDepthMask;\nPFNGLDEPTHRANGEPROC                                  gl3wDepthRange;\nPFNGLDEPTHRANGEARRAYVPROC                            gl3wDepthRangeArrayv;\nPFNGLDEPTHRANGEINDEXEDPROC                           gl3wDepthRangeIndexed;\nPFNGLDEPTHRANGEFPROC                                 gl3wDepthRangef;\nPFNGLDETACHSHADERPROC                                gl3wDetachShader;\nPFNGLDISABLEPROC                                     gl3wDisable;\nPFNGLDISABLEVERTEXARRAYATTRIBPROC                    gl3wDisableVertexArrayAttrib;\nPFNGLDISABLEVERTEXATTRIBARRAYPROC                    gl3wDisableVertexAttribArray;\nPFNGLDISABLEIPROC                                    gl3wDisablei;\nPFNGLDISPATCHCOMPUTEPROC                             gl3wDispatchCompute;\nPFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC                 gl3wDispatchComputeGroupSizeARB;\nPFNGLDISPATCHCOMPUTEINDIRECTPROC                     gl3wDispatchComputeIndirect;\nPFNGLDRAWARRAYSPROC                                  gl3wDrawArrays;\nPFNGLDRAWARRAYSINDIRECTPROC                          gl3wDrawArraysIndirect;\nPFNGLDRAWARRAYSINSTANCEDPROC                         gl3wDrawArraysInstanced;\nPFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC             gl3wDrawArraysInstancedBaseInstance;\nPFNGLDRAWBUFFERPROC                                  gl3wDrawBuffer;\nPFNGLDRAWBUFFERSPROC                                 gl3wDrawBuffers;\nPFNGLDRAWELEMENTSPROC                                gl3wDrawElements;\nPFNGLDRAWELEMENTSBASEVERTEXPROC                      gl3wDrawElementsBaseVertex;\nPFNGLDRAWELEMENTSINDIRECTPROC                        gl3wDrawElementsIndirect;\nPFNGLDRAWELEMENTSINSTANCEDPROC                       gl3wDrawElementsInstanced;\nPFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC           gl3wDrawElementsInstancedBaseInstance;\nPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC             gl3wDrawElementsInstancedBaseVertex;\nPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC gl3wDrawElementsInstancedBaseVertexBaseInstance;\nPFNGLDRAWRANGEELEMENTSPROC                           gl3wDrawRangeElements;\nPFNGLDRAWRANGEELEMENTSBASEVERTEXPROC                 gl3wDrawRangeElementsBaseVertex;\nPFNGLDRAWTRANSFORMFEEDBACKPROC                       gl3wDrawTransformFeedback;\nPFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC              gl3wDrawTransformFeedbackInstanced;\nPFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC                 gl3wDrawTransformFeedbackStream;\nPFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC        gl3wDrawTransformFeedbackStreamInstanced;\nPFNGLENABLEPROC                                      gl3wEnable;\nPFNGLENABLEVERTEXARRAYATTRIBPROC                     gl3wEnableVertexArrayAttrib;\nPFNGLENABLEVERTEXATTRIBARRAYPROC                     gl3wEnableVertexAttribArray;\nPFNGLENABLEIPROC                                     gl3wEnablei;\nPFNGLENDCONDITIONALRENDERPROC                        gl3wEndConditionalRender;\nPFNGLENDQUERYPROC                                    gl3wEndQuery;\nPFNGLENDQUERYINDEXEDPROC                             gl3wEndQueryIndexed;\nPFNGLENDTRANSFORMFEEDBACKPROC                        gl3wEndTransformFeedback;\nPFNGLFENCESYNCPROC                                   gl3wFenceSync;\nPFNGLFINISHPROC                                      gl3wFinish;\nPFNGLFLUSHPROC                                       gl3wFlush;\nPFNGLFLUSHMAPPEDBUFFERRANGEPROC                      gl3wFlushMappedBufferRange;\nPFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC                 gl3wFlushMappedNamedBufferRange;\nPFNGLFRAMEBUFFERPARAMETERIPROC                       gl3wFramebufferParameteri;\nPFNGLFRAMEBUFFERRENDERBUFFERPROC                     gl3wFramebufferRenderbuffer;\nPFNGLFRAMEBUFFERTEXTUREPROC                          gl3wFramebufferTexture;\nPFNGLFRAMEBUFFERTEXTURE1DPROC                        gl3wFramebufferTexture1D;\nPFNGLFRAMEBUFFERTEXTURE2DPROC                        gl3wFramebufferTexture2D;\nPFNGLFRAMEBUFFERTEXTURE3DPROC                        gl3wFramebufferTexture3D;\nPFNGLFRAMEBUFFERTEXTURELAYERPROC                     gl3wFramebufferTextureLayer;\nPFNGLFRONTFACEPROC                                   gl3wFrontFace;\nPFNGLGENBUFFERSPROC                                  gl3wGenBuffers;\nPFNGLGENFRAMEBUFFERSPROC                             gl3wGenFramebuffers;\nPFNGLGENPROGRAMPIPELINESPROC                         gl3wGenProgramPipelines;\nPFNGLGENQUERIESPROC                                  gl3wGenQueries;\nPFNGLGENRENDERBUFFERSPROC                            gl3wGenRenderbuffers;\nPFNGLGENSAMPLERSPROC                                 gl3wGenSamplers;\nPFNGLGENTEXTURESPROC                                 gl3wGenTextures;\nPFNGLGENTRANSFORMFEEDBACKSPROC                       gl3wGenTransformFeedbacks;\nPFNGLGENVERTEXARRAYSPROC                             gl3wGenVertexArrays;\nPFNGLGENERATEMIPMAPPROC                              gl3wGenerateMipmap;\nPFNGLGENERATETEXTUREMIPMAPPROC                       gl3wGenerateTextureMipmap;\nPFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC              gl3wGetActiveAtomicCounterBufferiv;\nPFNGLGETACTIVEATTRIBPROC                             gl3wGetActiveAttrib;\nPFNGLGETACTIVESUBROUTINENAMEPROC                     gl3wGetActiveSubroutineName;\nPFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC              gl3wGetActiveSubroutineUniformName;\nPFNGLGETACTIVESUBROUTINEUNIFORMIVPROC                gl3wGetActiveSubroutineUniformiv;\nPFNGLGETACTIVEUNIFORMPROC                            gl3wGetActiveUniform;\nPFNGLGETACTIVEUNIFORMBLOCKNAMEPROC                   gl3wGetActiveUniformBlockName;\nPFNGLGETACTIVEUNIFORMBLOCKIVPROC                     gl3wGetActiveUniformBlockiv;\nPFNGLGETACTIVEUNIFORMNAMEPROC                        gl3wGetActiveUniformName;\nPFNGLGETACTIVEUNIFORMSIVPROC                         gl3wGetActiveUniformsiv;\nPFNGLGETATTACHEDSHADERSPROC                          gl3wGetAttachedShaders;\nPFNGLGETATTRIBLOCATIONPROC                           gl3wGetAttribLocation;\nPFNGLGETBOOLEANI_VPROC                               gl3wGetBooleani_v;\nPFNGLGETBOOLEANVPROC                                 gl3wGetBooleanv;\nPFNGLGETBUFFERPARAMETERI64VPROC                      gl3wGetBufferParameteri64v;\nPFNGLGETBUFFERPARAMETERIVPROC                        gl3wGetBufferParameteriv;\nPFNGLGETBUFFERPOINTERVPROC                           gl3wGetBufferPointerv;\nPFNGLGETBUFFERSUBDATAPROC                            gl3wGetBufferSubData;\nPFNGLGETCOMPRESSEDTEXIMAGEPROC                       gl3wGetCompressedTexImage;\nPFNGLGETCOMPRESSEDTEXTUREIMAGEPROC                   gl3wGetCompressedTextureImage;\nPFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC                gl3wGetCompressedTextureSubImage;\nPFNGLGETDEBUGMESSAGELOGPROC                          gl3wGetDebugMessageLog;\nPFNGLGETDEBUGMESSAGELOGARBPROC                       gl3wGetDebugMessageLogARB;\nPFNGLGETDOUBLEI_VPROC                                gl3wGetDoublei_v;\nPFNGLGETDOUBLEVPROC                                  gl3wGetDoublev;\nPFNGLGETERRORPROC                                    gl3wGetError;\nPFNGLGETFLOATI_VPROC                                 gl3wGetFloati_v;\nPFNGLGETFLOATVPROC                                   gl3wGetFloatv;\nPFNGLGETFRAGDATAINDEXPROC                            gl3wGetFragDataIndex;\nPFNGLGETFRAGDATALOCATIONPROC                         gl3wGetFragDataLocation;\nPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC         gl3wGetFramebufferAttachmentParameteriv;\nPFNGLGETFRAMEBUFFERPARAMETERIVPROC                   gl3wGetFramebufferParameteriv;\nPFNGLGETGRAPHICSRESETSTATUSPROC                      gl3wGetGraphicsResetStatus;\nPFNGLGETGRAPHICSRESETSTATUSARBPROC                   gl3wGetGraphicsResetStatusARB;\nPFNGLGETIMAGEHANDLEARBPROC                           gl3wGetImageHandleARB;\nPFNGLGETINTEGER64I_VPROC                             gl3wGetInteger64i_v;\nPFNGLGETINTEGER64VPROC                               gl3wGetInteger64v;\nPFNGLGETINTEGERI_VPROC                               gl3wGetIntegeri_v;\nPFNGLGETINTEGERVPROC                                 gl3wGetIntegerv;\nPFNGLGETINTERNALFORMATI64VPROC                       gl3wGetInternalformati64v;\nPFNGLGETINTERNALFORMATIVPROC                         gl3wGetInternalformativ;\nPFNGLGETMULTISAMPLEFVPROC                            gl3wGetMultisamplefv;\nPFNGLGETNAMEDBUFFERPARAMETERI64VPROC                 gl3wGetNamedBufferParameteri64v;\nPFNGLGETNAMEDBUFFERPARAMETERIVPROC                   gl3wGetNamedBufferParameteriv;\nPFNGLGETNAMEDBUFFERPOINTERVPROC                      gl3wGetNamedBufferPointerv;\nPFNGLGETNAMEDBUFFERSUBDATAPROC                       gl3wGetNamedBufferSubData;\nPFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC    gl3wGetNamedFramebufferAttachmentParameteriv;\nPFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC              gl3wGetNamedFramebufferParameteriv;\nPFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC             gl3wGetNamedRenderbufferParameteriv;\nPFNGLGETNAMEDSTRINGARBPROC                           gl3wGetNamedStringARB;\nPFNGLGETNAMEDSTRINGIVARBPROC                         gl3wGetNamedStringivARB;\nPFNGLGETOBJECTLABELPROC                              gl3wGetObjectLabel;\nPFNGLGETOBJECTPTRLABELPROC                           gl3wGetObjectPtrLabel;\nPFNGLGETPOINTERVPROC                                 gl3wGetPointerv;\nPFNGLGETPROGRAMBINARYPROC                            gl3wGetProgramBinary;\nPFNGLGETPROGRAMINFOLOGPROC                           gl3wGetProgramInfoLog;\nPFNGLGETPROGRAMINTERFACEIVPROC                       gl3wGetProgramInterfaceiv;\nPFNGLGETPROGRAMPIPELINEINFOLOGPROC                   gl3wGetProgramPipelineInfoLog;\nPFNGLGETPROGRAMPIPELINEIVPROC                        gl3wGetProgramPipelineiv;\nPFNGLGETPROGRAMRESOURCEINDEXPROC                     gl3wGetProgramResourceIndex;\nPFNGLGETPROGRAMRESOURCELOCATIONPROC                  gl3wGetProgramResourceLocation;\nPFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC             gl3wGetProgramResourceLocationIndex;\nPFNGLGETPROGRAMRESOURCENAMEPROC                      gl3wGetProgramResourceName;\nPFNGLGETPROGRAMRESOURCEIVPROC                        gl3wGetProgramResourceiv;\nPFNGLGETPROGRAMSTAGEIVPROC                           gl3wGetProgramStageiv;\nPFNGLGETPROGRAMIVPROC                                gl3wGetProgramiv;\nPFNGLGETQUERYBUFFEROBJECTI64VPROC                    gl3wGetQueryBufferObjecti64v;\nPFNGLGETQUERYBUFFEROBJECTIVPROC                      gl3wGetQueryBufferObjectiv;\nPFNGLGETQUERYBUFFEROBJECTUI64VPROC                   gl3wGetQueryBufferObjectui64v;\nPFNGLGETQUERYBUFFEROBJECTUIVPROC                     gl3wGetQueryBufferObjectuiv;\nPFNGLGETQUERYINDEXEDIVPROC                           gl3wGetQueryIndexediv;\nPFNGLGETQUERYOBJECTI64VPROC                          gl3wGetQueryObjecti64v;\nPFNGLGETQUERYOBJECTIVPROC                            gl3wGetQueryObjectiv;\nPFNGLGETQUERYOBJECTUI64VPROC                         gl3wGetQueryObjectui64v;\nPFNGLGETQUERYOBJECTUIVPROC                           gl3wGetQueryObjectuiv;\nPFNGLGETQUERYIVPROC                                  gl3wGetQueryiv;\nPFNGLGETRENDERBUFFERPARAMETERIVPROC                  gl3wGetRenderbufferParameteriv;\nPFNGLGETSAMPLERPARAMETERIIVPROC                      gl3wGetSamplerParameterIiv;\nPFNGLGETSAMPLERPARAMETERIUIVPROC                     gl3wGetSamplerParameterIuiv;\nPFNGLGETSAMPLERPARAMETERFVPROC                       gl3wGetSamplerParameterfv;\nPFNGLGETSAMPLERPARAMETERIVPROC                       gl3wGetSamplerParameteriv;\nPFNGLGETSHADERINFOLOGPROC                            gl3wGetShaderInfoLog;\nPFNGLGETSHADERPRECISIONFORMATPROC                    gl3wGetShaderPrecisionFormat;\nPFNGLGETSHADERSOURCEPROC                             gl3wGetShaderSource;\nPFNGLGETSHADERIVPROC                                 gl3wGetShaderiv;\nPFNGLGETSTRINGPROC                                   gl3wGetString;\nPFNGLGETSTRINGIPROC                                  gl3wGetStringi;\nPFNGLGETSUBROUTINEINDEXPROC                          gl3wGetSubroutineIndex;\nPFNGLGETSUBROUTINEUNIFORMLOCATIONPROC                gl3wGetSubroutineUniformLocation;\nPFNGLGETSYNCIVPROC                                   gl3wGetSynciv;\nPFNGLGETTEXIMAGEPROC                                 gl3wGetTexImage;\nPFNGLGETTEXLEVELPARAMETERFVPROC                      gl3wGetTexLevelParameterfv;\nPFNGLGETTEXLEVELPARAMETERIVPROC                      gl3wGetTexLevelParameteriv;\nPFNGLGETTEXPARAMETERIIVPROC                          gl3wGetTexParameterIiv;\nPFNGLGETTEXPARAMETERIUIVPROC                         gl3wGetTexParameterIuiv;\nPFNGLGETTEXPARAMETERFVPROC                           gl3wGetTexParameterfv;\nPFNGLGETTEXPARAMETERIVPROC                           gl3wGetTexParameteriv;\nPFNGLGETTEXTUREHANDLEARBPROC                         gl3wGetTextureHandleARB;\nPFNGLGETTEXTUREIMAGEPROC                             gl3wGetTextureImage;\nPFNGLGETTEXTURELEVELPARAMETERFVPROC                  gl3wGetTextureLevelParameterfv;\nPFNGLGETTEXTURELEVELPARAMETERIVPROC                  gl3wGetTextureLevelParameteriv;\nPFNGLGETTEXTUREPARAMETERIIVPROC                      gl3wGetTextureParameterIiv;\nPFNGLGETTEXTUREPARAMETERIUIVPROC                     gl3wGetTextureParameterIuiv;\nPFNGLGETTEXTUREPARAMETERFVPROC                       gl3wGetTextureParameterfv;\nPFNGLGETTEXTUREPARAMETERIVPROC                       gl3wGetTextureParameteriv;\nPFNGLGETTEXTURESAMPLERHANDLEARBPROC                  gl3wGetTextureSamplerHandleARB;\nPFNGLGETTEXTURESUBIMAGEPROC                          gl3wGetTextureSubImage;\nPFNGLGETTRANSFORMFEEDBACKVARYINGPROC                 gl3wGetTransformFeedbackVarying;\nPFNGLGETTRANSFORMFEEDBACKI64_VPROC                   gl3wGetTransformFeedbacki64_v;\nPFNGLGETTRANSFORMFEEDBACKI_VPROC                     gl3wGetTransformFeedbacki_v;\nPFNGLGETTRANSFORMFEEDBACKIVPROC                      gl3wGetTransformFeedbackiv;\nPFNGLGETUNIFORMBLOCKINDEXPROC                        gl3wGetUniformBlockIndex;\nPFNGLGETUNIFORMINDICESPROC                           gl3wGetUniformIndices;\nPFNGLGETUNIFORMLOCATIONPROC                          gl3wGetUniformLocation;\nPFNGLGETUNIFORMSUBROUTINEUIVPROC                     gl3wGetUniformSubroutineuiv;\nPFNGLGETUNIFORMDVPROC                                gl3wGetUniformdv;\nPFNGLGETUNIFORMFVPROC                                gl3wGetUniformfv;\nPFNGLGETUNIFORMIVPROC                                gl3wGetUniformiv;\nPFNGLGETUNIFORMUIVPROC                               gl3wGetUniformuiv;\nPFNGLGETVERTEXARRAYINDEXED64IVPROC                   gl3wGetVertexArrayIndexed64iv;\nPFNGLGETVERTEXARRAYINDEXEDIVPROC                     gl3wGetVertexArrayIndexediv;\nPFNGLGETVERTEXARRAYIVPROC                            gl3wGetVertexArrayiv;\nPFNGLGETVERTEXATTRIBIIVPROC                          gl3wGetVertexAttribIiv;\nPFNGLGETVERTEXATTRIBIUIVPROC                         gl3wGetVertexAttribIuiv;\nPFNGLGETVERTEXATTRIBLDVPROC                          gl3wGetVertexAttribLdv;\nPFNGLGETVERTEXATTRIBLUI64VARBPROC                    gl3wGetVertexAttribLui64vARB;\nPFNGLGETVERTEXATTRIBPOINTERVPROC                     gl3wGetVertexAttribPointerv;\nPFNGLGETVERTEXATTRIBDVPROC                           gl3wGetVertexAttribdv;\nPFNGLGETVERTEXATTRIBFVPROC                           gl3wGetVertexAttribfv;\nPFNGLGETVERTEXATTRIBIVPROC                           gl3wGetVertexAttribiv;\nPFNGLGETNCOMPRESSEDTEXIMAGEPROC                      gl3wGetnCompressedTexImage;\nPFNGLGETNCOMPRESSEDTEXIMAGEARBPROC                   gl3wGetnCompressedTexImageARB;\nPFNGLGETNTEXIMAGEPROC                                gl3wGetnTexImage;\nPFNGLGETNTEXIMAGEARBPROC                             gl3wGetnTexImageARB;\nPFNGLGETNUNIFORMDVPROC                               gl3wGetnUniformdv;\nPFNGLGETNUNIFORMDVARBPROC                            gl3wGetnUniformdvARB;\nPFNGLGETNUNIFORMFVPROC                               gl3wGetnUniformfv;\nPFNGLGETNUNIFORMFVARBPROC                            gl3wGetnUniformfvARB;\nPFNGLGETNUNIFORMIVPROC                               gl3wGetnUniformiv;\nPFNGLGETNUNIFORMIVARBPROC                            gl3wGetnUniformivARB;\nPFNGLGETNUNIFORMUIVPROC                              gl3wGetnUniformuiv;\nPFNGLGETNUNIFORMUIVARBPROC                           gl3wGetnUniformuivARB;\nPFNGLHINTPROC                                        gl3wHint;\nPFNGLINVALIDATEBUFFERDATAPROC                        gl3wInvalidateBufferData;\nPFNGLINVALIDATEBUFFERSUBDATAPROC                     gl3wInvalidateBufferSubData;\nPFNGLINVALIDATEFRAMEBUFFERPROC                       gl3wInvalidateFramebuffer;\nPFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC              gl3wInvalidateNamedFramebufferData;\nPFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC           gl3wInvalidateNamedFramebufferSubData;\nPFNGLINVALIDATESUBFRAMEBUFFERPROC                    gl3wInvalidateSubFramebuffer;\nPFNGLINVALIDATETEXIMAGEPROC                          gl3wInvalidateTexImage;\nPFNGLINVALIDATETEXSUBIMAGEPROC                       gl3wInvalidateTexSubImage;\nPFNGLISBUFFERPROC                                    gl3wIsBuffer;\nPFNGLISENABLEDPROC                                   gl3wIsEnabled;\nPFNGLISENABLEDIPROC                                  gl3wIsEnabledi;\nPFNGLISFRAMEBUFFERPROC                               gl3wIsFramebuffer;\nPFNGLISIMAGEHANDLERESIDENTARBPROC                    gl3wIsImageHandleResidentARB;\nPFNGLISNAMEDSTRINGARBPROC                            gl3wIsNamedStringARB;\nPFNGLISPROGRAMPROC                                   gl3wIsProgram;\nPFNGLISPROGRAMPIPELINEPROC                           gl3wIsProgramPipeline;\nPFNGLISQUERYPROC                                     gl3wIsQuery;\nPFNGLISRENDERBUFFERPROC                              gl3wIsRenderbuffer;\nPFNGLISSAMPLERPROC                                   gl3wIsSampler;\nPFNGLISSHADERPROC                                    gl3wIsShader;\nPFNGLISSYNCPROC                                      gl3wIsSync;\nPFNGLISTEXTUREPROC                                   gl3wIsTexture;\nPFNGLISTEXTUREHANDLERESIDENTARBPROC                  gl3wIsTextureHandleResidentARB;\nPFNGLISTRANSFORMFEEDBACKPROC                         gl3wIsTransformFeedback;\nPFNGLISVERTEXARRAYPROC                               gl3wIsVertexArray;\nPFNGLLINEWIDTHPROC                                   gl3wLineWidth;\nPFNGLLINKPROGRAMPROC                                 gl3wLinkProgram;\nPFNGLLOGICOPPROC                                     gl3wLogicOp;\nPFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC               gl3wMakeImageHandleNonResidentARB;\nPFNGLMAKEIMAGEHANDLERESIDENTARBPROC                  gl3wMakeImageHandleResidentARB;\nPFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC             gl3wMakeTextureHandleNonResidentARB;\nPFNGLMAKETEXTUREHANDLERESIDENTARBPROC                gl3wMakeTextureHandleResidentARB;\nPFNGLMAPBUFFERPROC                                   gl3wMapBuffer;\nPFNGLMAPBUFFERRANGEPROC                              gl3wMapBufferRange;\nPFNGLMAPNAMEDBUFFERPROC                              gl3wMapNamedBuffer;\nPFNGLMAPNAMEDBUFFERRANGEPROC                         gl3wMapNamedBufferRange;\nPFNGLMEMORYBARRIERPROC                               gl3wMemoryBarrier;\nPFNGLMEMORYBARRIERBYREGIONPROC                       gl3wMemoryBarrierByRegion;\nPFNGLMINSAMPLESHADINGPROC                            gl3wMinSampleShading;\nPFNGLMINSAMPLESHADINGARBPROC                         gl3wMinSampleShadingARB;\nPFNGLMULTIDRAWARRAYSPROC                             gl3wMultiDrawArrays;\nPFNGLMULTIDRAWARRAYSINDIRECTPROC                     gl3wMultiDrawArraysIndirect;\nPFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC             gl3wMultiDrawArraysIndirectCountARB;\nPFNGLMULTIDRAWELEMENTSPROC                           gl3wMultiDrawElements;\nPFNGLMULTIDRAWELEMENTSBASEVERTEXPROC                 gl3wMultiDrawElementsBaseVertex;\nPFNGLMULTIDRAWELEMENTSINDIRECTPROC                   gl3wMultiDrawElementsIndirect;\nPFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC           gl3wMultiDrawElementsIndirectCountARB;\nPFNGLNAMEDBUFFERDATAPROC                             gl3wNamedBufferData;\nPFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC                gl3wNamedBufferPageCommitmentARB;\nPFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC                gl3wNamedBufferPageCommitmentEXT;\nPFNGLNAMEDBUFFERSTORAGEPROC                          gl3wNamedBufferStorage;\nPFNGLNAMEDBUFFERSUBDATAPROC                          gl3wNamedBufferSubData;\nPFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC                  gl3wNamedFramebufferDrawBuffer;\nPFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC                 gl3wNamedFramebufferDrawBuffers;\nPFNGLNAMEDFRAMEBUFFERPARAMETERIPROC                  gl3wNamedFramebufferParameteri;\nPFNGLNAMEDFRAMEBUFFERREADBUFFERPROC                  gl3wNamedFramebufferReadBuffer;\nPFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC                gl3wNamedFramebufferRenderbuffer;\nPFNGLNAMEDFRAMEBUFFERTEXTUREPROC                     gl3wNamedFramebufferTexture;\nPFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC                gl3wNamedFramebufferTextureLayer;\nPFNGLNAMEDRENDERBUFFERSTORAGEPROC                    gl3wNamedRenderbufferStorage;\nPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC         gl3wNamedRenderbufferStorageMultisample;\nPFNGLNAMEDSTRINGARBPROC                              gl3wNamedStringARB;\nPFNGLOBJECTLABELPROC                                 gl3wObjectLabel;\nPFNGLOBJECTPTRLABELPROC                              gl3wObjectPtrLabel;\nPFNGLPATCHPARAMETERFVPROC                            gl3wPatchParameterfv;\nPFNGLPATCHPARAMETERIPROC                             gl3wPatchParameteri;\nPFNGLPAUSETRANSFORMFEEDBACKPROC                      gl3wPauseTransformFeedback;\nPFNGLPIXELSTOREFPROC                                 gl3wPixelStoref;\nPFNGLPIXELSTOREIPROC                                 gl3wPixelStorei;\nPFNGLPOINTPARAMETERFPROC                             gl3wPointParameterf;\nPFNGLPOINTPARAMETERFVPROC                            gl3wPointParameterfv;\nPFNGLPOINTPARAMETERIPROC                             gl3wPointParameteri;\nPFNGLPOINTPARAMETERIVPROC                            gl3wPointParameteriv;\nPFNGLPOINTSIZEPROC                                   gl3wPointSize;\nPFNGLPOLYGONMODEPROC                                 gl3wPolygonMode;\nPFNGLPOLYGONOFFSETPROC                               gl3wPolygonOffset;\nPFNGLPOPDEBUGGROUPPROC                               gl3wPopDebugGroup;\nPFNGLPRIMITIVERESTARTINDEXPROC                       gl3wPrimitiveRestartIndex;\nPFNGLPROGRAMBINARYPROC                               gl3wProgramBinary;\nPFNGLPROGRAMPARAMETERIPROC                           gl3wProgramParameteri;\nPFNGLPROGRAMUNIFORM1DPROC                            gl3wProgramUniform1d;\nPFNGLPROGRAMUNIFORM1DVPROC                           gl3wProgramUniform1dv;\nPFNGLPROGRAMUNIFORM1FPROC                            gl3wProgramUniform1f;\nPFNGLPROGRAMUNIFORM1FVPROC                           gl3wProgramUniform1fv;\nPFNGLPROGRAMUNIFORM1IPROC                            gl3wProgramUniform1i;\nPFNGLPROGRAMUNIFORM1IVPROC                           gl3wProgramUniform1iv;\nPFNGLPROGRAMUNIFORM1UIPROC                           gl3wProgramUniform1ui;\nPFNGLPROGRAMUNIFORM1UIVPROC                          gl3wProgramUniform1uiv;\nPFNGLPROGRAMUNIFORM2DPROC                            gl3wProgramUniform2d;\nPFNGLPROGRAMUNIFORM2DVPROC                           gl3wProgramUniform2dv;\nPFNGLPROGRAMUNIFORM2FPROC                            gl3wProgramUniform2f;\nPFNGLPROGRAMUNIFORM2FVPROC                           gl3wProgramUniform2fv;\nPFNGLPROGRAMUNIFORM2IPROC                            gl3wProgramUniform2i;\nPFNGLPROGRAMUNIFORM2IVPROC                           gl3wProgramUniform2iv;\nPFNGLPROGRAMUNIFORM2UIPROC                           gl3wProgramUniform2ui;\nPFNGLPROGRAMUNIFORM2UIVPROC                          gl3wProgramUniform2uiv;\nPFNGLPROGRAMUNIFORM3DPROC                            gl3wProgramUniform3d;\nPFNGLPROGRAMUNIFORM3DVPROC                           gl3wProgramUniform3dv;\nPFNGLPROGRAMUNIFORM3FPROC                            gl3wProgramUniform3f;\nPFNGLPROGRAMUNIFORM3FVPROC                           gl3wProgramUniform3fv;\nPFNGLPROGRAMUNIFORM3IPROC                            gl3wProgramUniform3i;\nPFNGLPROGRAMUNIFORM3IVPROC                           gl3wProgramUniform3iv;\nPFNGLPROGRAMUNIFORM3UIPROC                           gl3wProgramUniform3ui;\nPFNGLPROGRAMUNIFORM3UIVPROC                          gl3wProgramUniform3uiv;\nPFNGLPROGRAMUNIFORM4DPROC                            gl3wProgramUniform4d;\nPFNGLPROGRAMUNIFORM4DVPROC                           gl3wProgramUniform4dv;\nPFNGLPROGRAMUNIFORM4FPROC                            gl3wProgramUniform4f;\nPFNGLPROGRAMUNIFORM4FVPROC                           gl3wProgramUniform4fv;\nPFNGLPROGRAMUNIFORM4IPROC                            gl3wProgramUniform4i;\nPFNGLPROGRAMUNIFORM4IVPROC                           gl3wProgramUniform4iv;\nPFNGLPROGRAMUNIFORM4UIPROC                           gl3wProgramUniform4ui;\nPFNGLPROGRAMUNIFORM4UIVPROC                          gl3wProgramUniform4uiv;\nPFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC                 gl3wProgramUniformHandleui64ARB;\nPFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC                gl3wProgramUniformHandleui64vARB;\nPFNGLPROGRAMUNIFORMMATRIX2DVPROC                     gl3wProgramUniformMatrix2dv;\nPFNGLPROGRAMUNIFORMMATRIX2FVPROC                     gl3wProgramUniformMatrix2fv;\nPFNGLPROGRAMUNIFORMMATRIX2X3DVPROC                   gl3wProgramUniformMatrix2x3dv;\nPFNGLPROGRAMUNIFORMMATRIX2X3FVPROC                   gl3wProgramUniformMatrix2x3fv;\nPFNGLPROGRAMUNIFORMMATRIX2X4DVPROC                   gl3wProgramUniformMatrix2x4dv;\nPFNGLPROGRAMUNIFORMMATRIX2X4FVPROC                   gl3wProgramUniformMatrix2x4fv;\nPFNGLPROGRAMUNIFORMMATRIX3DVPROC                     gl3wProgramUniformMatrix3dv;\nPFNGLPROGRAMUNIFORMMATRIX3FVPROC                     gl3wProgramUniformMatrix3fv;\nPFNGLPROGRAMUNIFORMMATRIX3X2DVPROC                   gl3wProgramUniformMatrix3x2dv;\nPFNGLPROGRAMUNIFORMMATRIX3X2FVPROC                   gl3wProgramUniformMatrix3x2fv;\nPFNGLPROGRAMUNIFORMMATRIX3X4DVPROC                   gl3wProgramUniformMatrix3x4dv;\nPFNGLPROGRAMUNIFORMMATRIX3X4FVPROC                   gl3wProgramUniformMatrix3x4fv;\nPFNGLPROGRAMUNIFORMMATRIX4DVPROC                     gl3wProgramUniformMatrix4dv;\nPFNGLPROGRAMUNIFORMMATRIX4FVPROC                     gl3wProgramUniformMatrix4fv;\nPFNGLPROGRAMUNIFORMMATRIX4X2DVPROC                   gl3wProgramUniformMatrix4x2dv;\nPFNGLPROGRAMUNIFORMMATRIX4X2FVPROC                   gl3wProgramUniformMatrix4x2fv;\nPFNGLPROGRAMUNIFORMMATRIX4X3DVPROC                   gl3wProgramUniformMatrix4x3dv;\nPFNGLPROGRAMUNIFORMMATRIX4X3FVPROC                   gl3wProgramUniformMatrix4x3fv;\nPFNGLPROVOKINGVERTEXPROC                             gl3wProvokingVertex;\nPFNGLPUSHDEBUGGROUPPROC                              gl3wPushDebugGroup;\nPFNGLQUERYCOUNTERPROC                                gl3wQueryCounter;\nPFNGLREADBUFFERPROC                                  gl3wReadBuffer;\nPFNGLREADPIXELSPROC                                  gl3wReadPixels;\nPFNGLREADNPIXELSPROC                                 gl3wReadnPixels;\nPFNGLREADNPIXELSARBPROC                              gl3wReadnPixelsARB;\nPFNGLRELEASESHADERCOMPILERPROC                       gl3wReleaseShaderCompiler;\nPFNGLRENDERBUFFERSTORAGEPROC                         gl3wRenderbufferStorage;\nPFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC              gl3wRenderbufferStorageMultisample;\nPFNGLRESUMETRANSFORMFEEDBACKPROC                     gl3wResumeTransformFeedback;\nPFNGLSAMPLECOVERAGEPROC                              gl3wSampleCoverage;\nPFNGLSAMPLEMASKIPROC                                 gl3wSampleMaski;\nPFNGLSAMPLERPARAMETERIIVPROC                         gl3wSamplerParameterIiv;\nPFNGLSAMPLERPARAMETERIUIVPROC                        gl3wSamplerParameterIuiv;\nPFNGLSAMPLERPARAMETERFPROC                           gl3wSamplerParameterf;\nPFNGLSAMPLERPARAMETERFVPROC                          gl3wSamplerParameterfv;\nPFNGLSAMPLERPARAMETERIPROC                           gl3wSamplerParameteri;\nPFNGLSAMPLERPARAMETERIVPROC                          gl3wSamplerParameteriv;\nPFNGLSCISSORPROC                                     gl3wScissor;\nPFNGLSCISSORARRAYVPROC                               gl3wScissorArrayv;\nPFNGLSCISSORINDEXEDPROC                              gl3wScissorIndexed;\nPFNGLSCISSORINDEXEDVPROC                             gl3wScissorIndexedv;\nPFNGLSHADERBINARYPROC                                gl3wShaderBinary;\nPFNGLSHADERSOURCEPROC                                gl3wShaderSource;\nPFNGLSHADERSTORAGEBLOCKBINDINGPROC                   gl3wShaderStorageBlockBinding;\nPFNGLSTENCILFUNCPROC                                 gl3wStencilFunc;\nPFNGLSTENCILFUNCSEPARATEPROC                         gl3wStencilFuncSeparate;\nPFNGLSTENCILMASKPROC                                 gl3wStencilMask;\nPFNGLSTENCILMASKSEPARATEPROC                         gl3wStencilMaskSeparate;\nPFNGLSTENCILOPPROC                                   gl3wStencilOp;\nPFNGLSTENCILOPSEPARATEPROC                           gl3wStencilOpSeparate;\nPFNGLTEXBUFFERPROC                                   gl3wTexBuffer;\nPFNGLTEXBUFFERRANGEPROC                              gl3wTexBufferRange;\nPFNGLTEXIMAGE1DPROC                                  gl3wTexImage1D;\nPFNGLTEXIMAGE2DPROC                                  gl3wTexImage2D;\nPFNGLTEXIMAGE2DMULTISAMPLEPROC                       gl3wTexImage2DMultisample;\nPFNGLTEXIMAGE3DPROC                                  gl3wTexImage3D;\nPFNGLTEXIMAGE3DMULTISAMPLEPROC                       gl3wTexImage3DMultisample;\nPFNGLTEXPAGECOMMITMENTARBPROC                        gl3wTexPageCommitmentARB;\nPFNGLTEXPARAMETERIIVPROC                             gl3wTexParameterIiv;\nPFNGLTEXPARAMETERIUIVPROC                            gl3wTexParameterIuiv;\nPFNGLTEXPARAMETERFPROC                               gl3wTexParameterf;\nPFNGLTEXPARAMETERFVPROC                              gl3wTexParameterfv;\nPFNGLTEXPARAMETERIPROC                               gl3wTexParameteri;\nPFNGLTEXPARAMETERIVPROC                              gl3wTexParameteriv;\nPFNGLTEXSTORAGE1DPROC                                gl3wTexStorage1D;\nPFNGLTEXSTORAGE2DPROC                                gl3wTexStorage2D;\nPFNGLTEXSTORAGE2DMULTISAMPLEPROC                     gl3wTexStorage2DMultisample;\nPFNGLTEXSTORAGE3DPROC                                gl3wTexStorage3D;\nPFNGLTEXSTORAGE3DMULTISAMPLEPROC                     gl3wTexStorage3DMultisample;\nPFNGLTEXSUBIMAGE1DPROC                               gl3wTexSubImage1D;\nPFNGLTEXSUBIMAGE2DPROC                               gl3wTexSubImage2D;\nPFNGLTEXSUBIMAGE3DPROC                               gl3wTexSubImage3D;\nPFNGLTEXTUREBARRIERPROC                              gl3wTextureBarrier;\nPFNGLTEXTUREBUFFERPROC                               gl3wTextureBuffer;\nPFNGLTEXTUREBUFFERRANGEPROC                          gl3wTextureBufferRange;\nPFNGLTEXTUREPARAMETERIIVPROC                         gl3wTextureParameterIiv;\nPFNGLTEXTUREPARAMETERIUIVPROC                        gl3wTextureParameterIuiv;\nPFNGLTEXTUREPARAMETERFPROC                           gl3wTextureParameterf;\nPFNGLTEXTUREPARAMETERFVPROC                          gl3wTextureParameterfv;\nPFNGLTEXTUREPARAMETERIPROC                           gl3wTextureParameteri;\nPFNGLTEXTUREPARAMETERIVPROC                          gl3wTextureParameteriv;\nPFNGLTEXTURESTORAGE1DPROC                            gl3wTextureStorage1D;\nPFNGLTEXTURESTORAGE2DPROC                            gl3wTextureStorage2D;\nPFNGLTEXTURESTORAGE2DMULTISAMPLEPROC                 gl3wTextureStorage2DMultisample;\nPFNGLTEXTURESTORAGE3DPROC                            gl3wTextureStorage3D;\nPFNGLTEXTURESTORAGE3DMULTISAMPLEPROC                 gl3wTextureStorage3DMultisample;\nPFNGLTEXTURESUBIMAGE1DPROC                           gl3wTextureSubImage1D;\nPFNGLTEXTURESUBIMAGE2DPROC                           gl3wTextureSubImage2D;\nPFNGLTEXTURESUBIMAGE3DPROC                           gl3wTextureSubImage3D;\nPFNGLTEXTUREVIEWPROC                                 gl3wTextureView;\nPFNGLTRANSFORMFEEDBACKBUFFERBASEPROC                 gl3wTransformFeedbackBufferBase;\nPFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC                gl3wTransformFeedbackBufferRange;\nPFNGLTRANSFORMFEEDBACKVARYINGSPROC                   gl3wTransformFeedbackVaryings;\nPFNGLUNIFORM1DPROC                                   gl3wUniform1d;\nPFNGLUNIFORM1DVPROC                                  gl3wUniform1dv;\nPFNGLUNIFORM1FPROC                                   gl3wUniform1f;\nPFNGLUNIFORM1FVPROC                                  gl3wUniform1fv;\nPFNGLUNIFORM1IPROC                                   gl3wUniform1i;\nPFNGLUNIFORM1IVPROC                                  gl3wUniform1iv;\nPFNGLUNIFORM1UIPROC                                  gl3wUniform1ui;\nPFNGLUNIFORM1UIVPROC                                 gl3wUniform1uiv;\nPFNGLUNIFORM2DPROC                                   gl3wUniform2d;\nPFNGLUNIFORM2DVPROC                                  gl3wUniform2dv;\nPFNGLUNIFORM2FPROC                                   gl3wUniform2f;\nPFNGLUNIFORM2FVPROC                                  gl3wUniform2fv;\nPFNGLUNIFORM2IPROC                                   gl3wUniform2i;\nPFNGLUNIFORM2IVPROC                                  gl3wUniform2iv;\nPFNGLUNIFORM2UIPROC                                  gl3wUniform2ui;\nPFNGLUNIFORM2UIVPROC                                 gl3wUniform2uiv;\nPFNGLUNIFORM3DPROC                                   gl3wUniform3d;\nPFNGLUNIFORM3DVPROC                                  gl3wUniform3dv;\nPFNGLUNIFORM3FPROC                                   gl3wUniform3f;\nPFNGLUNIFORM3FVPROC                                  gl3wUniform3fv;\nPFNGLUNIFORM3IPROC                                   gl3wUniform3i;\nPFNGLUNIFORM3IVPROC                                  gl3wUniform3iv;\nPFNGLUNIFORM3UIPROC                                  gl3wUniform3ui;\nPFNGLUNIFORM3UIVPROC                                 gl3wUniform3uiv;\nPFNGLUNIFORM4DPROC                                   gl3wUniform4d;\nPFNGLUNIFORM4DVPROC                                  gl3wUniform4dv;\nPFNGLUNIFORM4FPROC                                   gl3wUniform4f;\nPFNGLUNIFORM4FVPROC                                  gl3wUniform4fv;\nPFNGLUNIFORM4IPROC                                   gl3wUniform4i;\nPFNGLUNIFORM4IVPROC                                  gl3wUniform4iv;\nPFNGLUNIFORM4UIPROC                                  gl3wUniform4ui;\nPFNGLUNIFORM4UIVPROC                                 gl3wUniform4uiv;\nPFNGLUNIFORMBLOCKBINDINGPROC                         gl3wUniformBlockBinding;\nPFNGLUNIFORMHANDLEUI64ARBPROC                        gl3wUniformHandleui64ARB;\nPFNGLUNIFORMHANDLEUI64VARBPROC                       gl3wUniformHandleui64vARB;\nPFNGLUNIFORMMATRIX2DVPROC                            gl3wUniformMatrix2dv;\nPFNGLUNIFORMMATRIX2FVPROC                            gl3wUniformMatrix2fv;\nPFNGLUNIFORMMATRIX2X3DVPROC                          gl3wUniformMatrix2x3dv;\nPFNGLUNIFORMMATRIX2X3FVPROC                          gl3wUniformMatrix2x3fv;\nPFNGLUNIFORMMATRIX2X4DVPROC                          gl3wUniformMatrix2x4dv;\nPFNGLUNIFORMMATRIX2X4FVPROC                          gl3wUniformMatrix2x4fv;\nPFNGLUNIFORMMATRIX3DVPROC                            gl3wUniformMatrix3dv;\nPFNGLUNIFORMMATRIX3FVPROC                            gl3wUniformMatrix3fv;\nPFNGLUNIFORMMATRIX3X2DVPROC                          gl3wUniformMatrix3x2dv;\nPFNGLUNIFORMMATRIX3X2FVPROC                          gl3wUniformMatrix3x2fv;\nPFNGLUNIFORMMATRIX3X4DVPROC                          gl3wUniformMatrix3x4dv;\nPFNGLUNIFORMMATRIX3X4FVPROC                          gl3wUniformMatrix3x4fv;\nPFNGLUNIFORMMATRIX4DVPROC                            gl3wUniformMatrix4dv;\nPFNGLUNIFORMMATRIX4FVPROC                            gl3wUniformMatrix4fv;\nPFNGLUNIFORMMATRIX4X2DVPROC                          gl3wUniformMatrix4x2dv;\nPFNGLUNIFORMMATRIX4X2FVPROC                          gl3wUniformMatrix4x2fv;\nPFNGLUNIFORMMATRIX4X3DVPROC                          gl3wUniformMatrix4x3dv;\nPFNGLUNIFORMMATRIX4X3FVPROC                          gl3wUniformMatrix4x3fv;\nPFNGLUNIFORMSUBROUTINESUIVPROC                       gl3wUniformSubroutinesuiv;\nPFNGLUNMAPBUFFERPROC                                 gl3wUnmapBuffer;\nPFNGLUNMAPNAMEDBUFFERPROC                            gl3wUnmapNamedBuffer;\nPFNGLUSEPROGRAMPROC                                  gl3wUseProgram;\nPFNGLUSEPROGRAMSTAGESPROC                            gl3wUseProgramStages;\nPFNGLVALIDATEPROGRAMPROC                             gl3wValidateProgram;\nPFNGLVALIDATEPROGRAMPIPELINEPROC                     gl3wValidateProgramPipeline;\nPFNGLVERTEXARRAYATTRIBBINDINGPROC                    gl3wVertexArrayAttribBinding;\nPFNGLVERTEXARRAYATTRIBFORMATPROC                     gl3wVertexArrayAttribFormat;\nPFNGLVERTEXARRAYATTRIBIFORMATPROC                    gl3wVertexArrayAttribIFormat;\nPFNGLVERTEXARRAYATTRIBLFORMATPROC                    gl3wVertexArrayAttribLFormat;\nPFNGLVERTEXARRAYBINDINGDIVISORPROC                   gl3wVertexArrayBindingDivisor;\nPFNGLVERTEXARRAYELEMENTBUFFERPROC                    gl3wVertexArrayElementBuffer;\nPFNGLVERTEXARRAYVERTEXBUFFERPROC                     gl3wVertexArrayVertexBuffer;\nPFNGLVERTEXARRAYVERTEXBUFFERSPROC                    gl3wVertexArrayVertexBuffers;\nPFNGLVERTEXATTRIB1DPROC                              gl3wVertexAttrib1d;\nPFNGLVERTEXATTRIB1DVPROC                             gl3wVertexAttrib1dv;\nPFNGLVERTEXATTRIB1FPROC                              gl3wVertexAttrib1f;\nPFNGLVERTEXATTRIB1FVPROC                             gl3wVertexAttrib1fv;\nPFNGLVERTEXATTRIB1SPROC                              gl3wVertexAttrib1s;\nPFNGLVERTEXATTRIB1SVPROC                             gl3wVertexAttrib1sv;\nPFNGLVERTEXATTRIB2DPROC                              gl3wVertexAttrib2d;\nPFNGLVERTEXATTRIB2DVPROC                             gl3wVertexAttrib2dv;\nPFNGLVERTEXATTRIB2FPROC                              gl3wVertexAttrib2f;\nPFNGLVERTEXATTRIB2FVPROC                             gl3wVertexAttrib2fv;\nPFNGLVERTEXATTRIB2SPROC                              gl3wVertexAttrib2s;\nPFNGLVERTEXATTRIB2SVPROC                             gl3wVertexAttrib2sv;\nPFNGLVERTEXATTRIB3DPROC                              gl3wVertexAttrib3d;\nPFNGLVERTEXATTRIB3DVPROC                             gl3wVertexAttrib3dv;\nPFNGLVERTEXATTRIB3FPROC                              gl3wVertexAttrib3f;\nPFNGLVERTEXATTRIB3FVPROC                             gl3wVertexAttrib3fv;\nPFNGLVERTEXATTRIB3SPROC                              gl3wVertexAttrib3s;\nPFNGLVERTEXATTRIB3SVPROC                             gl3wVertexAttrib3sv;\nPFNGLVERTEXATTRIB4NBVPROC                            gl3wVertexAttrib4Nbv;\nPFNGLVERTEXATTRIB4NIVPROC                            gl3wVertexAttrib4Niv;\nPFNGLVERTEXATTRIB4NSVPROC                            gl3wVertexAttrib4Nsv;\nPFNGLVERTEXATTRIB4NUBPROC                            gl3wVertexAttrib4Nub;\nPFNGLVERTEXATTRIB4NUBVPROC                           gl3wVertexAttrib4Nubv;\nPFNGLVERTEXATTRIB4NUIVPROC                           gl3wVertexAttrib4Nuiv;\nPFNGLVERTEXATTRIB4NUSVPROC                           gl3wVertexAttrib4Nusv;\nPFNGLVERTEXATTRIB4BVPROC                             gl3wVertexAttrib4bv;\nPFNGLVERTEXATTRIB4DPROC                              gl3wVertexAttrib4d;\nPFNGLVERTEXATTRIB4DVPROC                             gl3wVertexAttrib4dv;\nPFNGLVERTEXATTRIB4FPROC                              gl3wVertexAttrib4f;\nPFNGLVERTEXATTRIB4FVPROC                             gl3wVertexAttrib4fv;\nPFNGLVERTEXATTRIB4IVPROC                             gl3wVertexAttrib4iv;\nPFNGLVERTEXATTRIB4SPROC                              gl3wVertexAttrib4s;\nPFNGLVERTEXATTRIB4SVPROC                             gl3wVertexAttrib4sv;\nPFNGLVERTEXATTRIB4UBVPROC                            gl3wVertexAttrib4ubv;\nPFNGLVERTEXATTRIB4UIVPROC                            gl3wVertexAttrib4uiv;\nPFNGLVERTEXATTRIB4USVPROC                            gl3wVertexAttrib4usv;\nPFNGLVERTEXATTRIBBINDINGPROC                         gl3wVertexAttribBinding;\nPFNGLVERTEXATTRIBDIVISORPROC                         gl3wVertexAttribDivisor;\nPFNGLVERTEXATTRIBFORMATPROC                          gl3wVertexAttribFormat;\nPFNGLVERTEXATTRIBI1IPROC                             gl3wVertexAttribI1i;\nPFNGLVERTEXATTRIBI1IVPROC                            gl3wVertexAttribI1iv;\nPFNGLVERTEXATTRIBI1UIPROC                            gl3wVertexAttribI1ui;\nPFNGLVERTEXATTRIBI1UIVPROC                           gl3wVertexAttribI1uiv;\nPFNGLVERTEXATTRIBI2IPROC                             gl3wVertexAttribI2i;\nPFNGLVERTEXATTRIBI2IVPROC                            gl3wVertexAttribI2iv;\nPFNGLVERTEXATTRIBI2UIPROC                            gl3wVertexAttribI2ui;\nPFNGLVERTEXATTRIBI2UIVPROC                           gl3wVertexAttribI2uiv;\nPFNGLVERTEXATTRIBI3IPROC                             gl3wVertexAttribI3i;\nPFNGLVERTEXATTRIBI3IVPROC                            gl3wVertexAttribI3iv;\nPFNGLVERTEXATTRIBI3UIPROC                            gl3wVertexAttribI3ui;\nPFNGLVERTEXATTRIBI3UIVPROC                           gl3wVertexAttribI3uiv;\nPFNGLVERTEXATTRIBI4BVPROC                            gl3wVertexAttribI4bv;\nPFNGLVERTEXATTRIBI4IPROC                             gl3wVertexAttribI4i;\nPFNGLVERTEXATTRIBI4IVPROC                            gl3wVertexAttribI4iv;\nPFNGLVERTEXATTRIBI4SVPROC                            gl3wVertexAttribI4sv;\nPFNGLVERTEXATTRIBI4UBVPROC                           gl3wVertexAttribI4ubv;\nPFNGLVERTEXATTRIBI4UIPROC                            gl3wVertexAttribI4ui;\nPFNGLVERTEXATTRIBI4UIVPROC                           gl3wVertexAttribI4uiv;\nPFNGLVERTEXATTRIBI4USVPROC                           gl3wVertexAttribI4usv;\nPFNGLVERTEXATTRIBIFORMATPROC                         gl3wVertexAttribIFormat;\nPFNGLVERTEXATTRIBIPOINTERPROC                        gl3wVertexAttribIPointer;\nPFNGLVERTEXATTRIBL1DPROC                             gl3wVertexAttribL1d;\nPFNGLVERTEXATTRIBL1DVPROC                            gl3wVertexAttribL1dv;\nPFNGLVERTEXATTRIBL1UI64ARBPROC                       gl3wVertexAttribL1ui64ARB;\nPFNGLVERTEXATTRIBL1UI64VARBPROC                      gl3wVertexAttribL1ui64vARB;\nPFNGLVERTEXATTRIBL2DPROC                             gl3wVertexAttribL2d;\nPFNGLVERTEXATTRIBL2DVPROC                            gl3wVertexAttribL2dv;\nPFNGLVERTEXATTRIBL3DPROC                             gl3wVertexAttribL3d;\nPFNGLVERTEXATTRIBL3DVPROC                            gl3wVertexAttribL3dv;\nPFNGLVERTEXATTRIBL4DPROC                             gl3wVertexAttribL4d;\nPFNGLVERTEXATTRIBL4DVPROC                            gl3wVertexAttribL4dv;\nPFNGLVERTEXATTRIBLFORMATPROC                         gl3wVertexAttribLFormat;\nPFNGLVERTEXATTRIBLPOINTERPROC                        gl3wVertexAttribLPointer;\nPFNGLVERTEXATTRIBP1UIPROC                            gl3wVertexAttribP1ui;\nPFNGLVERTEXATTRIBP1UIVPROC                           gl3wVertexAttribP1uiv;\nPFNGLVERTEXATTRIBP2UIPROC                            gl3wVertexAttribP2ui;\nPFNGLVERTEXATTRIBP2UIVPROC                           gl3wVertexAttribP2uiv;\nPFNGLVERTEXATTRIBP3UIPROC                            gl3wVertexAttribP3ui;\nPFNGLVERTEXATTRIBP3UIVPROC                           gl3wVertexAttribP3uiv;\nPFNGLVERTEXATTRIBP4UIPROC                            gl3wVertexAttribP4ui;\nPFNGLVERTEXATTRIBP4UIVPROC                           gl3wVertexAttribP4uiv;\nPFNGLVERTEXATTRIBPOINTERPROC                         gl3wVertexAttribPointer;\nPFNGLVERTEXBINDINGDIVISORPROC                        gl3wVertexBindingDivisor;\nPFNGLVIEWPORTPROC                                    gl3wViewport;\nPFNGLVIEWPORTARRAYVPROC                              gl3wViewportArrayv;\nPFNGLVIEWPORTINDEXEDFPROC                            gl3wViewportIndexedf;\nPFNGLVIEWPORTINDEXEDFVPROC                           gl3wViewportIndexedfv;\nPFNGLWAITSYNCPROC                                    gl3wWaitSync;\n\n/* --------------------------------------------------------------------------------------------- */\n\nstatic void gl3w_load_all_functions(void)\n{\n\tgl3wActiveShaderProgram                         = ( PFNGLACTIVESHADERPROGRAMPROC                         ) gl3w_fn(\"glActiveShaderProgram\");\n\tgl3wActiveTexture                               = ( PFNGLACTIVETEXTUREPROC                               ) gl3w_fn(\"glActiveTexture\");\n\tgl3wAttachShader                                = ( PFNGLATTACHSHADERPROC                                ) gl3w_fn(\"glAttachShader\");\n\tgl3wBeginConditionalRender                      = ( PFNGLBEGINCONDITIONALRENDERPROC                      ) gl3w_fn(\"glBeginConditionalRender\");\n\tgl3wBeginQuery                                  = ( PFNGLBEGINQUERYPROC                                  ) gl3w_fn(\"glBeginQuery\");\n\tgl3wBeginQueryIndexed                           = ( PFNGLBEGINQUERYINDEXEDPROC                           ) gl3w_fn(\"glBeginQueryIndexed\");\n\tgl3wBeginTransformFeedback                      = ( PFNGLBEGINTRANSFORMFEEDBACKPROC                      ) gl3w_fn(\"glBeginTransformFeedback\");\n\tgl3wBindAttribLocation                          = ( PFNGLBINDATTRIBLOCATIONPROC                          ) gl3w_fn(\"glBindAttribLocation\");\n\tgl3wBindBuffer                                  = ( PFNGLBINDBUFFERPROC                                  ) gl3w_fn(\"glBindBuffer\");\n\tgl3wBindBufferBase                              = ( PFNGLBINDBUFFERBASEPROC                              ) gl3w_fn(\"glBindBufferBase\");\n\tgl3wBindBufferRange                             = ( PFNGLBINDBUFFERRANGEPROC                             ) gl3w_fn(\"glBindBufferRange\");\n\tgl3wBindBuffersBase                             = ( PFNGLBINDBUFFERSBASEPROC                             ) gl3w_fn(\"glBindBuffersBase\");\n\tgl3wBindBuffersRange                            = ( PFNGLBINDBUFFERSRANGEPROC                            ) gl3w_fn(\"glBindBuffersRange\");\n\tgl3wBindFragDataLocation                        = ( PFNGLBINDFRAGDATALOCATIONPROC                        ) gl3w_fn(\"glBindFragDataLocation\");\n\tgl3wBindFragDataLocationIndexed                 = ( PFNGLBINDFRAGDATALOCATIONINDEXEDPROC                 ) gl3w_fn(\"glBindFragDataLocationIndexed\");\n\tgl3wBindFramebuffer                             = ( PFNGLBINDFRAMEBUFFERPROC                             ) gl3w_fn(\"glBindFramebuffer\");\n\tgl3wBindImageTexture                            = ( PFNGLBINDIMAGETEXTUREPROC                            ) gl3w_fn(\"glBindImageTexture\");\n\tgl3wBindImageTextures                           = ( PFNGLBINDIMAGETEXTURESPROC                           ) gl3w_fn(\"glBindImageTextures\");\n\tgl3wBindProgramPipeline                         = ( PFNGLBINDPROGRAMPIPELINEPROC                         ) gl3w_fn(\"glBindProgramPipeline\");\n\tgl3wBindRenderbuffer                            = ( PFNGLBINDRENDERBUFFERPROC                            ) gl3w_fn(\"glBindRenderbuffer\");\n\tgl3wBindSampler                                 = ( PFNGLBINDSAMPLERPROC                                 ) gl3w_fn(\"glBindSampler\");\n\tgl3wBindSamplers                                = ( PFNGLBINDSAMPLERSPROC                                ) gl3w_fn(\"glBindSamplers\");\n\tgl3wBindTexture                                 = ( PFNGLBINDTEXTUREPROC                                 ) gl3w_fn(\"glBindTexture\");\n\tgl3wBindTextureUnit                             = ( PFNGLBINDTEXTUREUNITPROC                             ) gl3w_fn(\"glBindTextureUnit\");\n\tgl3wBindTextures                                = ( PFNGLBINDTEXTURESPROC                                ) gl3w_fn(\"glBindTextures\");\n\tgl3wBindTransformFeedback                       = ( PFNGLBINDTRANSFORMFEEDBACKPROC                       ) gl3w_fn(\"glBindTransformFeedback\");\n\tgl3wBindVertexArray                             = ( PFNGLBINDVERTEXARRAYPROC                             ) gl3w_fn(\"glBindVertexArray\");\n\tgl3wBindVertexBuffer                            = ( PFNGLBINDVERTEXBUFFERPROC                            ) gl3w_fn(\"glBindVertexBuffer\");\n\tgl3wBindVertexBuffers                           = ( PFNGLBINDVERTEXBUFFERSPROC                           ) gl3w_fn(\"glBindVertexBuffers\");\n\tgl3wBlendColor                                  = ( PFNGLBLENDCOLORPROC                                  ) gl3w_fn(\"glBlendColor\");\n\tgl3wBlendEquation                               = ( PFNGLBLENDEQUATIONPROC                               ) gl3w_fn(\"glBlendEquation\");\n\tgl3wBlendEquationSeparate                       = ( PFNGLBLENDEQUATIONSEPARATEPROC                       ) gl3w_fn(\"glBlendEquationSeparate\");\n\tgl3wBlendEquationSeparatei                      = ( PFNGLBLENDEQUATIONSEPARATEIPROC                      ) gl3w_fn(\"glBlendEquationSeparatei\");\n\tgl3wBlendEquationSeparateiARB                   = ( PFNGLBLENDEQUATIONSEPARATEIARBPROC                   ) gl3w_fn(\"glBlendEquationSeparateiARB\");\n\tgl3wBlendEquationi                              = ( PFNGLBLENDEQUATIONIPROC                              ) gl3w_fn(\"glBlendEquationi\");\n\tgl3wBlendEquationiARB                           = ( PFNGLBLENDEQUATIONIARBPROC                           ) gl3w_fn(\"glBlendEquationiARB\");\n\tgl3wBlendFunc                                   = ( PFNGLBLENDFUNCPROC                                   ) gl3w_fn(\"glBlendFunc\");\n\tgl3wBlendFuncSeparate                           = ( PFNGLBLENDFUNCSEPARATEPROC                           ) gl3w_fn(\"glBlendFuncSeparate\");\n\tgl3wBlendFuncSeparatei                          = ( PFNGLBLENDFUNCSEPARATEIPROC                          ) gl3w_fn(\"glBlendFuncSeparatei\");\n\tgl3wBlendFuncSeparateiARB                       = ( PFNGLBLENDFUNCSEPARATEIARBPROC                       ) gl3w_fn(\"glBlendFuncSeparateiARB\");\n\tgl3wBlendFunci                                  = ( PFNGLBLENDFUNCIPROC                                  ) gl3w_fn(\"glBlendFunci\");\n\tgl3wBlendFunciARB                               = ( PFNGLBLENDFUNCIARBPROC                               ) gl3w_fn(\"glBlendFunciARB\");\n\tgl3wBlitFramebuffer                             = ( PFNGLBLITFRAMEBUFFERPROC                             ) gl3w_fn(\"glBlitFramebuffer\");\n\tgl3wBlitNamedFramebuffer                        = ( PFNGLBLITNAMEDFRAMEBUFFERPROC                        ) gl3w_fn(\"glBlitNamedFramebuffer\");\n\tgl3wBufferData                                  = ( PFNGLBUFFERDATAPROC                                  ) gl3w_fn(\"glBufferData\");\n\tgl3wBufferPageCommitmentARB                     = ( PFNGLBUFFERPAGECOMMITMENTARBPROC                     ) gl3w_fn(\"glBufferPageCommitmentARB\");\n\tgl3wBufferStorage                               = ( PFNGLBUFFERSTORAGEPROC                               ) gl3w_fn(\"glBufferStorage\");\n\tgl3wBufferSubData                               = ( PFNGLBUFFERSUBDATAPROC                               ) gl3w_fn(\"glBufferSubData\");\n\tgl3wCheckFramebufferStatus                      = ( PFNGLCHECKFRAMEBUFFERSTATUSPROC                      ) gl3w_fn(\"glCheckFramebufferStatus\");\n\tgl3wCheckNamedFramebufferStatus                 = ( PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC                 ) gl3w_fn(\"glCheckNamedFramebufferStatus\");\n\tgl3wClampColor                                  = ( PFNGLCLAMPCOLORPROC                                  ) gl3w_fn(\"glClampColor\");\n\tgl3wClear                                       = ( PFNGLCLEARPROC                                       ) gl3w_fn(\"glClear\");\n\tgl3wClearBufferData                             = ( PFNGLCLEARBUFFERDATAPROC                             ) gl3w_fn(\"glClearBufferData\");\n\tgl3wClearBufferSubData                          = ( PFNGLCLEARBUFFERSUBDATAPROC                          ) gl3w_fn(\"glClearBufferSubData\");\n\tgl3wClearBufferfi                               = ( PFNGLCLEARBUFFERFIPROC                               ) gl3w_fn(\"glClearBufferfi\");\n\tgl3wClearBufferfv                               = ( PFNGLCLEARBUFFERFVPROC                               ) gl3w_fn(\"glClearBufferfv\");\n\tgl3wClearBufferiv                               = ( PFNGLCLEARBUFFERIVPROC                               ) gl3w_fn(\"glClearBufferiv\");\n\tgl3wClearBufferuiv                              = ( PFNGLCLEARBUFFERUIVPROC                              ) gl3w_fn(\"glClearBufferuiv\");\n\tgl3wClearColor                                  = ( PFNGLCLEARCOLORPROC                                  ) gl3w_fn(\"glClearColor\");\n\tgl3wClearDepth                                  = ( PFNGLCLEARDEPTHPROC                                  ) gl3w_fn(\"glClearDepth\");\n\tgl3wClearDepthf                                 = ( PFNGLCLEARDEPTHFPROC                                 ) gl3w_fn(\"glClearDepthf\");\n\tgl3wClearNamedBufferData                        = ( PFNGLCLEARNAMEDBUFFERDATAPROC                        ) gl3w_fn(\"glClearNamedBufferData\");\n\tgl3wClearNamedBufferSubData                     = ( PFNGLCLEARNAMEDBUFFERSUBDATAPROC                     ) gl3w_fn(\"glClearNamedBufferSubData\");\n\tgl3wClearNamedFramebufferfi                     = ( PFNGLCLEARNAMEDFRAMEBUFFERFIPROC                     ) gl3w_fn(\"glClearNamedFramebufferfi\");\n\tgl3wClearNamedFramebufferfv                     = ( PFNGLCLEARNAMEDFRAMEBUFFERFVPROC                     ) gl3w_fn(\"glClearNamedFramebufferfv\");\n\tgl3wClearNamedFramebufferiv                     = ( PFNGLCLEARNAMEDFRAMEBUFFERIVPROC                     ) gl3w_fn(\"glClearNamedFramebufferiv\");\n\tgl3wClearNamedFramebufferuiv                    = ( PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC                    ) gl3w_fn(\"glClearNamedFramebufferuiv\");\n\tgl3wClearStencil                                = ( PFNGLCLEARSTENCILPROC                                ) gl3w_fn(\"glClearStencil\");\n\tgl3wClearTexImage                               = ( PFNGLCLEARTEXIMAGEPROC                               ) gl3w_fn(\"glClearTexImage\");\n\tgl3wClearTexSubImage                            = ( PFNGLCLEARTEXSUBIMAGEPROC                            ) gl3w_fn(\"glClearTexSubImage\");\n\tgl3wClientWaitSync                              = ( PFNGLCLIENTWAITSYNCPROC                              ) gl3w_fn(\"glClientWaitSync\");\n\tgl3wClipControl                                 = ( PFNGLCLIPCONTROLPROC                                 ) gl3w_fn(\"glClipControl\");\n\tgl3wColorMask                                   = ( PFNGLCOLORMASKPROC                                   ) gl3w_fn(\"glColorMask\");\n\tgl3wColorMaski                                  = ( PFNGLCOLORMASKIPROC                                  ) gl3w_fn(\"glColorMaski\");\n\tgl3wCompileShader                               = ( PFNGLCOMPILESHADERPROC                               ) gl3w_fn(\"glCompileShader\");\n\tgl3wCompileShaderIncludeARB                     = ( PFNGLCOMPILESHADERINCLUDEARBPROC                     ) gl3w_fn(\"glCompileShaderIncludeARB\");\n\tgl3wCompressedTexImage1D                        = ( PFNGLCOMPRESSEDTEXIMAGE1DPROC                        ) gl3w_fn(\"glCompressedTexImage1D\");\n\tgl3wCompressedTexImage2D                        = ( PFNGLCOMPRESSEDTEXIMAGE2DPROC                        ) gl3w_fn(\"glCompressedTexImage2D\");\n\tgl3wCompressedTexImage3D                        = ( PFNGLCOMPRESSEDTEXIMAGE3DPROC                        ) gl3w_fn(\"glCompressedTexImage3D\");\n\tgl3wCompressedTexSubImage1D                     = ( PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC                     ) gl3w_fn(\"glCompressedTexSubImage1D\");\n\tgl3wCompressedTexSubImage2D                     = ( PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC                     ) gl3w_fn(\"glCompressedTexSubImage2D\");\n\tgl3wCompressedTexSubImage3D                     = ( PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC                     ) gl3w_fn(\"glCompressedTexSubImage3D\");\n\tgl3wCompressedTextureSubImage1D                 = ( PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC                 ) gl3w_fn(\"glCompressedTextureSubImage1D\");\n\tgl3wCompressedTextureSubImage2D                 = ( PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC                 ) gl3w_fn(\"glCompressedTextureSubImage2D\");\n\tgl3wCompressedTextureSubImage3D                 = ( PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC                 ) gl3w_fn(\"glCompressedTextureSubImage3D\");\n\tgl3wCopyBufferSubData                           = ( PFNGLCOPYBUFFERSUBDATAPROC                           ) gl3w_fn(\"glCopyBufferSubData\");\n\tgl3wCopyImageSubData                            = ( PFNGLCOPYIMAGESUBDATAPROC                            ) gl3w_fn(\"glCopyImageSubData\");\n\tgl3wCopyNamedBufferSubData                      = ( PFNGLCOPYNAMEDBUFFERSUBDATAPROC                      ) gl3w_fn(\"glCopyNamedBufferSubData\");\n\tgl3wCopyTexImage1D                              = ( PFNGLCOPYTEXIMAGE1DPROC                              ) gl3w_fn(\"glCopyTexImage1D\");\n\tgl3wCopyTexImage2D                              = ( PFNGLCOPYTEXIMAGE2DPROC                              ) gl3w_fn(\"glCopyTexImage2D\");\n\tgl3wCopyTexSubImage1D                           = ( PFNGLCOPYTEXSUBIMAGE1DPROC                           ) gl3w_fn(\"glCopyTexSubImage1D\");\n\tgl3wCopyTexSubImage2D                           = ( PFNGLCOPYTEXSUBIMAGE2DPROC                           ) gl3w_fn(\"glCopyTexSubImage2D\");\n\tgl3wCopyTexSubImage3D                           = ( PFNGLCOPYTEXSUBIMAGE3DPROC                           ) gl3w_fn(\"glCopyTexSubImage3D\");\n\tgl3wCopyTextureSubImage1D                       = ( PFNGLCOPYTEXTURESUBIMAGE1DPROC                       ) gl3w_fn(\"glCopyTextureSubImage1D\");\n\tgl3wCopyTextureSubImage2D                       = ( PFNGLCOPYTEXTURESUBIMAGE2DPROC                       ) gl3w_fn(\"glCopyTextureSubImage2D\");\n\tgl3wCopyTextureSubImage3D                       = ( PFNGLCOPYTEXTURESUBIMAGE3DPROC                       ) gl3w_fn(\"glCopyTextureSubImage3D\");\n\tgl3wCreateBuffers                               = ( PFNGLCREATEBUFFERSPROC                               ) gl3w_fn(\"glCreateBuffers\");\n\tgl3wCreateFramebuffers                          = ( PFNGLCREATEFRAMEBUFFERSPROC                          ) gl3w_fn(\"glCreateFramebuffers\");\n\tgl3wCreateProgram                               = ( PFNGLCREATEPROGRAMPROC                               ) gl3w_fn(\"glCreateProgram\");\n\tgl3wCreateProgramPipelines                      = ( PFNGLCREATEPROGRAMPIPELINESPROC                      ) gl3w_fn(\"glCreateProgramPipelines\");\n\tgl3wCreateQueries                               = ( PFNGLCREATEQUERIESPROC                               ) gl3w_fn(\"glCreateQueries\");\n\tgl3wCreateRenderbuffers                         = ( PFNGLCREATERENDERBUFFERSPROC                         ) gl3w_fn(\"glCreateRenderbuffers\");\n\tgl3wCreateSamplers                              = ( PFNGLCREATESAMPLERSPROC                              ) gl3w_fn(\"glCreateSamplers\");\n\tgl3wCreateShader                                = ( PFNGLCREATESHADERPROC                                ) gl3w_fn(\"glCreateShader\");\n\tgl3wCreateShaderProgramv                        = ( PFNGLCREATESHADERPROGRAMVPROC                        ) gl3w_fn(\"glCreateShaderProgramv\");\n\tgl3wCreateSyncFromCLeventARB                    = ( PFNGLCREATESYNCFROMCLEVENTARBPROC                    ) gl3w_fn(\"glCreateSyncFromCLeventARB\");\n\tgl3wCreateTextures                              = ( PFNGLCREATETEXTURESPROC                              ) gl3w_fn(\"glCreateTextures\");\n\tgl3wCreateTransformFeedbacks                    = ( PFNGLCREATETRANSFORMFEEDBACKSPROC                    ) gl3w_fn(\"glCreateTransformFeedbacks\");\n\tgl3wCreateVertexArrays                          = ( PFNGLCREATEVERTEXARRAYSPROC                          ) gl3w_fn(\"glCreateVertexArrays\");\n\tgl3wCullFace                                    = ( PFNGLCULLFACEPROC                                    ) gl3w_fn(\"glCullFace\");\n\tgl3wDebugMessageCallback                        = ( PFNGLDEBUGMESSAGECALLBACKPROC                        ) gl3w_fn(\"glDebugMessageCallback\");\n\tgl3wDebugMessageCallbackARB                     = ( PFNGLDEBUGMESSAGECALLBACKARBPROC                     ) gl3w_fn(\"glDebugMessageCallbackARB\");\n\tgl3wDebugMessageControl                         = ( PFNGLDEBUGMESSAGECONTROLPROC                         ) gl3w_fn(\"glDebugMessageControl\");\n\tgl3wDebugMessageControlARB                      = ( PFNGLDEBUGMESSAGECONTROLARBPROC                      ) gl3w_fn(\"glDebugMessageControlARB\");\n\tgl3wDebugMessageInsert                          = ( PFNGLDEBUGMESSAGEINSERTPROC                          ) gl3w_fn(\"glDebugMessageInsert\");\n\tgl3wDebugMessageInsertARB                       = ( PFNGLDEBUGMESSAGEINSERTARBPROC                       ) gl3w_fn(\"glDebugMessageInsertARB\");\n\tgl3wDeleteBuffers                               = ( PFNGLDELETEBUFFERSPROC                               ) gl3w_fn(\"glDeleteBuffers\");\n\tgl3wDeleteFramebuffers                          = ( PFNGLDELETEFRAMEBUFFERSPROC                          ) gl3w_fn(\"glDeleteFramebuffers\");\n\tgl3wDeleteNamedStringARB                        = ( PFNGLDELETENAMEDSTRINGARBPROC                        ) gl3w_fn(\"glDeleteNamedStringARB\");\n\tgl3wDeleteProgram                               = ( PFNGLDELETEPROGRAMPROC                               ) gl3w_fn(\"glDeleteProgram\");\n\tgl3wDeleteProgramPipelines                      = ( PFNGLDELETEPROGRAMPIPELINESPROC                      ) gl3w_fn(\"glDeleteProgramPipelines\");\n\tgl3wDeleteQueries                               = ( PFNGLDELETEQUERIESPROC                               ) gl3w_fn(\"glDeleteQueries\");\n\tgl3wDeleteRenderbuffers                         = ( PFNGLDELETERENDERBUFFERSPROC                         ) gl3w_fn(\"glDeleteRenderbuffers\");\n\tgl3wDeleteSamplers                              = ( PFNGLDELETESAMPLERSPROC                              ) gl3w_fn(\"glDeleteSamplers\");\n\tgl3wDeleteShader                                = ( PFNGLDELETESHADERPROC                                ) gl3w_fn(\"glDeleteShader\");\n\tgl3wDeleteSync                                  = ( PFNGLDELETESYNCPROC                                  ) gl3w_fn(\"glDeleteSync\");\n\tgl3wDeleteTextures                              = ( PFNGLDELETETEXTURESPROC                              ) gl3w_fn(\"glDeleteTextures\");\n\tgl3wDeleteTransformFeedbacks                    = ( PFNGLDELETETRANSFORMFEEDBACKSPROC                    ) gl3w_fn(\"glDeleteTransformFeedbacks\");\n\tgl3wDeleteVertexArrays                          = ( PFNGLDELETEVERTEXARRAYSPROC                          ) gl3w_fn(\"glDeleteVertexArrays\");\n\tgl3wDepthFunc                                   = ( PFNGLDEPTHFUNCPROC                                   ) gl3w_fn(\"glDepthFunc\");\n\tgl3wDepthMask                                   = ( PFNGLDEPTHMASKPROC                                   ) gl3w_fn(\"glDepthMask\");\n\tgl3wDepthRange                                  = ( PFNGLDEPTHRANGEPROC                                  ) gl3w_fn(\"glDepthRange\");\n\tgl3wDepthRangeArrayv                            = ( PFNGLDEPTHRANGEARRAYVPROC                            ) gl3w_fn(\"glDepthRangeArrayv\");\n\tgl3wDepthRangeIndexed                           = ( PFNGLDEPTHRANGEINDEXEDPROC                           ) gl3w_fn(\"glDepthRangeIndexed\");\n\tgl3wDepthRangef                                 = ( PFNGLDEPTHRANGEFPROC                                 ) gl3w_fn(\"glDepthRangef\");\n\tgl3wDetachShader                                = ( PFNGLDETACHSHADERPROC                                ) gl3w_fn(\"glDetachShader\");\n\tgl3wDisable                                     = ( PFNGLDISABLEPROC                                     ) gl3w_fn(\"glDisable\");\n\tgl3wDisableVertexArrayAttrib                    = ( PFNGLDISABLEVERTEXARRAYATTRIBPROC                    ) gl3w_fn(\"glDisableVertexArrayAttrib\");\n\tgl3wDisableVertexAttribArray                    = ( PFNGLDISABLEVERTEXATTRIBARRAYPROC                    ) gl3w_fn(\"glDisableVertexAttribArray\");\n\tgl3wDisablei                                    = ( PFNGLDISABLEIPROC                                    ) gl3w_fn(\"glDisablei\");\n\tgl3wDispatchCompute                             = ( PFNGLDISPATCHCOMPUTEPROC                             ) gl3w_fn(\"glDispatchCompute\");\n\tgl3wDispatchComputeGroupSizeARB                 = ( PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC                 ) gl3w_fn(\"glDispatchComputeGroupSizeARB\");\n\tgl3wDispatchComputeIndirect                     = ( PFNGLDISPATCHCOMPUTEINDIRECTPROC                     ) gl3w_fn(\"glDispatchComputeIndirect\");\n\tgl3wDrawArrays                                  = ( PFNGLDRAWARRAYSPROC                                  ) gl3w_fn(\"glDrawArrays\");\n\tgl3wDrawArraysIndirect                          = ( PFNGLDRAWARRAYSINDIRECTPROC                          ) gl3w_fn(\"glDrawArraysIndirect\");\n\tgl3wDrawArraysInstanced                         = ( PFNGLDRAWARRAYSINSTANCEDPROC                         ) gl3w_fn(\"glDrawArraysInstanced\");\n\tgl3wDrawArraysInstancedBaseInstance             = ( PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC             ) gl3w_fn(\"glDrawArraysInstancedBaseInstance\");\n\tgl3wDrawBuffer                                  = ( PFNGLDRAWBUFFERPROC                                  ) gl3w_fn(\"glDrawBuffer\");\n\tgl3wDrawBuffers                                 = ( PFNGLDRAWBUFFERSPROC                                 ) gl3w_fn(\"glDrawBuffers\");\n\tgl3wDrawElements                                = ( PFNGLDRAWELEMENTSPROC                                ) gl3w_fn(\"glDrawElements\");\n\tgl3wDrawElementsBaseVertex                      = ( PFNGLDRAWELEMENTSBASEVERTEXPROC                      ) gl3w_fn(\"glDrawElementsBaseVertex\");\n\tgl3wDrawElementsIndirect                        = ( PFNGLDRAWELEMENTSINDIRECTPROC                        ) gl3w_fn(\"glDrawElementsIndirect\");\n\tgl3wDrawElementsInstanced                       = ( PFNGLDRAWELEMENTSINSTANCEDPROC                       ) gl3w_fn(\"glDrawElementsInstanced\");\n\tgl3wDrawElementsInstancedBaseInstance           = ( PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC           ) gl3w_fn(\"glDrawElementsInstancedBaseInstance\");\n\tgl3wDrawElementsInstancedBaseVertex             = ( PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC             ) gl3w_fn(\"glDrawElementsInstancedBaseVertex\");\n\tgl3wDrawElementsInstancedBaseVertexBaseInstance = ( PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC ) gl3w_fn(\"glDrawElementsInstancedBaseVertexBaseInstance\");\n\tgl3wDrawRangeElements                           = ( PFNGLDRAWRANGEELEMENTSPROC                           ) gl3w_fn(\"glDrawRangeElements\");\n\tgl3wDrawRangeElementsBaseVertex                 = ( PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC                 ) gl3w_fn(\"glDrawRangeElementsBaseVertex\");\n\tgl3wDrawTransformFeedback                       = ( PFNGLDRAWTRANSFORMFEEDBACKPROC                       ) gl3w_fn(\"glDrawTransformFeedback\");\n\tgl3wDrawTransformFeedbackInstanced              = ( PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC              ) gl3w_fn(\"glDrawTransformFeedbackInstanced\");\n\tgl3wDrawTransformFeedbackStream                 = ( PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC                 ) gl3w_fn(\"glDrawTransformFeedbackStream\");\n\tgl3wDrawTransformFeedbackStreamInstanced        = ( PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC        ) gl3w_fn(\"glDrawTransformFeedbackStreamInstanced\");\n\tgl3wEnable                                      = ( PFNGLENABLEPROC                                      ) gl3w_fn(\"glEnable\");\n\tgl3wEnableVertexArrayAttrib                     = ( PFNGLENABLEVERTEXARRAYATTRIBPROC                     ) gl3w_fn(\"glEnableVertexArrayAttrib\");\n\tgl3wEnableVertexAttribArray                     = ( PFNGLENABLEVERTEXATTRIBARRAYPROC                     ) gl3w_fn(\"glEnableVertexAttribArray\");\n\tgl3wEnablei                                     = ( PFNGLENABLEIPROC                                     ) gl3w_fn(\"glEnablei\");\n\tgl3wEndConditionalRender                        = ( PFNGLENDCONDITIONALRENDERPROC                        ) gl3w_fn(\"glEndConditionalRender\");\n\tgl3wEndQuery                                    = ( PFNGLENDQUERYPROC                                    ) gl3w_fn(\"glEndQuery\");\n\tgl3wEndQueryIndexed                             = ( PFNGLENDQUERYINDEXEDPROC                             ) gl3w_fn(\"glEndQueryIndexed\");\n\tgl3wEndTransformFeedback                        = ( PFNGLENDTRANSFORMFEEDBACKPROC                        ) gl3w_fn(\"glEndTransformFeedback\");\n\tgl3wFenceSync                                   = ( PFNGLFENCESYNCPROC                                   ) gl3w_fn(\"glFenceSync\");\n\tgl3wFinish                                      = ( PFNGLFINISHPROC                                      ) gl3w_fn(\"glFinish\");\n\tgl3wFlush                                       = ( PFNGLFLUSHPROC                                       ) gl3w_fn(\"glFlush\");\n\tgl3wFlushMappedBufferRange                      = ( PFNGLFLUSHMAPPEDBUFFERRANGEPROC                      ) gl3w_fn(\"glFlushMappedBufferRange\");\n\tgl3wFlushMappedNamedBufferRange                 = ( PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC                 ) gl3w_fn(\"glFlushMappedNamedBufferRange\");\n\tgl3wFramebufferParameteri                       = ( PFNGLFRAMEBUFFERPARAMETERIPROC                       ) gl3w_fn(\"glFramebufferParameteri\");\n\tgl3wFramebufferRenderbuffer                     = ( PFNGLFRAMEBUFFERRENDERBUFFERPROC                     ) gl3w_fn(\"glFramebufferRenderbuffer\");\n\tgl3wFramebufferTexture                          = ( PFNGLFRAMEBUFFERTEXTUREPROC                          ) gl3w_fn(\"glFramebufferTexture\");\n\tgl3wFramebufferTexture1D                        = ( PFNGLFRAMEBUFFERTEXTURE1DPROC                        ) gl3w_fn(\"glFramebufferTexture1D\");\n\tgl3wFramebufferTexture2D                        = ( PFNGLFRAMEBUFFERTEXTURE2DPROC                        ) gl3w_fn(\"glFramebufferTexture2D\");\n\tgl3wFramebufferTexture3D                        = ( PFNGLFRAMEBUFFERTEXTURE3DPROC                        ) gl3w_fn(\"glFramebufferTexture3D\");\n\tgl3wFramebufferTextureLayer                     = ( PFNGLFRAMEBUFFERTEXTURELAYERPROC                     ) gl3w_fn(\"glFramebufferTextureLayer\");\n\tgl3wFrontFace                                   = ( PFNGLFRONTFACEPROC                                   ) gl3w_fn(\"glFrontFace\");\n\tgl3wGenBuffers                                  = ( PFNGLGENBUFFERSPROC                                  ) gl3w_fn(\"glGenBuffers\");\n\tgl3wGenFramebuffers                             = ( PFNGLGENFRAMEBUFFERSPROC                             ) gl3w_fn(\"glGenFramebuffers\");\n\tgl3wGenProgramPipelines                         = ( PFNGLGENPROGRAMPIPELINESPROC                         ) gl3w_fn(\"glGenProgramPipelines\");\n\tgl3wGenQueries                                  = ( PFNGLGENQUERIESPROC                                  ) gl3w_fn(\"glGenQueries\");\n\tgl3wGenRenderbuffers                            = ( PFNGLGENRENDERBUFFERSPROC                            ) gl3w_fn(\"glGenRenderbuffers\");\n\tgl3wGenSamplers                                 = ( PFNGLGENSAMPLERSPROC                                 ) gl3w_fn(\"glGenSamplers\");\n\tgl3wGenTextures                                 = ( PFNGLGENTEXTURESPROC                                 ) gl3w_fn(\"glGenTextures\");\n\tgl3wGenTransformFeedbacks                       = ( PFNGLGENTRANSFORMFEEDBACKSPROC                       ) gl3w_fn(\"glGenTransformFeedbacks\");\n\tgl3wGenVertexArrays                             = ( PFNGLGENVERTEXARRAYSPROC                             ) gl3w_fn(\"glGenVertexArrays\");\n\tgl3wGenerateMipmap                              = ( PFNGLGENERATEMIPMAPPROC                              ) gl3w_fn(\"glGenerateMipmap\");\n\tgl3wGenerateTextureMipmap                       = ( PFNGLGENERATETEXTUREMIPMAPPROC                       ) gl3w_fn(\"glGenerateTextureMipmap\");\n\tgl3wGetActiveAtomicCounterBufferiv              = ( PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC              ) gl3w_fn(\"glGetActiveAtomicCounterBufferiv\");\n\tgl3wGetActiveAttrib                             = ( PFNGLGETACTIVEATTRIBPROC                             ) gl3w_fn(\"glGetActiveAttrib\");\n\tgl3wGetActiveSubroutineName                     = ( PFNGLGETACTIVESUBROUTINENAMEPROC                     ) gl3w_fn(\"glGetActiveSubroutineName\");\n\tgl3wGetActiveSubroutineUniformName              = ( PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC              ) gl3w_fn(\"glGetActiveSubroutineUniformName\");\n\tgl3wGetActiveSubroutineUniformiv                = ( PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC                ) gl3w_fn(\"glGetActiveSubroutineUniformiv\");\n\tgl3wGetActiveUniform                            = ( PFNGLGETACTIVEUNIFORMPROC                            ) gl3w_fn(\"glGetActiveUniform\");\n\tgl3wGetActiveUniformBlockName                   = ( PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC                   ) gl3w_fn(\"glGetActiveUniformBlockName\");\n\tgl3wGetActiveUniformBlockiv                     = ( PFNGLGETACTIVEUNIFORMBLOCKIVPROC                     ) gl3w_fn(\"glGetActiveUniformBlockiv\");\n\tgl3wGetActiveUniformName                        = ( PFNGLGETACTIVEUNIFORMNAMEPROC                        ) gl3w_fn(\"glGetActiveUniformName\");\n\tgl3wGetActiveUniformsiv                         = ( PFNGLGETACTIVEUNIFORMSIVPROC                         ) gl3w_fn(\"glGetActiveUniformsiv\");\n\tgl3wGetAttachedShaders                          = ( PFNGLGETATTACHEDSHADERSPROC                          ) gl3w_fn(\"glGetAttachedShaders\");\n\tgl3wGetAttribLocation                           = ( PFNGLGETATTRIBLOCATIONPROC                           ) gl3w_fn(\"glGetAttribLocation\");\n\tgl3wGetBooleani_v                               = ( PFNGLGETBOOLEANI_VPROC                               ) gl3w_fn(\"glGetBooleani_v\");\n\tgl3wGetBooleanv                                 = ( PFNGLGETBOOLEANVPROC                                 ) gl3w_fn(\"glGetBooleanv\");\n\tgl3wGetBufferParameteri64v                      = ( PFNGLGETBUFFERPARAMETERI64VPROC                      ) gl3w_fn(\"glGetBufferParameteri64v\");\n\tgl3wGetBufferParameteriv                        = ( PFNGLGETBUFFERPARAMETERIVPROC                        ) gl3w_fn(\"glGetBufferParameteriv\");\n\tgl3wGetBufferPointerv                           = ( PFNGLGETBUFFERPOINTERVPROC                           ) gl3w_fn(\"glGetBufferPointerv\");\n\tgl3wGetBufferSubData                            = ( PFNGLGETBUFFERSUBDATAPROC                            ) gl3w_fn(\"glGetBufferSubData\");\n\tgl3wGetCompressedTexImage                       = ( PFNGLGETCOMPRESSEDTEXIMAGEPROC                       ) gl3w_fn(\"glGetCompressedTexImage\");\n\tgl3wGetCompressedTextureImage                   = ( PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC                   ) gl3w_fn(\"glGetCompressedTextureImage\");\n\tgl3wGetCompressedTextureSubImage                = ( PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC                ) gl3w_fn(\"glGetCompressedTextureSubImage\");\n\tgl3wGetDebugMessageLog                          = ( PFNGLGETDEBUGMESSAGELOGPROC                          ) gl3w_fn(\"glGetDebugMessageLog\");\n\tgl3wGetDebugMessageLogARB                       = ( PFNGLGETDEBUGMESSAGELOGARBPROC                       ) gl3w_fn(\"glGetDebugMessageLogARB\");\n\tgl3wGetDoublei_v                                = ( PFNGLGETDOUBLEI_VPROC                                ) gl3w_fn(\"glGetDoublei_v\");\n\tgl3wGetDoublev                                  = ( PFNGLGETDOUBLEVPROC                                  ) gl3w_fn(\"glGetDoublev\");\n\tgl3wGetError                                    = ( PFNGLGETERRORPROC                                    ) gl3w_fn(\"glGetError\");\n\tgl3wGetFloati_v                                 = ( PFNGLGETFLOATI_VPROC                                 ) gl3w_fn(\"glGetFloati_v\");\n\tgl3wGetFloatv                                   = ( PFNGLGETFLOATVPROC                                   ) gl3w_fn(\"glGetFloatv\");\n\tgl3wGetFragDataIndex                            = ( PFNGLGETFRAGDATAINDEXPROC                            ) gl3w_fn(\"glGetFragDataIndex\");\n\tgl3wGetFragDataLocation                         = ( PFNGLGETFRAGDATALOCATIONPROC                         ) gl3w_fn(\"glGetFragDataLocation\");\n\tgl3wGetFramebufferAttachmentParameteriv         = ( PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC         ) gl3w_fn(\"glGetFramebufferAttachmentParameteriv\");\n\tgl3wGetFramebufferParameteriv                   = ( PFNGLGETFRAMEBUFFERPARAMETERIVPROC                   ) gl3w_fn(\"glGetFramebufferParameteriv\");\n\tgl3wGetGraphicsResetStatus                      = ( PFNGLGETGRAPHICSRESETSTATUSPROC                      ) gl3w_fn(\"glGetGraphicsResetStatus\");\n\tgl3wGetGraphicsResetStatusARB                   = ( PFNGLGETGRAPHICSRESETSTATUSARBPROC                   ) gl3w_fn(\"glGetGraphicsResetStatusARB\");\n\tgl3wGetImageHandleARB                           = ( PFNGLGETIMAGEHANDLEARBPROC                           ) gl3w_fn(\"glGetImageHandleARB\");\n\tgl3wGetInteger64i_v                             = ( PFNGLGETINTEGER64I_VPROC                             ) gl3w_fn(\"glGetInteger64i_v\");\n\tgl3wGetInteger64v                               = ( PFNGLGETINTEGER64VPROC                               ) gl3w_fn(\"glGetInteger64v\");\n\tgl3wGetIntegeri_v                               = ( PFNGLGETINTEGERI_VPROC                               ) gl3w_fn(\"glGetIntegeri_v\");\n\tgl3wGetIntegerv                                 = ( PFNGLGETINTEGERVPROC                                 ) gl3w_fn(\"glGetIntegerv\");\n\tgl3wGetInternalformati64v                       = ( PFNGLGETINTERNALFORMATI64VPROC                       ) gl3w_fn(\"glGetInternalformati64v\");\n\tgl3wGetInternalformativ                         = ( PFNGLGETINTERNALFORMATIVPROC                         ) gl3w_fn(\"glGetInternalformativ\");\n\tgl3wGetMultisamplefv                            = ( PFNGLGETMULTISAMPLEFVPROC                            ) gl3w_fn(\"glGetMultisamplefv\");\n\tgl3wGetNamedBufferParameteri64v                 = ( PFNGLGETNAMEDBUFFERPARAMETERI64VPROC                 ) gl3w_fn(\"glGetNamedBufferParameteri64v\");\n\tgl3wGetNamedBufferParameteriv                   = ( PFNGLGETNAMEDBUFFERPARAMETERIVPROC                   ) gl3w_fn(\"glGetNamedBufferParameteriv\");\n\tgl3wGetNamedBufferPointerv                      = ( PFNGLGETNAMEDBUFFERPOINTERVPROC                      ) gl3w_fn(\"glGetNamedBufferPointerv\");\n\tgl3wGetNamedBufferSubData                       = ( PFNGLGETNAMEDBUFFERSUBDATAPROC                       ) gl3w_fn(\"glGetNamedBufferSubData\");\n\tgl3wGetNamedFramebufferAttachmentParameteriv    = ( PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC    ) gl3w_fn(\"glGetNamedFramebufferAttachmentParameteriv\");\n\tgl3wGetNamedFramebufferParameteriv              = ( PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC              ) gl3w_fn(\"glGetNamedFramebufferParameteriv\");\n\tgl3wGetNamedRenderbufferParameteriv             = ( PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC             ) gl3w_fn(\"glGetNamedRenderbufferParameteriv\");\n\tgl3wGetNamedStringARB                           = ( PFNGLGETNAMEDSTRINGARBPROC                           ) gl3w_fn(\"glGetNamedStringARB\");\n\tgl3wGetNamedStringivARB                         = ( PFNGLGETNAMEDSTRINGIVARBPROC                         ) gl3w_fn(\"glGetNamedStringivARB\");\n\tgl3wGetObjectLabel                              = ( PFNGLGETOBJECTLABELPROC                              ) gl3w_fn(\"glGetObjectLabel\");\n\tgl3wGetObjectPtrLabel                           = ( PFNGLGETOBJECTPTRLABELPROC                           ) gl3w_fn(\"glGetObjectPtrLabel\");\n\tgl3wGetPointerv                                 = ( PFNGLGETPOINTERVPROC                                 ) gl3w_fn(\"glGetPointerv\");\n\tgl3wGetProgramBinary                            = ( PFNGLGETPROGRAMBINARYPROC                            ) gl3w_fn(\"glGetProgramBinary\");\n\tgl3wGetProgramInfoLog                           = ( PFNGLGETPROGRAMINFOLOGPROC                           ) gl3w_fn(\"glGetProgramInfoLog\");\n\tgl3wGetProgramInterfaceiv                       = ( PFNGLGETPROGRAMINTERFACEIVPROC                       ) gl3w_fn(\"glGetProgramInterfaceiv\");\n\tgl3wGetProgramPipelineInfoLog                   = ( PFNGLGETPROGRAMPIPELINEINFOLOGPROC                   ) gl3w_fn(\"glGetProgramPipelineInfoLog\");\n\tgl3wGetProgramPipelineiv                        = ( PFNGLGETPROGRAMPIPELINEIVPROC                        ) gl3w_fn(\"glGetProgramPipelineiv\");\n\tgl3wGetProgramResourceIndex                     = ( PFNGLGETPROGRAMRESOURCEINDEXPROC                     ) gl3w_fn(\"glGetProgramResourceIndex\");\n\tgl3wGetProgramResourceLocation                  = ( PFNGLGETPROGRAMRESOURCELOCATIONPROC                  ) gl3w_fn(\"glGetProgramResourceLocation\");\n\tgl3wGetProgramResourceLocationIndex             = ( PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC             ) gl3w_fn(\"glGetProgramResourceLocationIndex\");\n\tgl3wGetProgramResourceName                      = ( PFNGLGETPROGRAMRESOURCENAMEPROC                      ) gl3w_fn(\"glGetProgramResourceName\");\n\tgl3wGetProgramResourceiv                        = ( PFNGLGETPROGRAMRESOURCEIVPROC                        ) gl3w_fn(\"glGetProgramResourceiv\");\n\tgl3wGetProgramStageiv                           = ( PFNGLGETPROGRAMSTAGEIVPROC                           ) gl3w_fn(\"glGetProgramStageiv\");\n\tgl3wGetProgramiv                                = ( PFNGLGETPROGRAMIVPROC                                ) gl3w_fn(\"glGetProgramiv\");\n\tgl3wGetQueryBufferObjecti64v                    = ( PFNGLGETQUERYBUFFEROBJECTI64VPROC                    ) gl3w_fn(\"glGetQueryBufferObjecti64v\");\n\tgl3wGetQueryBufferObjectiv                      = ( PFNGLGETQUERYBUFFEROBJECTIVPROC                      ) gl3w_fn(\"glGetQueryBufferObjectiv\");\n\tgl3wGetQueryBufferObjectui64v                   = ( PFNGLGETQUERYBUFFEROBJECTUI64VPROC                   ) gl3w_fn(\"glGetQueryBufferObjectui64v\");\n\tgl3wGetQueryBufferObjectuiv                     = ( PFNGLGETQUERYBUFFEROBJECTUIVPROC                     ) gl3w_fn(\"glGetQueryBufferObjectuiv\");\n\tgl3wGetQueryIndexediv                           = ( PFNGLGETQUERYINDEXEDIVPROC                           ) gl3w_fn(\"glGetQueryIndexediv\");\n\tgl3wGetQueryObjecti64v                          = ( PFNGLGETQUERYOBJECTI64VPROC                          ) gl3w_fn(\"glGetQueryObjecti64v\");\n\tgl3wGetQueryObjectiv                            = ( PFNGLGETQUERYOBJECTIVPROC                            ) gl3w_fn(\"glGetQueryObjectiv\");\n\tgl3wGetQueryObjectui64v                         = ( PFNGLGETQUERYOBJECTUI64VPROC                         ) gl3w_fn(\"glGetQueryObjectui64v\");\n\tgl3wGetQueryObjectuiv                           = ( PFNGLGETQUERYOBJECTUIVPROC                           ) gl3w_fn(\"glGetQueryObjectuiv\");\n\tgl3wGetQueryiv                                  = ( PFNGLGETQUERYIVPROC                                  ) gl3w_fn(\"glGetQueryiv\");\n\tgl3wGetRenderbufferParameteriv                  = ( PFNGLGETRENDERBUFFERPARAMETERIVPROC                  ) gl3w_fn(\"glGetRenderbufferParameteriv\");\n\tgl3wGetSamplerParameterIiv                      = ( PFNGLGETSAMPLERPARAMETERIIVPROC                      ) gl3w_fn(\"glGetSamplerParameterIiv\");\n\tgl3wGetSamplerParameterIuiv                     = ( PFNGLGETSAMPLERPARAMETERIUIVPROC                     ) gl3w_fn(\"glGetSamplerParameterIuiv\");\n\tgl3wGetSamplerParameterfv                       = ( PFNGLGETSAMPLERPARAMETERFVPROC                       ) gl3w_fn(\"glGetSamplerParameterfv\");\n\tgl3wGetSamplerParameteriv                       = ( PFNGLGETSAMPLERPARAMETERIVPROC                       ) gl3w_fn(\"glGetSamplerParameteriv\");\n\tgl3wGetShaderInfoLog                            = ( PFNGLGETSHADERINFOLOGPROC                            ) gl3w_fn(\"glGetShaderInfoLog\");\n\tgl3wGetShaderPrecisionFormat                    = ( PFNGLGETSHADERPRECISIONFORMATPROC                    ) gl3w_fn(\"glGetShaderPrecisionFormat\");\n\tgl3wGetShaderSource                             = ( PFNGLGETSHADERSOURCEPROC                             ) gl3w_fn(\"glGetShaderSource\");\n\tgl3wGetShaderiv                                 = ( PFNGLGETSHADERIVPROC                                 ) gl3w_fn(\"glGetShaderiv\");\n\tgl3wGetString                                   = ( PFNGLGETSTRINGPROC                                   ) gl3w_fn(\"glGetString\");\n\tgl3wGetStringi                                  = ( PFNGLGETSTRINGIPROC                                  ) gl3w_fn(\"glGetStringi\");\n\tgl3wGetSubroutineIndex                          = ( PFNGLGETSUBROUTINEINDEXPROC                          ) gl3w_fn(\"glGetSubroutineIndex\");\n\tgl3wGetSubroutineUniformLocation                = ( PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC                ) gl3w_fn(\"glGetSubroutineUniformLocation\");\n\tgl3wGetSynciv                                   = ( PFNGLGETSYNCIVPROC                                   ) gl3w_fn(\"glGetSynciv\");\n\tgl3wGetTexImage                                 = ( PFNGLGETTEXIMAGEPROC                                 ) gl3w_fn(\"glGetTexImage\");\n\tgl3wGetTexLevelParameterfv                      = ( PFNGLGETTEXLEVELPARAMETERFVPROC                      ) gl3w_fn(\"glGetTexLevelParameterfv\");\n\tgl3wGetTexLevelParameteriv                      = ( PFNGLGETTEXLEVELPARAMETERIVPROC                      ) gl3w_fn(\"glGetTexLevelParameteriv\");\n\tgl3wGetTexParameterIiv                          = ( PFNGLGETTEXPARAMETERIIVPROC                          ) gl3w_fn(\"glGetTexParameterIiv\");\n\tgl3wGetTexParameterIuiv                         = ( PFNGLGETTEXPARAMETERIUIVPROC                         ) gl3w_fn(\"glGetTexParameterIuiv\");\n\tgl3wGetTexParameterfv                           = ( PFNGLGETTEXPARAMETERFVPROC                           ) gl3w_fn(\"glGetTexParameterfv\");\n\tgl3wGetTexParameteriv                           = ( PFNGLGETTEXPARAMETERIVPROC                           ) gl3w_fn(\"glGetTexParameteriv\");\n\tgl3wGetTextureHandleARB                         = ( PFNGLGETTEXTUREHANDLEARBPROC                         ) gl3w_fn(\"glGetTextureHandleARB\");\n\tgl3wGetTextureImage                             = ( PFNGLGETTEXTUREIMAGEPROC                             ) gl3w_fn(\"glGetTextureImage\");\n\tgl3wGetTextureLevelParameterfv                  = ( PFNGLGETTEXTURELEVELPARAMETERFVPROC                  ) gl3w_fn(\"glGetTextureLevelParameterfv\");\n\tgl3wGetTextureLevelParameteriv                  = ( PFNGLGETTEXTURELEVELPARAMETERIVPROC                  ) gl3w_fn(\"glGetTextureLevelParameteriv\");\n\tgl3wGetTextureParameterIiv                      = ( PFNGLGETTEXTUREPARAMETERIIVPROC                      ) gl3w_fn(\"glGetTextureParameterIiv\");\n\tgl3wGetTextureParameterIuiv                     = ( PFNGLGETTEXTUREPARAMETERIUIVPROC                     ) gl3w_fn(\"glGetTextureParameterIuiv\");\n\tgl3wGetTextureParameterfv                       = ( PFNGLGETTEXTUREPARAMETERFVPROC                       ) gl3w_fn(\"glGetTextureParameterfv\");\n\tgl3wGetTextureParameteriv                       = ( PFNGLGETTEXTUREPARAMETERIVPROC                       ) gl3w_fn(\"glGetTextureParameteriv\");\n\tgl3wGetTextureSamplerHandleARB                  = ( PFNGLGETTEXTURESAMPLERHANDLEARBPROC                  ) gl3w_fn(\"glGetTextureSamplerHandleARB\");\n\tgl3wGetTextureSubImage                          = ( PFNGLGETTEXTURESUBIMAGEPROC                          ) gl3w_fn(\"glGetTextureSubImage\");\n\tgl3wGetTransformFeedbackVarying                 = ( PFNGLGETTRANSFORMFEEDBACKVARYINGPROC                 ) gl3w_fn(\"glGetTransformFeedbackVarying\");\n\tgl3wGetTransformFeedbacki64_v                   = ( PFNGLGETTRANSFORMFEEDBACKI64_VPROC                   ) gl3w_fn(\"glGetTransformFeedbacki64_v\");\n\tgl3wGetTransformFeedbacki_v                     = ( PFNGLGETTRANSFORMFEEDBACKI_VPROC                     ) gl3w_fn(\"glGetTransformFeedbacki_v\");\n\tgl3wGetTransformFeedbackiv                      = ( PFNGLGETTRANSFORMFEEDBACKIVPROC                      ) gl3w_fn(\"glGetTransformFeedbackiv\");\n\tgl3wGetUniformBlockIndex                        = ( PFNGLGETUNIFORMBLOCKINDEXPROC                        ) gl3w_fn(\"glGetUniformBlockIndex\");\n\tgl3wGetUniformIndices                           = ( PFNGLGETUNIFORMINDICESPROC                           ) gl3w_fn(\"glGetUniformIndices\");\n\tgl3wGetUniformLocation                          = ( PFNGLGETUNIFORMLOCATIONPROC                          ) gl3w_fn(\"glGetUniformLocation\");\n\tgl3wGetUniformSubroutineuiv                     = ( PFNGLGETUNIFORMSUBROUTINEUIVPROC                     ) gl3w_fn(\"glGetUniformSubroutineuiv\");\n\tgl3wGetUniformdv                                = ( PFNGLGETUNIFORMDVPROC                                ) gl3w_fn(\"glGetUniformdv\");\n\tgl3wGetUniformfv                                = ( PFNGLGETUNIFORMFVPROC                                ) gl3w_fn(\"glGetUniformfv\");\n\tgl3wGetUniformiv                                = ( PFNGLGETUNIFORMIVPROC                                ) gl3w_fn(\"glGetUniformiv\");\n\tgl3wGetUniformuiv                               = ( PFNGLGETUNIFORMUIVPROC                               ) gl3w_fn(\"glGetUniformuiv\");\n\tgl3wGetVertexArrayIndexed64iv                   = ( PFNGLGETVERTEXARRAYINDEXED64IVPROC                   ) gl3w_fn(\"glGetVertexArrayIndexed64iv\");\n\tgl3wGetVertexArrayIndexediv                     = ( PFNGLGETVERTEXARRAYINDEXEDIVPROC                     ) gl3w_fn(\"glGetVertexArrayIndexediv\");\n\tgl3wGetVertexArrayiv                            = ( PFNGLGETVERTEXARRAYIVPROC                            ) gl3w_fn(\"glGetVertexArrayiv\");\n\tgl3wGetVertexAttribIiv                          = ( PFNGLGETVERTEXATTRIBIIVPROC                          ) gl3w_fn(\"glGetVertexAttribIiv\");\n\tgl3wGetVertexAttribIuiv                         = ( PFNGLGETVERTEXATTRIBIUIVPROC                         ) gl3w_fn(\"glGetVertexAttribIuiv\");\n\tgl3wGetVertexAttribLdv                          = ( PFNGLGETVERTEXATTRIBLDVPROC                          ) gl3w_fn(\"glGetVertexAttribLdv\");\n\tgl3wGetVertexAttribLui64vARB                    = ( PFNGLGETVERTEXATTRIBLUI64VARBPROC                    ) gl3w_fn(\"glGetVertexAttribLui64vARB\");\n\tgl3wGetVertexAttribPointerv                     = ( PFNGLGETVERTEXATTRIBPOINTERVPROC                     ) gl3w_fn(\"glGetVertexAttribPointerv\");\n\tgl3wGetVertexAttribdv                           = ( PFNGLGETVERTEXATTRIBDVPROC                           ) gl3w_fn(\"glGetVertexAttribdv\");\n\tgl3wGetVertexAttribfv                           = ( PFNGLGETVERTEXATTRIBFVPROC                           ) gl3w_fn(\"glGetVertexAttribfv\");\n\tgl3wGetVertexAttribiv                           = ( PFNGLGETVERTEXATTRIBIVPROC                           ) gl3w_fn(\"glGetVertexAttribiv\");\n\tgl3wGetnCompressedTexImage                      = ( PFNGLGETNCOMPRESSEDTEXIMAGEPROC                      ) gl3w_fn(\"glGetnCompressedTexImage\");\n\tgl3wGetnCompressedTexImageARB                   = ( PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC                   ) gl3w_fn(\"glGetnCompressedTexImageARB\");\n\tgl3wGetnTexImage                                = ( PFNGLGETNTEXIMAGEPROC                                ) gl3w_fn(\"glGetnTexImage\");\n\tgl3wGetnTexImageARB                             = ( PFNGLGETNTEXIMAGEARBPROC                             ) gl3w_fn(\"glGetnTexImageARB\");\n\tgl3wGetnUniformdv                               = ( PFNGLGETNUNIFORMDVPROC                               ) gl3w_fn(\"glGetnUniformdv\");\n\tgl3wGetnUniformdvARB                            = ( PFNGLGETNUNIFORMDVARBPROC                            ) gl3w_fn(\"glGetnUniformdvARB\");\n\tgl3wGetnUniformfv                               = ( PFNGLGETNUNIFORMFVPROC                               ) gl3w_fn(\"glGetnUniformfv\");\n\tgl3wGetnUniformfvARB                            = ( PFNGLGETNUNIFORMFVARBPROC                            ) gl3w_fn(\"glGetnUniformfvARB\");\n\tgl3wGetnUniformiv                               = ( PFNGLGETNUNIFORMIVPROC                               ) gl3w_fn(\"glGetnUniformiv\");\n\tgl3wGetnUniformivARB                            = ( PFNGLGETNUNIFORMIVARBPROC                            ) gl3w_fn(\"glGetnUniformivARB\");\n\tgl3wGetnUniformuiv                              = ( PFNGLGETNUNIFORMUIVPROC                              ) gl3w_fn(\"glGetnUniformuiv\");\n\tgl3wGetnUniformuivARB                           = ( PFNGLGETNUNIFORMUIVARBPROC                           ) gl3w_fn(\"glGetnUniformuivARB\");\n\tgl3wHint                                        = ( PFNGLHINTPROC                                        ) gl3w_fn(\"glHint\");\n\tgl3wInvalidateBufferData                        = ( PFNGLINVALIDATEBUFFERDATAPROC                        ) gl3w_fn(\"glInvalidateBufferData\");\n\tgl3wInvalidateBufferSubData                     = ( PFNGLINVALIDATEBUFFERSUBDATAPROC                     ) gl3w_fn(\"glInvalidateBufferSubData\");\n\tgl3wInvalidateFramebuffer                       = ( PFNGLINVALIDATEFRAMEBUFFERPROC                       ) gl3w_fn(\"glInvalidateFramebuffer\");\n\tgl3wInvalidateNamedFramebufferData              = ( PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC              ) gl3w_fn(\"glInvalidateNamedFramebufferData\");\n\tgl3wInvalidateNamedFramebufferSubData           = ( PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC           ) gl3w_fn(\"glInvalidateNamedFramebufferSubData\");\n\tgl3wInvalidateSubFramebuffer                    = ( PFNGLINVALIDATESUBFRAMEBUFFERPROC                    ) gl3w_fn(\"glInvalidateSubFramebuffer\");\n\tgl3wInvalidateTexImage                          = ( PFNGLINVALIDATETEXIMAGEPROC                          ) gl3w_fn(\"glInvalidateTexImage\");\n\tgl3wInvalidateTexSubImage                       = ( PFNGLINVALIDATETEXSUBIMAGEPROC                       ) gl3w_fn(\"glInvalidateTexSubImage\");\n\tgl3wIsBuffer                                    = ( PFNGLISBUFFERPROC                                    ) gl3w_fn(\"glIsBuffer\");\n\tgl3wIsEnabled                                   = ( PFNGLISENABLEDPROC                                   ) gl3w_fn(\"glIsEnabled\");\n\tgl3wIsEnabledi                                  = ( PFNGLISENABLEDIPROC                                  ) gl3w_fn(\"glIsEnabledi\");\n\tgl3wIsFramebuffer                               = ( PFNGLISFRAMEBUFFERPROC                               ) gl3w_fn(\"glIsFramebuffer\");\n\tgl3wIsImageHandleResidentARB                    = ( PFNGLISIMAGEHANDLERESIDENTARBPROC                    ) gl3w_fn(\"glIsImageHandleResidentARB\");\n\tgl3wIsNamedStringARB                            = ( PFNGLISNAMEDSTRINGARBPROC                            ) gl3w_fn(\"glIsNamedStringARB\");\n\tgl3wIsProgram                                   = ( PFNGLISPROGRAMPROC                                   ) gl3w_fn(\"glIsProgram\");\n\tgl3wIsProgramPipeline                           = ( PFNGLISPROGRAMPIPELINEPROC                           ) gl3w_fn(\"glIsProgramPipeline\");\n\tgl3wIsQuery                                     = ( PFNGLISQUERYPROC                                     ) gl3w_fn(\"glIsQuery\");\n\tgl3wIsRenderbuffer                              = ( PFNGLISRENDERBUFFERPROC                              ) gl3w_fn(\"glIsRenderbuffer\");\n\tgl3wIsSampler                                   = ( PFNGLISSAMPLERPROC                                   ) gl3w_fn(\"glIsSampler\");\n\tgl3wIsShader                                    = ( PFNGLISSHADERPROC                                    ) gl3w_fn(\"glIsShader\");\n\tgl3wIsSync                                      = ( PFNGLISSYNCPROC                                      ) gl3w_fn(\"glIsSync\");\n\tgl3wIsTexture                                   = ( PFNGLISTEXTUREPROC                                   ) gl3w_fn(\"glIsTexture\");\n\tgl3wIsTextureHandleResidentARB                  = ( PFNGLISTEXTUREHANDLERESIDENTARBPROC                  ) gl3w_fn(\"glIsTextureHandleResidentARB\");\n\tgl3wIsTransformFeedback                         = ( PFNGLISTRANSFORMFEEDBACKPROC                         ) gl3w_fn(\"glIsTransformFeedback\");\n\tgl3wIsVertexArray                               = ( PFNGLISVERTEXARRAYPROC                               ) gl3w_fn(\"glIsVertexArray\");\n\tgl3wLineWidth                                   = ( PFNGLLINEWIDTHPROC                                   ) gl3w_fn(\"glLineWidth\");\n\tgl3wLinkProgram                                 = ( PFNGLLINKPROGRAMPROC                                 ) gl3w_fn(\"glLinkProgram\");\n\tgl3wLogicOp                                     = ( PFNGLLOGICOPPROC                                     ) gl3w_fn(\"glLogicOp\");\n\tgl3wMakeImageHandleNonResidentARB               = ( PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC               ) gl3w_fn(\"glMakeImageHandleNonResidentARB\");\n\tgl3wMakeImageHandleResidentARB                  = ( PFNGLMAKEIMAGEHANDLERESIDENTARBPROC                  ) gl3w_fn(\"glMakeImageHandleResidentARB\");\n\tgl3wMakeTextureHandleNonResidentARB             = ( PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC             ) gl3w_fn(\"glMakeTextureHandleNonResidentARB\");\n\tgl3wMakeTextureHandleResidentARB                = ( PFNGLMAKETEXTUREHANDLERESIDENTARBPROC                ) gl3w_fn(\"glMakeTextureHandleResidentARB\");\n\tgl3wMapBuffer                                   = ( PFNGLMAPBUFFERPROC                                   ) gl3w_fn(\"glMapBuffer\");\n\tgl3wMapBufferRange                              = ( PFNGLMAPBUFFERRANGEPROC                              ) gl3w_fn(\"glMapBufferRange\");\n\tgl3wMapNamedBuffer                              = ( PFNGLMAPNAMEDBUFFERPROC                              ) gl3w_fn(\"glMapNamedBuffer\");\n\tgl3wMapNamedBufferRange                         = ( PFNGLMAPNAMEDBUFFERRANGEPROC                         ) gl3w_fn(\"glMapNamedBufferRange\");\n\tgl3wMemoryBarrier                               = ( PFNGLMEMORYBARRIERPROC                               ) gl3w_fn(\"glMemoryBarrier\");\n\tgl3wMemoryBarrierByRegion                       = ( PFNGLMEMORYBARRIERBYREGIONPROC                       ) gl3w_fn(\"glMemoryBarrierByRegion\");\n\tgl3wMinSampleShading                            = ( PFNGLMINSAMPLESHADINGPROC                            ) gl3w_fn(\"glMinSampleShading\");\n\tgl3wMinSampleShadingARB                         = ( PFNGLMINSAMPLESHADINGARBPROC                         ) gl3w_fn(\"glMinSampleShadingARB\");\n\tgl3wMultiDrawArrays                             = ( PFNGLMULTIDRAWARRAYSPROC                             ) gl3w_fn(\"glMultiDrawArrays\");\n\tgl3wMultiDrawArraysIndirect                     = ( PFNGLMULTIDRAWARRAYSINDIRECTPROC                     ) gl3w_fn(\"glMultiDrawArraysIndirect\");\n\tgl3wMultiDrawArraysIndirectCountARB             = ( PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC             ) gl3w_fn(\"glMultiDrawArraysIndirectCountARB\");\n\tgl3wMultiDrawElements                           = ( PFNGLMULTIDRAWELEMENTSPROC                           ) gl3w_fn(\"glMultiDrawElements\");\n\tgl3wMultiDrawElementsBaseVertex                 = ( PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC                 ) gl3w_fn(\"glMultiDrawElementsBaseVertex\");\n\tgl3wMultiDrawElementsIndirect                   = ( PFNGLMULTIDRAWELEMENTSINDIRECTPROC                   ) gl3w_fn(\"glMultiDrawElementsIndirect\");\n\tgl3wMultiDrawElementsIndirectCountARB           = ( PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC           ) gl3w_fn(\"glMultiDrawElementsIndirectCountARB\");\n\tgl3wNamedBufferData                             = ( PFNGLNAMEDBUFFERDATAPROC                             ) gl3w_fn(\"glNamedBufferData\");\n\tgl3wNamedBufferPageCommitmentARB                = ( PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC                ) gl3w_fn(\"glNamedBufferPageCommitmentARB\");\n\tgl3wNamedBufferPageCommitmentEXT                = ( PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC                ) gl3w_fn(\"glNamedBufferPageCommitmentEXT\");\n\tgl3wNamedBufferStorage                          = ( PFNGLNAMEDBUFFERSTORAGEPROC                          ) gl3w_fn(\"glNamedBufferStorage\");\n\tgl3wNamedBufferSubData                          = ( PFNGLNAMEDBUFFERSUBDATAPROC                          ) gl3w_fn(\"glNamedBufferSubData\");\n\tgl3wNamedFramebufferDrawBuffer                  = ( PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC                  ) gl3w_fn(\"glNamedFramebufferDrawBuffer\");\n\tgl3wNamedFramebufferDrawBuffers                 = ( PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC                 ) gl3w_fn(\"glNamedFramebufferDrawBuffers\");\n\tgl3wNamedFramebufferParameteri                  = ( PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC                  ) gl3w_fn(\"glNamedFramebufferParameteri\");\n\tgl3wNamedFramebufferReadBuffer                  = ( PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC                  ) gl3w_fn(\"glNamedFramebufferReadBuffer\");\n\tgl3wNamedFramebufferRenderbuffer                = ( PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC                ) gl3w_fn(\"glNamedFramebufferRenderbuffer\");\n\tgl3wNamedFramebufferTexture                     = ( PFNGLNAMEDFRAMEBUFFERTEXTUREPROC                     ) gl3w_fn(\"glNamedFramebufferTexture\");\n\tgl3wNamedFramebufferTextureLayer                = ( PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC                ) gl3w_fn(\"glNamedFramebufferTextureLayer\");\n\tgl3wNamedRenderbufferStorage                    = ( PFNGLNAMEDRENDERBUFFERSTORAGEPROC                    ) gl3w_fn(\"glNamedRenderbufferStorage\");\n\tgl3wNamedRenderbufferStorageMultisample         = ( PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC         ) gl3w_fn(\"glNamedRenderbufferStorageMultisample\");\n\tgl3wNamedStringARB                              = ( PFNGLNAMEDSTRINGARBPROC                              ) gl3w_fn(\"glNamedStringARB\");\n\tgl3wObjectLabel                                 = ( PFNGLOBJECTLABELPROC                                 ) gl3w_fn(\"glObjectLabel\");\n\tgl3wObjectPtrLabel                              = ( PFNGLOBJECTPTRLABELPROC                              ) gl3w_fn(\"glObjectPtrLabel\");\n\tgl3wPatchParameterfv                            = ( PFNGLPATCHPARAMETERFVPROC                            ) gl3w_fn(\"glPatchParameterfv\");\n\tgl3wPatchParameteri                             = ( PFNGLPATCHPARAMETERIPROC                             ) gl3w_fn(\"glPatchParameteri\");\n\tgl3wPauseTransformFeedback                      = ( PFNGLPAUSETRANSFORMFEEDBACKPROC                      ) gl3w_fn(\"glPauseTransformFeedback\");\n\tgl3wPixelStoref                                 = ( PFNGLPIXELSTOREFPROC                                 ) gl3w_fn(\"glPixelStoref\");\n\tgl3wPixelStorei                                 = ( PFNGLPIXELSTOREIPROC                                 ) gl3w_fn(\"glPixelStorei\");\n\tgl3wPointParameterf                             = ( PFNGLPOINTPARAMETERFPROC                             ) gl3w_fn(\"glPointParameterf\");\n\tgl3wPointParameterfv                            = ( PFNGLPOINTPARAMETERFVPROC                            ) gl3w_fn(\"glPointParameterfv\");\n\tgl3wPointParameteri                             = ( PFNGLPOINTPARAMETERIPROC                             ) gl3w_fn(\"glPointParameteri\");\n\tgl3wPointParameteriv                            = ( PFNGLPOINTPARAMETERIVPROC                            ) gl3w_fn(\"glPointParameteriv\");\n\tgl3wPointSize                                   = ( PFNGLPOINTSIZEPROC                                   ) gl3w_fn(\"glPointSize\");\n\tgl3wPolygonMode                                 = ( PFNGLPOLYGONMODEPROC                                 ) gl3w_fn(\"glPolygonMode\");\n\tgl3wPolygonOffset                               = ( PFNGLPOLYGONOFFSETPROC                               ) gl3w_fn(\"glPolygonOffset\");\n\tgl3wPopDebugGroup                               = ( PFNGLPOPDEBUGGROUPPROC                               ) gl3w_fn(\"glPopDebugGroup\");\n\tgl3wPrimitiveRestartIndex                       = ( PFNGLPRIMITIVERESTARTINDEXPROC                       ) gl3w_fn(\"glPrimitiveRestartIndex\");\n\tgl3wProgramBinary                               = ( PFNGLPROGRAMBINARYPROC                               ) gl3w_fn(\"glProgramBinary\");\n\tgl3wProgramParameteri                           = ( PFNGLPROGRAMPARAMETERIPROC                           ) gl3w_fn(\"glProgramParameteri\");\n\tgl3wProgramUniform1d                            = ( PFNGLPROGRAMUNIFORM1DPROC                            ) gl3w_fn(\"glProgramUniform1d\");\n\tgl3wProgramUniform1dv                           = ( PFNGLPROGRAMUNIFORM1DVPROC                           ) gl3w_fn(\"glProgramUniform1dv\");\n\tgl3wProgramUniform1f                            = ( PFNGLPROGRAMUNIFORM1FPROC                            ) gl3w_fn(\"glProgramUniform1f\");\n\tgl3wProgramUniform1fv                           = ( PFNGLPROGRAMUNIFORM1FVPROC                           ) gl3w_fn(\"glProgramUniform1fv\");\n\tgl3wProgramUniform1i                            = ( PFNGLPROGRAMUNIFORM1IPROC                            ) gl3w_fn(\"glProgramUniform1i\");\n\tgl3wProgramUniform1iv                           = ( PFNGLPROGRAMUNIFORM1IVPROC                           ) gl3w_fn(\"glProgramUniform1iv\");\n\tgl3wProgramUniform1ui                           = ( PFNGLPROGRAMUNIFORM1UIPROC                           ) gl3w_fn(\"glProgramUniform1ui\");\n\tgl3wProgramUniform1uiv                          = ( PFNGLPROGRAMUNIFORM1UIVPROC                          ) gl3w_fn(\"glProgramUniform1uiv\");\n\tgl3wProgramUniform2d                            = ( PFNGLPROGRAMUNIFORM2DPROC                            ) gl3w_fn(\"glProgramUniform2d\");\n\tgl3wProgramUniform2dv                           = ( PFNGLPROGRAMUNIFORM2DVPROC                           ) gl3w_fn(\"glProgramUniform2dv\");\n\tgl3wProgramUniform2f                            = ( PFNGLPROGRAMUNIFORM2FPROC                            ) gl3w_fn(\"glProgramUniform2f\");\n\tgl3wProgramUniform2fv                           = ( PFNGLPROGRAMUNIFORM2FVPROC                           ) gl3w_fn(\"glProgramUniform2fv\");\n\tgl3wProgramUniform2i                            = ( PFNGLPROGRAMUNIFORM2IPROC                            ) gl3w_fn(\"glProgramUniform2i\");\n\tgl3wProgramUniform2iv                           = ( PFNGLPROGRAMUNIFORM2IVPROC                           ) gl3w_fn(\"glProgramUniform2iv\");\n\tgl3wProgramUniform2ui                           = ( PFNGLPROGRAMUNIFORM2UIPROC                           ) gl3w_fn(\"glProgramUniform2ui\");\n\tgl3wProgramUniform2uiv                          = ( PFNGLPROGRAMUNIFORM2UIVPROC                          ) gl3w_fn(\"glProgramUniform2uiv\");\n\tgl3wProgramUniform3d                            = ( PFNGLPROGRAMUNIFORM3DPROC                            ) gl3w_fn(\"glProgramUniform3d\");\n\tgl3wProgramUniform3dv                           = ( PFNGLPROGRAMUNIFORM3DVPROC                           ) gl3w_fn(\"glProgramUniform3dv\");\n\tgl3wProgramUniform3f                            = ( PFNGLPROGRAMUNIFORM3FPROC                            ) gl3w_fn(\"glProgramUniform3f\");\n\tgl3wProgramUniform3fv                           = ( PFNGLPROGRAMUNIFORM3FVPROC                           ) gl3w_fn(\"glProgramUniform3fv\");\n\tgl3wProgramUniform3i                            = ( PFNGLPROGRAMUNIFORM3IPROC                            ) gl3w_fn(\"glProgramUniform3i\");\n\tgl3wProgramUniform3iv                           = ( PFNGLPROGRAMUNIFORM3IVPROC                           ) gl3w_fn(\"glProgramUniform3iv\");\n\tgl3wProgramUniform3ui                           = ( PFNGLPROGRAMUNIFORM3UIPROC                           ) gl3w_fn(\"glProgramUniform3ui\");\n\tgl3wProgramUniform3uiv                          = ( PFNGLPROGRAMUNIFORM3UIVPROC                          ) gl3w_fn(\"glProgramUniform3uiv\");\n\tgl3wProgramUniform4d                            = ( PFNGLPROGRAMUNIFORM4DPROC                            ) gl3w_fn(\"glProgramUniform4d\");\n\tgl3wProgramUniform4dv                           = ( PFNGLPROGRAMUNIFORM4DVPROC                           ) gl3w_fn(\"glProgramUniform4dv\");\n\tgl3wProgramUniform4f                            = ( PFNGLPROGRAMUNIFORM4FPROC                            ) gl3w_fn(\"glProgramUniform4f\");\n\tgl3wProgramUniform4fv                           = ( PFNGLPROGRAMUNIFORM4FVPROC                           ) gl3w_fn(\"glProgramUniform4fv\");\n\tgl3wProgramUniform4i                            = ( PFNGLPROGRAMUNIFORM4IPROC                            ) gl3w_fn(\"glProgramUniform4i\");\n\tgl3wProgramUniform4iv                           = ( PFNGLPROGRAMUNIFORM4IVPROC                           ) gl3w_fn(\"glProgramUniform4iv\");\n\tgl3wProgramUniform4ui                           = ( PFNGLPROGRAMUNIFORM4UIPROC                           ) gl3w_fn(\"glProgramUniform4ui\");\n\tgl3wProgramUniform4uiv                          = ( PFNGLPROGRAMUNIFORM4UIVPROC                          ) gl3w_fn(\"glProgramUniform4uiv\");\n\tgl3wProgramUniformHandleui64ARB                 = ( PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC                 ) gl3w_fn(\"glProgramUniformHandleui64ARB\");\n\tgl3wProgramUniformHandleui64vARB                = ( PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC                ) gl3w_fn(\"glProgramUniformHandleui64vARB\");\n\tgl3wProgramUniformMatrix2dv                     = ( PFNGLPROGRAMUNIFORMMATRIX2DVPROC                     ) gl3w_fn(\"glProgramUniformMatrix2dv\");\n\tgl3wProgramUniformMatrix2fv                     = ( PFNGLPROGRAMUNIFORMMATRIX2FVPROC                     ) gl3w_fn(\"glProgramUniformMatrix2fv\");\n\tgl3wProgramUniformMatrix2x3dv                   = ( PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC                   ) gl3w_fn(\"glProgramUniformMatrix2x3dv\");\n\tgl3wProgramUniformMatrix2x3fv                   = ( PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC                   ) gl3w_fn(\"glProgramUniformMatrix2x3fv\");\n\tgl3wProgramUniformMatrix2x4dv                   = ( PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC                   ) gl3w_fn(\"glProgramUniformMatrix2x4dv\");\n\tgl3wProgramUniformMatrix2x4fv                   = ( PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC                   ) gl3w_fn(\"glProgramUniformMatrix2x4fv\");\n\tgl3wProgramUniformMatrix3dv                     = ( PFNGLPROGRAMUNIFORMMATRIX3DVPROC                     ) gl3w_fn(\"glProgramUniformMatrix3dv\");\n\tgl3wProgramUniformMatrix3fv                     = ( PFNGLPROGRAMUNIFORMMATRIX3FVPROC                     ) gl3w_fn(\"glProgramUniformMatrix3fv\");\n\tgl3wProgramUniformMatrix3x2dv                   = ( PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC                   ) gl3w_fn(\"glProgramUniformMatrix3x2dv\");\n\tgl3wProgramUniformMatrix3x2fv                   = ( PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC                   ) gl3w_fn(\"glProgramUniformMatrix3x2fv\");\n\tgl3wProgramUniformMatrix3x4dv                   = ( PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC                   ) gl3w_fn(\"glProgramUniformMatrix3x4dv\");\n\tgl3wProgramUniformMatrix3x4fv                   = ( PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC                   ) gl3w_fn(\"glProgramUniformMatrix3x4fv\");\n\tgl3wProgramUniformMatrix4dv                     = ( PFNGLPROGRAMUNIFORMMATRIX4DVPROC                     ) gl3w_fn(\"glProgramUniformMatrix4dv\");\n\tgl3wProgramUniformMatrix4fv                     = ( PFNGLPROGRAMUNIFORMMATRIX4FVPROC                     ) gl3w_fn(\"glProgramUniformMatrix4fv\");\n\tgl3wProgramUniformMatrix4x2dv                   = ( PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC                   ) gl3w_fn(\"glProgramUniformMatrix4x2dv\");\n\tgl3wProgramUniformMatrix4x2fv                   = ( PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC                   ) gl3w_fn(\"glProgramUniformMatrix4x2fv\");\n\tgl3wProgramUniformMatrix4x3dv                   = ( PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC                   ) gl3w_fn(\"glProgramUniformMatrix4x3dv\");\n\tgl3wProgramUniformMatrix4x3fv                   = ( PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC                   ) gl3w_fn(\"glProgramUniformMatrix4x3fv\");\n\tgl3wProvokingVertex                             = ( PFNGLPROVOKINGVERTEXPROC                             ) gl3w_fn(\"glProvokingVertex\");\n\tgl3wPushDebugGroup                              = ( PFNGLPUSHDEBUGGROUPPROC                              ) gl3w_fn(\"glPushDebugGroup\");\n\tgl3wQueryCounter                                = ( PFNGLQUERYCOUNTERPROC                                ) gl3w_fn(\"glQueryCounter\");\n\tgl3wReadBuffer                                  = ( PFNGLREADBUFFERPROC                                  ) gl3w_fn(\"glReadBuffer\");\n\tgl3wReadPixels                                  = ( PFNGLREADPIXELSPROC                                  ) gl3w_fn(\"glReadPixels\");\n\tgl3wReadnPixels                                 = ( PFNGLREADNPIXELSPROC                                 ) gl3w_fn(\"glReadnPixels\");\n\tgl3wReadnPixelsARB                              = ( PFNGLREADNPIXELSARBPROC                              ) gl3w_fn(\"glReadnPixelsARB\");\n\tgl3wReleaseShaderCompiler                       = ( PFNGLRELEASESHADERCOMPILERPROC                       ) gl3w_fn(\"glReleaseShaderCompiler\");\n\tgl3wRenderbufferStorage                         = ( PFNGLRENDERBUFFERSTORAGEPROC                         ) gl3w_fn(\"glRenderbufferStorage\");\n\tgl3wRenderbufferStorageMultisample              = ( PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC              ) gl3w_fn(\"glRenderbufferStorageMultisample\");\n\tgl3wResumeTransformFeedback                     = ( PFNGLRESUMETRANSFORMFEEDBACKPROC                     ) gl3w_fn(\"glResumeTransformFeedback\");\n\tgl3wSampleCoverage                              = ( PFNGLSAMPLECOVERAGEPROC                              ) gl3w_fn(\"glSampleCoverage\");\n\tgl3wSampleMaski                                 = ( PFNGLSAMPLEMASKIPROC                                 ) gl3w_fn(\"glSampleMaski\");\n\tgl3wSamplerParameterIiv                         = ( PFNGLSAMPLERPARAMETERIIVPROC                         ) gl3w_fn(\"glSamplerParameterIiv\");\n\tgl3wSamplerParameterIuiv                        = ( PFNGLSAMPLERPARAMETERIUIVPROC                        ) gl3w_fn(\"glSamplerParameterIuiv\");\n\tgl3wSamplerParameterf                           = ( PFNGLSAMPLERPARAMETERFPROC                           ) gl3w_fn(\"glSamplerParameterf\");\n\tgl3wSamplerParameterfv                          = ( PFNGLSAMPLERPARAMETERFVPROC                          ) gl3w_fn(\"glSamplerParameterfv\");\n\tgl3wSamplerParameteri                           = ( PFNGLSAMPLERPARAMETERIPROC                           ) gl3w_fn(\"glSamplerParameteri\");\n\tgl3wSamplerParameteriv                          = ( PFNGLSAMPLERPARAMETERIVPROC                          ) gl3w_fn(\"glSamplerParameteriv\");\n\tgl3wScissor                                     = ( PFNGLSCISSORPROC                                     ) gl3w_fn(\"glScissor\");\n\tgl3wScissorArrayv                               = ( PFNGLSCISSORARRAYVPROC                               ) gl3w_fn(\"glScissorArrayv\");\n\tgl3wScissorIndexed                              = ( PFNGLSCISSORINDEXEDPROC                              ) gl3w_fn(\"glScissorIndexed\");\n\tgl3wScissorIndexedv                             = ( PFNGLSCISSORINDEXEDVPROC                             ) gl3w_fn(\"glScissorIndexedv\");\n\tgl3wShaderBinary                                = ( PFNGLSHADERBINARYPROC                                ) gl3w_fn(\"glShaderBinary\");\n\tgl3wShaderSource                                = ( PFNGLSHADERSOURCEPROC                                ) gl3w_fn(\"glShaderSource\");\n\tgl3wShaderStorageBlockBinding                   = ( PFNGLSHADERSTORAGEBLOCKBINDINGPROC                   ) gl3w_fn(\"glShaderStorageBlockBinding\");\n\tgl3wStencilFunc                                 = ( PFNGLSTENCILFUNCPROC                                 ) gl3w_fn(\"glStencilFunc\");\n\tgl3wStencilFuncSeparate                         = ( PFNGLSTENCILFUNCSEPARATEPROC                         ) gl3w_fn(\"glStencilFuncSeparate\");\n\tgl3wStencilMask                                 = ( PFNGLSTENCILMASKPROC                                 ) gl3w_fn(\"glStencilMask\");\n\tgl3wStencilMaskSeparate                         = ( PFNGLSTENCILMASKSEPARATEPROC                         ) gl3w_fn(\"glStencilMaskSeparate\");\n\tgl3wStencilOp                                   = ( PFNGLSTENCILOPPROC                                   ) gl3w_fn(\"glStencilOp\");\n\tgl3wStencilOpSeparate                           = ( PFNGLSTENCILOPSEPARATEPROC                           ) gl3w_fn(\"glStencilOpSeparate\");\n\tgl3wTexBuffer                                   = ( PFNGLTEXBUFFERPROC                                   ) gl3w_fn(\"glTexBuffer\");\n\tgl3wTexBufferRange                              = ( PFNGLTEXBUFFERRANGEPROC                              ) gl3w_fn(\"glTexBufferRange\");\n\tgl3wTexImage1D                                  = ( PFNGLTEXIMAGE1DPROC                                  ) gl3w_fn(\"glTexImage1D\");\n\tgl3wTexImage2D                                  = ( PFNGLTEXIMAGE2DPROC                                  ) gl3w_fn(\"glTexImage2D\");\n\tgl3wTexImage2DMultisample                       = ( PFNGLTEXIMAGE2DMULTISAMPLEPROC                       ) gl3w_fn(\"glTexImage2DMultisample\");\n\tgl3wTexImage3D                                  = ( PFNGLTEXIMAGE3DPROC                                  ) gl3w_fn(\"glTexImage3D\");\n\tgl3wTexImage3DMultisample                       = ( PFNGLTEXIMAGE3DMULTISAMPLEPROC                       ) gl3w_fn(\"glTexImage3DMultisample\");\n\tgl3wTexPageCommitmentARB                        = ( PFNGLTEXPAGECOMMITMENTARBPROC                        ) gl3w_fn(\"glTexPageCommitmentARB\");\n\tgl3wTexParameterIiv                             = ( PFNGLTEXPARAMETERIIVPROC                             ) gl3w_fn(\"glTexParameterIiv\");\n\tgl3wTexParameterIuiv                            = ( PFNGLTEXPARAMETERIUIVPROC                            ) gl3w_fn(\"glTexParameterIuiv\");\n\tgl3wTexParameterf                               = ( PFNGLTEXPARAMETERFPROC                               ) gl3w_fn(\"glTexParameterf\");\n\tgl3wTexParameterfv                              = ( PFNGLTEXPARAMETERFVPROC                              ) gl3w_fn(\"glTexParameterfv\");\n\tgl3wTexParameteri                               = ( PFNGLTEXPARAMETERIPROC                               ) gl3w_fn(\"glTexParameteri\");\n\tgl3wTexParameteriv                              = ( PFNGLTEXPARAMETERIVPROC                              ) gl3w_fn(\"glTexParameteriv\");\n\tgl3wTexStorage1D                                = ( PFNGLTEXSTORAGE1DPROC                                ) gl3w_fn(\"glTexStorage1D\");\n\tgl3wTexStorage2D                                = ( PFNGLTEXSTORAGE2DPROC                                ) gl3w_fn(\"glTexStorage2D\");\n\tgl3wTexStorage2DMultisample                     = ( PFNGLTEXSTORAGE2DMULTISAMPLEPROC                     ) gl3w_fn(\"glTexStorage2DMultisample\");\n\tgl3wTexStorage3D                                = ( PFNGLTEXSTORAGE3DPROC                                ) gl3w_fn(\"glTexStorage3D\");\n\tgl3wTexStorage3DMultisample                     = ( PFNGLTEXSTORAGE3DMULTISAMPLEPROC                     ) gl3w_fn(\"glTexStorage3DMultisample\");\n\tgl3wTexSubImage1D                               = ( PFNGLTEXSUBIMAGE1DPROC                               ) gl3w_fn(\"glTexSubImage1D\");\n\tgl3wTexSubImage2D                               = ( PFNGLTEXSUBIMAGE2DPROC                               ) gl3w_fn(\"glTexSubImage2D\");\n\tgl3wTexSubImage3D                               = ( PFNGLTEXSUBIMAGE3DPROC                               ) gl3w_fn(\"glTexSubImage3D\");\n\tgl3wTextureBarrier                              = ( PFNGLTEXTUREBARRIERPROC                              ) gl3w_fn(\"glTextureBarrier\");\n\tgl3wTextureBuffer                               = ( PFNGLTEXTUREBUFFERPROC                               ) gl3w_fn(\"glTextureBuffer\");\n\tgl3wTextureBufferRange                          = ( PFNGLTEXTUREBUFFERRANGEPROC                          ) gl3w_fn(\"glTextureBufferRange\");\n\tgl3wTextureParameterIiv                         = ( PFNGLTEXTUREPARAMETERIIVPROC                         ) gl3w_fn(\"glTextureParameterIiv\");\n\tgl3wTextureParameterIuiv                        = ( PFNGLTEXTUREPARAMETERIUIVPROC                        ) gl3w_fn(\"glTextureParameterIuiv\");\n\tgl3wTextureParameterf                           = ( PFNGLTEXTUREPARAMETERFPROC                           ) gl3w_fn(\"glTextureParameterf\");\n\tgl3wTextureParameterfv                          = ( PFNGLTEXTUREPARAMETERFVPROC                          ) gl3w_fn(\"glTextureParameterfv\");\n\tgl3wTextureParameteri                           = ( PFNGLTEXTUREPARAMETERIPROC                           ) gl3w_fn(\"glTextureParameteri\");\n\tgl3wTextureParameteriv                          = ( PFNGLTEXTUREPARAMETERIVPROC                          ) gl3w_fn(\"glTextureParameteriv\");\n\tgl3wTextureStorage1D                            = ( PFNGLTEXTURESTORAGE1DPROC                            ) gl3w_fn(\"glTextureStorage1D\");\n\tgl3wTextureStorage2D                            = ( PFNGLTEXTURESTORAGE2DPROC                            ) gl3w_fn(\"glTextureStorage2D\");\n\tgl3wTextureStorage2DMultisample                 = ( PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC                 ) gl3w_fn(\"glTextureStorage2DMultisample\");\n\tgl3wTextureStorage3D                            = ( PFNGLTEXTURESTORAGE3DPROC                            ) gl3w_fn(\"glTextureStorage3D\");\n\tgl3wTextureStorage3DMultisample                 = ( PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC                 ) gl3w_fn(\"glTextureStorage3DMultisample\");\n\tgl3wTextureSubImage1D                           = ( PFNGLTEXTURESUBIMAGE1DPROC                           ) gl3w_fn(\"glTextureSubImage1D\");\n\tgl3wTextureSubImage2D                           = ( PFNGLTEXTURESUBIMAGE2DPROC                           ) gl3w_fn(\"glTextureSubImage2D\");\n\tgl3wTextureSubImage3D                           = ( PFNGLTEXTURESUBIMAGE3DPROC                           ) gl3w_fn(\"glTextureSubImage3D\");\n\tgl3wTextureView                                 = ( PFNGLTEXTUREVIEWPROC                                 ) gl3w_fn(\"glTextureView\");\n\tgl3wTransformFeedbackBufferBase                 = ( PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC                 ) gl3w_fn(\"glTransformFeedbackBufferBase\");\n\tgl3wTransformFeedbackBufferRange                = ( PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC                ) gl3w_fn(\"glTransformFeedbackBufferRange\");\n\tgl3wTransformFeedbackVaryings                   = ( PFNGLTRANSFORMFEEDBACKVARYINGSPROC                   ) gl3w_fn(\"glTransformFeedbackVaryings\");\n\tgl3wUniform1d                                   = ( PFNGLUNIFORM1DPROC                                   ) gl3w_fn(\"glUniform1d\");\n\tgl3wUniform1dv                                  = ( PFNGLUNIFORM1DVPROC                                  ) gl3w_fn(\"glUniform1dv\");\n\tgl3wUniform1f                                   = ( PFNGLUNIFORM1FPROC                                   ) gl3w_fn(\"glUniform1f\");\n\tgl3wUniform1fv                                  = ( PFNGLUNIFORM1FVPROC                                  ) gl3w_fn(\"glUniform1fv\");\n\tgl3wUniform1i                                   = ( PFNGLUNIFORM1IPROC                                   ) gl3w_fn(\"glUniform1i\");\n\tgl3wUniform1iv                                  = ( PFNGLUNIFORM1IVPROC                                  ) gl3w_fn(\"glUniform1iv\");\n\tgl3wUniform1ui                                  = ( PFNGLUNIFORM1UIPROC                                  ) gl3w_fn(\"glUniform1ui\");\n\tgl3wUniform1uiv                                 = ( PFNGLUNIFORM1UIVPROC                                 ) gl3w_fn(\"glUniform1uiv\");\n\tgl3wUniform2d                                   = ( PFNGLUNIFORM2DPROC                                   ) gl3w_fn(\"glUniform2d\");\n\tgl3wUniform2dv                                  = ( PFNGLUNIFORM2DVPROC                                  ) gl3w_fn(\"glUniform2dv\");\n\tgl3wUniform2f                                   = ( PFNGLUNIFORM2FPROC                                   ) gl3w_fn(\"glUniform2f\");\n\tgl3wUniform2fv                                  = ( PFNGLUNIFORM2FVPROC                                  ) gl3w_fn(\"glUniform2fv\");\n\tgl3wUniform2i                                   = ( PFNGLUNIFORM2IPROC                                   ) gl3w_fn(\"glUniform2i\");\n\tgl3wUniform2iv                                  = ( PFNGLUNIFORM2IVPROC                                  ) gl3w_fn(\"glUniform2iv\");\n\tgl3wUniform2ui                                  = ( PFNGLUNIFORM2UIPROC                                  ) gl3w_fn(\"glUniform2ui\");\n\tgl3wUniform2uiv                                 = ( PFNGLUNIFORM2UIVPROC                                 ) gl3w_fn(\"glUniform2uiv\");\n\tgl3wUniform3d                                   = ( PFNGLUNIFORM3DPROC                                   ) gl3w_fn(\"glUniform3d\");\n\tgl3wUniform3dv                                  = ( PFNGLUNIFORM3DVPROC                                  ) gl3w_fn(\"glUniform3dv\");\n\tgl3wUniform3f                                   = ( PFNGLUNIFORM3FPROC                                   ) gl3w_fn(\"glUniform3f\");\n\tgl3wUniform3fv                                  = ( PFNGLUNIFORM3FVPROC                                  ) gl3w_fn(\"glUniform3fv\");\n\tgl3wUniform3i                                   = ( PFNGLUNIFORM3IPROC                                   ) gl3w_fn(\"glUniform3i\");\n\tgl3wUniform3iv                                  = ( PFNGLUNIFORM3IVPROC                                  ) gl3w_fn(\"glUniform3iv\");\n\tgl3wUniform3ui                                  = ( PFNGLUNIFORM3UIPROC                                  ) gl3w_fn(\"glUniform3ui\");\n\tgl3wUniform3uiv                                 = ( PFNGLUNIFORM3UIVPROC                                 ) gl3w_fn(\"glUniform3uiv\");\n\tgl3wUniform4d                                   = ( PFNGLUNIFORM4DPROC                                   ) gl3w_fn(\"glUniform4d\");\n\tgl3wUniform4dv                                  = ( PFNGLUNIFORM4DVPROC                                  ) gl3w_fn(\"glUniform4dv\");\n\tgl3wUniform4f                                   = ( PFNGLUNIFORM4FPROC                                   ) gl3w_fn(\"glUniform4f\");\n\tgl3wUniform4fv                                  = ( PFNGLUNIFORM4FVPROC                                  ) gl3w_fn(\"glUniform4fv\");\n\tgl3wUniform4i                                   = ( PFNGLUNIFORM4IPROC                                   ) gl3w_fn(\"glUniform4i\");\n\tgl3wUniform4iv                                  = ( PFNGLUNIFORM4IVPROC                                  ) gl3w_fn(\"glUniform4iv\");\n\tgl3wUniform4ui                                  = ( PFNGLUNIFORM4UIPROC                                  ) gl3w_fn(\"glUniform4ui\");\n\tgl3wUniform4uiv                                 = ( PFNGLUNIFORM4UIVPROC                                 ) gl3w_fn(\"glUniform4uiv\");\n\tgl3wUniformBlockBinding                         = ( PFNGLUNIFORMBLOCKBINDINGPROC                         ) gl3w_fn(\"glUniformBlockBinding\");\n\tgl3wUniformHandleui64ARB                        = ( PFNGLUNIFORMHANDLEUI64ARBPROC                        ) gl3w_fn(\"glUniformHandleui64ARB\");\n\tgl3wUniformHandleui64vARB                       = ( PFNGLUNIFORMHANDLEUI64VARBPROC                       ) gl3w_fn(\"glUniformHandleui64vARB\");\n\tgl3wUniformMatrix2dv                            = ( PFNGLUNIFORMMATRIX2DVPROC                            ) gl3w_fn(\"glUniformMatrix2dv\");\n\tgl3wUniformMatrix2fv                            = ( PFNGLUNIFORMMATRIX2FVPROC                            ) gl3w_fn(\"glUniformMatrix2fv\");\n\tgl3wUniformMatrix2x3dv                          = ( PFNGLUNIFORMMATRIX2X3DVPROC                          ) gl3w_fn(\"glUniformMatrix2x3dv\");\n\tgl3wUniformMatrix2x3fv                          = ( PFNGLUNIFORMMATRIX2X3FVPROC                          ) gl3w_fn(\"glUniformMatrix2x3fv\");\n\tgl3wUniformMatrix2x4dv                          = ( PFNGLUNIFORMMATRIX2X4DVPROC                          ) gl3w_fn(\"glUniformMatrix2x4dv\");\n\tgl3wUniformMatrix2x4fv                          = ( PFNGLUNIFORMMATRIX2X4FVPROC                          ) gl3w_fn(\"glUniformMatrix2x4fv\");\n\tgl3wUniformMatrix3dv                            = ( PFNGLUNIFORMMATRIX3DVPROC                            ) gl3w_fn(\"glUniformMatrix3dv\");\n\tgl3wUniformMatrix3fv                            = ( PFNGLUNIFORMMATRIX3FVPROC                            ) gl3w_fn(\"glUniformMatrix3fv\");\n\tgl3wUniformMatrix3x2dv                          = ( PFNGLUNIFORMMATRIX3X2DVPROC                          ) gl3w_fn(\"glUniformMatrix3x2dv\");\n\tgl3wUniformMatrix3x2fv                          = ( PFNGLUNIFORMMATRIX3X2FVPROC                          ) gl3w_fn(\"glUniformMatrix3x2fv\");\n\tgl3wUniformMatrix3x4dv                          = ( PFNGLUNIFORMMATRIX3X4DVPROC                          ) gl3w_fn(\"glUniformMatrix3x4dv\");\n\tgl3wUniformMatrix3x4fv                          = ( PFNGLUNIFORMMATRIX3X4FVPROC                          ) gl3w_fn(\"glUniformMatrix3x4fv\");\n\tgl3wUniformMatrix4dv                            = ( PFNGLUNIFORMMATRIX4DVPROC                            ) gl3w_fn(\"glUniformMatrix4dv\");\n\tgl3wUniformMatrix4fv                            = ( PFNGLUNIFORMMATRIX4FVPROC                            ) gl3w_fn(\"glUniformMatrix4fv\");\n\tgl3wUniformMatrix4x2dv                          = ( PFNGLUNIFORMMATRIX4X2DVPROC                          ) gl3w_fn(\"glUniformMatrix4x2dv\");\n\tgl3wUniformMatrix4x2fv                          = ( PFNGLUNIFORMMATRIX4X2FVPROC                          ) gl3w_fn(\"glUniformMatrix4x2fv\");\n\tgl3wUniformMatrix4x3dv                          = ( PFNGLUNIFORMMATRIX4X3DVPROC                          ) gl3w_fn(\"glUniformMatrix4x3dv\");\n\tgl3wUniformMatrix4x3fv                          = ( PFNGLUNIFORMMATRIX4X3FVPROC                          ) gl3w_fn(\"glUniformMatrix4x3fv\");\n\tgl3wUniformSubroutinesuiv                       = ( PFNGLUNIFORMSUBROUTINESUIVPROC                       ) gl3w_fn(\"glUniformSubroutinesuiv\");\n\tgl3wUnmapBuffer                                 = ( PFNGLUNMAPBUFFERPROC                                 ) gl3w_fn(\"glUnmapBuffer\");\n\tgl3wUnmapNamedBuffer                            = ( PFNGLUNMAPNAMEDBUFFERPROC                            ) gl3w_fn(\"glUnmapNamedBuffer\");\n\tgl3wUseProgram                                  = ( PFNGLUSEPROGRAMPROC                                  ) gl3w_fn(\"glUseProgram\");\n\tgl3wUseProgramStages                            = ( PFNGLUSEPROGRAMSTAGESPROC                            ) gl3w_fn(\"glUseProgramStages\");\n\tgl3wValidateProgram                             = ( PFNGLVALIDATEPROGRAMPROC                             ) gl3w_fn(\"glValidateProgram\");\n\tgl3wValidateProgramPipeline                     = ( PFNGLVALIDATEPROGRAMPIPELINEPROC                     ) gl3w_fn(\"glValidateProgramPipeline\");\n\tgl3wVertexArrayAttribBinding                    = ( PFNGLVERTEXARRAYATTRIBBINDINGPROC                    ) gl3w_fn(\"glVertexArrayAttribBinding\");\n\tgl3wVertexArrayAttribFormat                     = ( PFNGLVERTEXARRAYATTRIBFORMATPROC                     ) gl3w_fn(\"glVertexArrayAttribFormat\");\n\tgl3wVertexArrayAttribIFormat                    = ( PFNGLVERTEXARRAYATTRIBIFORMATPROC                    ) gl3w_fn(\"glVertexArrayAttribIFormat\");\n\tgl3wVertexArrayAttribLFormat                    = ( PFNGLVERTEXARRAYATTRIBLFORMATPROC                    ) gl3w_fn(\"glVertexArrayAttribLFormat\");\n\tgl3wVertexArrayBindingDivisor                   = ( PFNGLVERTEXARRAYBINDINGDIVISORPROC                   ) gl3w_fn(\"glVertexArrayBindingDivisor\");\n\tgl3wVertexArrayElementBuffer                    = ( PFNGLVERTEXARRAYELEMENTBUFFERPROC                    ) gl3w_fn(\"glVertexArrayElementBuffer\");\n\tgl3wVertexArrayVertexBuffer                     = ( PFNGLVERTEXARRAYVERTEXBUFFERPROC                     ) gl3w_fn(\"glVertexArrayVertexBuffer\");\n\tgl3wVertexArrayVertexBuffers                    = ( PFNGLVERTEXARRAYVERTEXBUFFERSPROC                    ) gl3w_fn(\"glVertexArrayVertexBuffers\");\n\tgl3wVertexAttrib1d                              = ( PFNGLVERTEXATTRIB1DPROC                              ) gl3w_fn(\"glVertexAttrib1d\");\n\tgl3wVertexAttrib1dv                             = ( PFNGLVERTEXATTRIB1DVPROC                             ) gl3w_fn(\"glVertexAttrib1dv\");\n\tgl3wVertexAttrib1f                              = ( PFNGLVERTEXATTRIB1FPROC                              ) gl3w_fn(\"glVertexAttrib1f\");\n\tgl3wVertexAttrib1fv                             = ( PFNGLVERTEXATTRIB1FVPROC                             ) gl3w_fn(\"glVertexAttrib1fv\");\n\tgl3wVertexAttrib1s                              = ( PFNGLVERTEXATTRIB1SPROC                              ) gl3w_fn(\"glVertexAttrib1s\");\n\tgl3wVertexAttrib1sv                             = ( PFNGLVERTEXATTRIB1SVPROC                             ) gl3w_fn(\"glVertexAttrib1sv\");\n\tgl3wVertexAttrib2d                              = ( PFNGLVERTEXATTRIB2DPROC                              ) gl3w_fn(\"glVertexAttrib2d\");\n\tgl3wVertexAttrib2dv                             = ( PFNGLVERTEXATTRIB2DVPROC                             ) gl3w_fn(\"glVertexAttrib2dv\");\n\tgl3wVertexAttrib2f                              = ( PFNGLVERTEXATTRIB2FPROC                              ) gl3w_fn(\"glVertexAttrib2f\");\n\tgl3wVertexAttrib2fv                             = ( PFNGLVERTEXATTRIB2FVPROC                             ) gl3w_fn(\"glVertexAttrib2fv\");\n\tgl3wVertexAttrib2s                              = ( PFNGLVERTEXATTRIB2SPROC                              ) gl3w_fn(\"glVertexAttrib2s\");\n\tgl3wVertexAttrib2sv                             = ( PFNGLVERTEXATTRIB2SVPROC                             ) gl3w_fn(\"glVertexAttrib2sv\");\n\tgl3wVertexAttrib3d                              = ( PFNGLVERTEXATTRIB3DPROC                              ) gl3w_fn(\"glVertexAttrib3d\");\n\tgl3wVertexAttrib3dv                             = ( PFNGLVERTEXATTRIB3DVPROC                             ) gl3w_fn(\"glVertexAttrib3dv\");\n\tgl3wVertexAttrib3f                              = ( PFNGLVERTEXATTRIB3FPROC                              ) gl3w_fn(\"glVertexAttrib3f\");\n\tgl3wVertexAttrib3fv                             = ( PFNGLVERTEXATTRIB3FVPROC                             ) gl3w_fn(\"glVertexAttrib3fv\");\n\tgl3wVertexAttrib3s                              = ( PFNGLVERTEXATTRIB3SPROC                              ) gl3w_fn(\"glVertexAttrib3s\");\n\tgl3wVertexAttrib3sv                             = ( PFNGLVERTEXATTRIB3SVPROC                             ) gl3w_fn(\"glVertexAttrib3sv\");\n\tgl3wVertexAttrib4Nbv                            = ( PFNGLVERTEXATTRIB4NBVPROC                            ) gl3w_fn(\"glVertexAttrib4Nbv\");\n\tgl3wVertexAttrib4Niv                            = ( PFNGLVERTEXATTRIB4NIVPROC                            ) gl3w_fn(\"glVertexAttrib4Niv\");\n\tgl3wVertexAttrib4Nsv                            = ( PFNGLVERTEXATTRIB4NSVPROC                            ) gl3w_fn(\"glVertexAttrib4Nsv\");\n\tgl3wVertexAttrib4Nub                            = ( PFNGLVERTEXATTRIB4NUBPROC                            ) gl3w_fn(\"glVertexAttrib4Nub\");\n\tgl3wVertexAttrib4Nubv                           = ( PFNGLVERTEXATTRIB4NUBVPROC                           ) gl3w_fn(\"glVertexAttrib4Nubv\");\n\tgl3wVertexAttrib4Nuiv                           = ( PFNGLVERTEXATTRIB4NUIVPROC                           ) gl3w_fn(\"glVertexAttrib4Nuiv\");\n\tgl3wVertexAttrib4Nusv                           = ( PFNGLVERTEXATTRIB4NUSVPROC                           ) gl3w_fn(\"glVertexAttrib4Nusv\");\n\tgl3wVertexAttrib4bv                             = ( PFNGLVERTEXATTRIB4BVPROC                             ) gl3w_fn(\"glVertexAttrib4bv\");\n\tgl3wVertexAttrib4d                              = ( PFNGLVERTEXATTRIB4DPROC                              ) gl3w_fn(\"glVertexAttrib4d\");\n\tgl3wVertexAttrib4dv                             = ( PFNGLVERTEXATTRIB4DVPROC                             ) gl3w_fn(\"glVertexAttrib4dv\");\n\tgl3wVertexAttrib4f                              = ( PFNGLVERTEXATTRIB4FPROC                              ) gl3w_fn(\"glVertexAttrib4f\");\n\tgl3wVertexAttrib4fv                             = ( PFNGLVERTEXATTRIB4FVPROC                             ) gl3w_fn(\"glVertexAttrib4fv\");\n\tgl3wVertexAttrib4iv                             = ( PFNGLVERTEXATTRIB4IVPROC                             ) gl3w_fn(\"glVertexAttrib4iv\");\n\tgl3wVertexAttrib4s                              = ( PFNGLVERTEXATTRIB4SPROC                              ) gl3w_fn(\"glVertexAttrib4s\");\n\tgl3wVertexAttrib4sv                             = ( PFNGLVERTEXATTRIB4SVPROC                             ) gl3w_fn(\"glVertexAttrib4sv\");\n\tgl3wVertexAttrib4ubv                            = ( PFNGLVERTEXATTRIB4UBVPROC                            ) gl3w_fn(\"glVertexAttrib4ubv\");\n\tgl3wVertexAttrib4uiv                            = ( PFNGLVERTEXATTRIB4UIVPROC                            ) gl3w_fn(\"glVertexAttrib4uiv\");\n\tgl3wVertexAttrib4usv                            = ( PFNGLVERTEXATTRIB4USVPROC                            ) gl3w_fn(\"glVertexAttrib4usv\");\n\tgl3wVertexAttribBinding                         = ( PFNGLVERTEXATTRIBBINDINGPROC                         ) gl3w_fn(\"glVertexAttribBinding\");\n\tgl3wVertexAttribDivisor                         = ( PFNGLVERTEXATTRIBDIVISORPROC                         ) gl3w_fn(\"glVertexAttribDivisor\");\n\tgl3wVertexAttribFormat                          = ( PFNGLVERTEXATTRIBFORMATPROC                          ) gl3w_fn(\"glVertexAttribFormat\");\n\tgl3wVertexAttribI1i                             = ( PFNGLVERTEXATTRIBI1IPROC                             ) gl3w_fn(\"glVertexAttribI1i\");\n\tgl3wVertexAttribI1iv                            = ( PFNGLVERTEXATTRIBI1IVPROC                            ) gl3w_fn(\"glVertexAttribI1iv\");\n\tgl3wVertexAttribI1ui                            = ( PFNGLVERTEXATTRIBI1UIPROC                            ) gl3w_fn(\"glVertexAttribI1ui\");\n\tgl3wVertexAttribI1uiv                           = ( PFNGLVERTEXATTRIBI1UIVPROC                           ) gl3w_fn(\"glVertexAttribI1uiv\");\n\tgl3wVertexAttribI2i                             = ( PFNGLVERTEXATTRIBI2IPROC                             ) gl3w_fn(\"glVertexAttribI2i\");\n\tgl3wVertexAttribI2iv                            = ( PFNGLVERTEXATTRIBI2IVPROC                            ) gl3w_fn(\"glVertexAttribI2iv\");\n\tgl3wVertexAttribI2ui                            = ( PFNGLVERTEXATTRIBI2UIPROC                            ) gl3w_fn(\"glVertexAttribI2ui\");\n\tgl3wVertexAttribI2uiv                           = ( PFNGLVERTEXATTRIBI2UIVPROC                           ) gl3w_fn(\"glVertexAttribI2uiv\");\n\tgl3wVertexAttribI3i                             = ( PFNGLVERTEXATTRIBI3IPROC                             ) gl3w_fn(\"glVertexAttribI3i\");\n\tgl3wVertexAttribI3iv                            = ( PFNGLVERTEXATTRIBI3IVPROC                            ) gl3w_fn(\"glVertexAttribI3iv\");\n\tgl3wVertexAttribI3ui                            = ( PFNGLVERTEXATTRIBI3UIPROC                            ) gl3w_fn(\"glVertexAttribI3ui\");\n\tgl3wVertexAttribI3uiv                           = ( PFNGLVERTEXATTRIBI3UIVPROC                           ) gl3w_fn(\"glVertexAttribI3uiv\");\n\tgl3wVertexAttribI4bv                            = ( PFNGLVERTEXATTRIBI4BVPROC                            ) gl3w_fn(\"glVertexAttribI4bv\");\n\tgl3wVertexAttribI4i                             = ( PFNGLVERTEXATTRIBI4IPROC                             ) gl3w_fn(\"glVertexAttribI4i\");\n\tgl3wVertexAttribI4iv                            = ( PFNGLVERTEXATTRIBI4IVPROC                            ) gl3w_fn(\"glVertexAttribI4iv\");\n\tgl3wVertexAttribI4sv                            = ( PFNGLVERTEXATTRIBI4SVPROC                            ) gl3w_fn(\"glVertexAttribI4sv\");\n\tgl3wVertexAttribI4ubv                           = ( PFNGLVERTEXATTRIBI4UBVPROC                           ) gl3w_fn(\"glVertexAttribI4ubv\");\n\tgl3wVertexAttribI4ui                            = ( PFNGLVERTEXATTRIBI4UIPROC                            ) gl3w_fn(\"glVertexAttribI4ui\");\n\tgl3wVertexAttribI4uiv                           = ( PFNGLVERTEXATTRIBI4UIVPROC                           ) gl3w_fn(\"glVertexAttribI4uiv\");\n\tgl3wVertexAttribI4usv                           = ( PFNGLVERTEXATTRIBI4USVPROC                           ) gl3w_fn(\"glVertexAttribI4usv\");\n\tgl3wVertexAttribIFormat                         = ( PFNGLVERTEXATTRIBIFORMATPROC                         ) gl3w_fn(\"glVertexAttribIFormat\");\n\tgl3wVertexAttribIPointer                        = ( PFNGLVERTEXATTRIBIPOINTERPROC                        ) gl3w_fn(\"glVertexAttribIPointer\");\n\tgl3wVertexAttribL1d                             = ( PFNGLVERTEXATTRIBL1DPROC                             ) gl3w_fn(\"glVertexAttribL1d\");\n\tgl3wVertexAttribL1dv                            = ( PFNGLVERTEXATTRIBL1DVPROC                            ) gl3w_fn(\"glVertexAttribL1dv\");\n\tgl3wVertexAttribL1ui64ARB                       = ( PFNGLVERTEXATTRIBL1UI64ARBPROC                       ) gl3w_fn(\"glVertexAttribL1ui64ARB\");\n\tgl3wVertexAttribL1ui64vARB                      = ( PFNGLVERTEXATTRIBL1UI64VARBPROC                      ) gl3w_fn(\"glVertexAttribL1ui64vARB\");\n\tgl3wVertexAttribL2d                             = ( PFNGLVERTEXATTRIBL2DPROC                             ) gl3w_fn(\"glVertexAttribL2d\");\n\tgl3wVertexAttribL2dv                            = ( PFNGLVERTEXATTRIBL2DVPROC                            ) gl3w_fn(\"glVertexAttribL2dv\");\n\tgl3wVertexAttribL3d                             = ( PFNGLVERTEXATTRIBL3DPROC                             ) gl3w_fn(\"glVertexAttribL3d\");\n\tgl3wVertexAttribL3dv                            = ( PFNGLVERTEXATTRIBL3DVPROC                            ) gl3w_fn(\"glVertexAttribL3dv\");\n\tgl3wVertexAttribL4d                             = ( PFNGLVERTEXATTRIBL4DPROC                             ) gl3w_fn(\"glVertexAttribL4d\");\n\tgl3wVertexAttribL4dv                            = ( PFNGLVERTEXATTRIBL4DVPROC                            ) gl3w_fn(\"glVertexAttribL4dv\");\n\tgl3wVertexAttribLFormat                         = ( PFNGLVERTEXATTRIBLFORMATPROC                         ) gl3w_fn(\"glVertexAttribLFormat\");\n\tgl3wVertexAttribLPointer                        = ( PFNGLVERTEXATTRIBLPOINTERPROC                        ) gl3w_fn(\"glVertexAttribLPointer\");\n\tgl3wVertexAttribP1ui                            = ( PFNGLVERTEXATTRIBP1UIPROC                            ) gl3w_fn(\"glVertexAttribP1ui\");\n\tgl3wVertexAttribP1uiv                           = ( PFNGLVERTEXATTRIBP1UIVPROC                           ) gl3w_fn(\"glVertexAttribP1uiv\");\n\tgl3wVertexAttribP2ui                            = ( PFNGLVERTEXATTRIBP2UIPROC                            ) gl3w_fn(\"glVertexAttribP2ui\");\n\tgl3wVertexAttribP2uiv                           = ( PFNGLVERTEXATTRIBP2UIVPROC                           ) gl3w_fn(\"glVertexAttribP2uiv\");\n\tgl3wVertexAttribP3ui                            = ( PFNGLVERTEXATTRIBP3UIPROC                            ) gl3w_fn(\"glVertexAttribP3ui\");\n\tgl3wVertexAttribP3uiv                           = ( PFNGLVERTEXATTRIBP3UIVPROC                           ) gl3w_fn(\"glVertexAttribP3uiv\");\n\tgl3wVertexAttribP4ui                            = ( PFNGLVERTEXATTRIBP4UIPROC                            ) gl3w_fn(\"glVertexAttribP4ui\");\n\tgl3wVertexAttribP4uiv                           = ( PFNGLVERTEXATTRIBP4UIVPROC                           ) gl3w_fn(\"glVertexAttribP4uiv\");\n\tgl3wVertexAttribPointer                         = ( PFNGLVERTEXATTRIBPOINTERPROC                         ) gl3w_fn(\"glVertexAttribPointer\");\n\tgl3wVertexBindingDivisor                        = ( PFNGLVERTEXBINDINGDIVISORPROC                        ) gl3w_fn(\"glVertexBindingDivisor\");\n\tgl3wViewport                                    = ( PFNGLVIEWPORTPROC                                    ) gl3w_fn(\"glViewport\");\n\tgl3wViewportArrayv                              = ( PFNGLVIEWPORTARRAYVPROC                              ) gl3w_fn(\"glViewportArrayv\");\n\tgl3wViewportIndexedf                            = ( PFNGLVIEWPORTINDEXEDFPROC                            ) gl3w_fn(\"glViewportIndexedf\");\n\tgl3wViewportIndexedfv                           = ( PFNGLVIEWPORTINDEXEDFVPROC                           ) gl3w_fn(\"glViewportIndexedfv\");\n\tgl3wWaitSync                                    = ( PFNGLWAITSYNCPROC                                    ) gl3w_fn(\"glWaitSync\");\n}\n"
  },
  {
    "path": "samples/sample_d3d11.cpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   sample_d3d11.cpp\n// Author: Guilherme R. Lampert\n// Brief:  D3D11 Debug Draw sample. Also uses the newer explicit context API.\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#define DEBUG_DRAW_IMPLEMENTATION\n#define DEBUG_DRAW_EXPLICIT_CONTEXT\n#include \"debug_draw.hpp\"\n\n#define DD_SAMPLES_NOGL\n#include \"samples_common.hpp\"\nusing namespace ddSamplesCommon;\n\n#include <cstdlib>\n#include <tuple>\n\n#define NOIME\n#define NOMINMAX\n#define WIN32_LEAN_AND_MEAN\n#include <ShellScalingAPI.h>\n#include <windows.h>\n#include <wrl.h>\n\n#include <dxgi.h>\n#include <d3d11.h>\n#include <d3d11_1.h>\n#include <d3dcompiler.h>\n#include <DirectXMath.h>\n\n#pragma comment(lib, \"Shcore\")\n#pragma comment(lib, \"d3d11\")\n#pragma comment(lib, \"dxguid\")\n#pragma comment(lib, \"d3dcompiler\")\n\nusing Microsoft::WRL::ComPtr;\n\n// ========================================================\n// Helper functions\n// ========================================================\n\nstatic void panicF(const char * format, ...)\n{\n    va_list args;\n    char buffer[2048] = {'\\0'};\n\n    va_start(args, format);\n    std::vsnprintf(buffer, sizeof(buffer), format, args);\n    va_end(args);\n\n    MessageBoxA(nullptr, buffer, \"Fatal Error\", MB_OK);\n    std::abort();\n}\n\n// ========================================================\n// Window\n// ========================================================\n\nconst wchar_t WindowTitle[] = L\"Debug Draw - D3D11 Sample\";\nconst wchar_t WindowClassName[] = L\"DebugDrawD3D11\";\n\nclass Window\n{\npublic:\n\n    HINSTANCE hInst   = nullptr;\n    HWND      hWindow = nullptr;\n\n    Window(HINSTANCE hInstance, int nCmdShow)\n        : hInst(hInstance)\n    {\n        registerClass();\n        createWindow(nCmdShow);\n    }\n\n    virtual ~Window()\n    {\n        if (hWindow != nullptr)\n        {\n            DestroyWindow(hWindow);\n        }\n        if (hInst != nullptr)\n        {\n            UnregisterClass(WindowClassName, hInst);\n        }\n    }\n\n    void runMessageLoop()\n    {\n        MSG msg = {0};\n        while (msg.message != WM_QUIT)\n        {\n            if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))\n            {\n                TranslateMessage(&msg);\n                DispatchMessage(&msg);\n            }\n            onRender();\n        }\n    }\n\n    virtual void onRender() { }\n\n    //\n    // DPI scaling helpers:\n    //\n\n    static const std::tuple<float, float> DpiXY;\n    static const int WidthScaled;\n    static const int HeightScaled;\n\n    static int GetDpiAdjustedX(int size) { return static_cast<int>(size * std::get<0>(DpiXY) / 96.0f); }\n    static int GetDpiAdjustedY(int size) { return static_cast<int>(size * std::get<1>(DpiXY) / 96.0f); }\n\n    static std::tuple<float, float> GetDpiXY()\n    {\n        const POINT ptZero = {0,0};\n        HMONITOR hm = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);\n\n        UINT dpiX = 0, dpiY = 0;\n        if (FAILED(GetDpiForMonitor(hm, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))\n        {\n            dpiX = dpiY = 192; // Some arbitrary default (2x scaling)\n        }\n\n        return {float(dpiX), float(dpiY)};\n    }\n\nprivate:\n\n    void registerClass()\n    {\n        WNDCLASSEX wcex    = {0};\n        wcex.cbSize        = sizeof(WNDCLASSEX);\n        wcex.style         = CS_HREDRAW | CS_VREDRAW;\n        wcex.lpfnWndProc   = &Window::WndProc;\n        wcex.hInstance     = hInst;\n        wcex.lpszClassName = WindowClassName;\n        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);\n        wcex.hIcon         = LoadIcon(nullptr, IDI_APPLICATION);\n        wcex.hIconSm       = LoadIcon(nullptr, IDI_APPLICATION);\n        wcex.hCursor       = LoadCursor(nullptr, IDC_ARROW);\n        RegisterClassEx(&wcex);\n    }\n\n    void createWindow(int nCmdShow)\n    {\n        hWindow = CreateWindow(WindowClassName, WindowTitle, WS_OVERLAPPEDWINDOW,\n                               0, 0, WidthScaled, HeightScaled,\n                               nullptr, nullptr, hInst, nullptr);\n        if (hWindow == nullptr)\n        {\n            panicF(\"Failed to create application window!\");\n        }\n        ShowWindow(hWindow, nCmdShow);\n        UpdateWindow(hWindow);\n    }\n\n    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\n    {\n        switch (message)\n        {\n        case WM_DESTROY:\n            PostQuitMessage(0);\n            return 0;\n\n        case WM_KEYDOWN:\n            if (wParam == VK_RETURN) { keys.showGrid   = !keys.showGrid;   }\n            if (wParam == VK_SPACE)  { keys.showLabels = !keys.showLabels; }\n            return 0;\n\n        case WM_MOUSEMOVE:\n            {\n                int mx = LOWORD(lParam); \n                int my = HIWORD(lParam); \n\n                // Clamp to window bounds:\n                if      (mx > WidthScaled)  { mx = WidthScaled;  }\n                else if (mx < 0)            { mx = 0;            }\n                if      (my > HeightScaled) { my = HeightScaled; }\n                else if (my < 0)            { my = 0;            }\n\n                mouse.deltaX = mx - mouse.lastPosX;\n                mouse.deltaY = my - mouse.lastPosY;\n                mouse.lastPosX = mx;\n                mouse.lastPosY = my;\n\n                // Clamp between -/+ max delta:\n                if      (mouse.deltaX >  Mouse::MaxDelta) { mouse.deltaX =  Mouse::MaxDelta; }\n                else if (mouse.deltaX < -Mouse::MaxDelta) { mouse.deltaX = -Mouse::MaxDelta; }\n                if      (mouse.deltaY >  Mouse::MaxDelta) { mouse.deltaY =  Mouse::MaxDelta; }\n                else if (mouse.deltaY < -Mouse::MaxDelta) { mouse.deltaY = -Mouse::MaxDelta; }\n            }\n            return 0;\n\n        default:\n            break;\n        } // switch\n\n        return DefWindowProc(hWnd, message, wParam, lParam);\n    }\n};\n\n// Caching these for convenience\nconst std::tuple<float, float> Window::DpiXY = Window::GetDpiXY();\nconst int Window::WidthScaled  = Window::GetDpiAdjustedX(WindowWidth);\nconst int Window::HeightScaled = Window::GetDpiAdjustedY(WindowHeight);\n\n// ========================================================\n// RenderWindowD3D11\n// ========================================================\n\nclass RenderWindowD3D11 final\n    : public Window\n{\npublic:\n\n    ComPtr<IDXGISwapChain>         swapChain;\n    ComPtr<ID3D11Device>           d3dDevice;\n    ComPtr<ID3D11DeviceContext>    deviceContext;\n    ComPtr<ID3D11RenderTargetView> renderTargetView;\n    std::function<void()>          renderCallback;\n\n    RenderWindowD3D11(HINSTANCE hInstance, int nCmdShow)\n        : Window(hInstance, nCmdShow)\n    {\n        initD3D();\n    }\n\n    void onRender() override\n    {\n        const float clearColor[] = {0.2f, 0.2f, 0.2f, 1.0f};\n        deviceContext->ClearRenderTargetView(renderTargetView.Get(), clearColor);\n\n        if (renderCallback)\n        {\n            renderCallback();\n        }\n\n        swapChain->Present(0, 0);\n    }\n\nprivate:\n\n    void initD3D()\n    {\n        UINT createDeviceFlags = 0;\n        const UINT width  = Window::WidthScaled;\n        const UINT height = Window::HeightScaled;\n\n        // If the project is in a debug build, enable debugging via SDK Layers with this flag.\n        #if defined(DEBUG) || defined(_DEBUG)\n        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;\n        #endif // DEBUG\n\n        // Acceptable driver types.\n        const D3D_DRIVER_TYPE driverTypes[] = {\n            D3D_DRIVER_TYPE_HARDWARE,\n            D3D_DRIVER_TYPE_WARP,\n            D3D_DRIVER_TYPE_REFERENCE,\n        };\n        const UINT numDriverTypes = ARRAYSIZE(driverTypes);\n\n        // This array defines the ordering of feature levels that D3D should attempt to create.\n        const D3D_FEATURE_LEVEL featureLevels[] = {\n            D3D_FEATURE_LEVEL_11_1,\n            D3D_FEATURE_LEVEL_11_0,\n            D3D_FEATURE_LEVEL_10_1,\n            D3D_FEATURE_LEVEL_10_0,\n        };\n        const UINT numFeatureLevels = ARRAYSIZE(featureLevels);\n\n        DXGI_SWAP_CHAIN_DESC sd               = {0};\n        sd.BufferCount                        = 2;\n        sd.BufferDesc.Width                   = width;\n        sd.BufferDesc.Height                  = height;\n        sd.BufferDesc.Format                  = DXGI_FORMAT_R8G8B8A8_UNORM;\n        sd.BufferDesc.RefreshRate.Numerator   = 60;\n        sd.BufferDesc.RefreshRate.Denominator = 1;\n        sd.BufferUsage                        = DXGI_USAGE_RENDER_TARGET_OUTPUT;\n        sd.OutputWindow                       = hWindow;\n        sd.SampleDesc.Count                   = 1;\n        sd.SampleDesc.Quality                 = 0;\n        sd.Windowed                           = true;\n        sd.SwapEffect                         = DXGI_SWAP_EFFECT_DISCARD;\n\n        HRESULT hr;\n        D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;\n\n        // Try to create the device and swap chain:\n        for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex)\n        {\n            auto driverType = driverTypes[driverTypeIndex];\n            hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags,\n                                               featureLevels, numFeatureLevels, D3D11_SDK_VERSION,\n                                               &sd, swapChain.GetAddressOf(), d3dDevice.GetAddressOf(),\n                                               &featureLevel, deviceContext.GetAddressOf());\n\n            if (hr == E_INVALIDARG)\n            {\n                // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it\n                hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags,\n                                                   &featureLevels[1], numFeatureLevels - 1,\n                                                   D3D11_SDK_VERSION, &sd, swapChain.GetAddressOf(),\n                                                   d3dDevice.GetAddressOf(), &featureLevel,\n                                                   deviceContext.GetAddressOf());\n            }\n\n            if (SUCCEEDED(hr))\n            {\n                break;\n            }\n        }\n\n        if (FAILED(hr))\n        {\n            panicF(\"Failed to create D3D device or swap chain!\");\n        }\n\n        // Create a render target view for the framebuffer:\n        ID3D11Texture2D * backBuffer = nullptr;\n        hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer);\n        if (FAILED(hr))\n        {\n            panicF(\"Failed to get framebuffer from swap chain!\");\n        }\n\n        hr = d3dDevice->CreateRenderTargetView(backBuffer, nullptr, renderTargetView.GetAddressOf());\n        backBuffer->Release();\n        if (FAILED(hr))\n        {\n            panicF(\"Failed to create RTV for framebuffer!\");\n        }\n\n        deviceContext->OMSetRenderTargets(1, renderTargetView.GetAddressOf(), nullptr);\n\n        // Setup the viewport:\n        D3D11_VIEWPORT vp;\n        vp.Width    = static_cast<float>(width);\n        vp.Height   = static_cast<float>(height);\n        vp.MinDepth = 0.0f;\n        vp.MaxDepth = 1.0f;\n        vp.TopLeftX = 0;\n        vp.TopLeftY = 0;\n        deviceContext->RSSetViewports(1, &vp);\n    }\n};\n\n// ========================================================\n// ShaderSetD3D11\n// ========================================================\n\nstruct ShaderSetD3D11 final\n{\n    using InputLayoutDesc = std::tuple<const D3D11_INPUT_ELEMENT_DESC *, int>;\n\n    ComPtr<ID3D11VertexShader> vs;\n    ComPtr<ID3D11PixelShader>  ps;\n    ComPtr<ID3D11InputLayout>  vertexLayout;\n\n    ShaderSetD3D11() = default;\n\n    void loadFromFxFile(ID3D11Device * device, const wchar_t * filename,\n                        const char * vsEntry, const char * psEntry,\n                        const InputLayoutDesc & layout)\n    {\n        assert(filename != nullptr && filename[0] != L'\\0');\n        assert(vsEntry  != nullptr && vsEntry[0]  != '\\0');\n        assert(psEntry  != nullptr && psEntry[0]  != '\\0');\n\n        ComPtr<ID3DBlob> vsBlob;\n        compileShaderFromFile(filename, vsEntry, \"vs_4_0\", vsBlob.GetAddressOf());\n        assert(vsBlob != nullptr);\n\n        ComPtr<ID3DBlob> psBlob;\n        compileShaderFromFile(filename, psEntry, \"ps_4_0\", psBlob.GetAddressOf());\n        assert(psBlob != nullptr);\n\n        HRESULT hr;\n\n        // Create the vertex shader:\n        hr = device->CreateVertexShader(vsBlob->GetBufferPointer(),\n                                        vsBlob->GetBufferSize(), nullptr,\n                                        vs.GetAddressOf());\n        if (FAILED(hr))\n        {\n            panicF(\"Failed to create vertex shader '%s'\", vsEntry);\n        }\n\n        // Create the pixel shader:\n        hr = device->CreatePixelShader(psBlob->GetBufferPointer(),\n                                       psBlob->GetBufferSize(), nullptr,\n                                       ps.GetAddressOf());\n        if (FAILED(hr))\n        {\n            panicF(\"Failed to create pixel shader '%s'\", psEntry);\n        }\n\n        // Create vertex input layout:\n        hr = device->CreateInputLayout(std::get<0>(layout), std::get<1>(layout),\n                                       vsBlob->GetBufferPointer(),\n                                       vsBlob->GetBufferSize(),\n                                       vertexLayout.GetAddressOf());\n        if (FAILED(hr))\n        {\n            panicF(\"Failed to create vertex layout!\");\n        }\n    }\n\n    static void compileShaderFromFile(const wchar_t * fileName, const char * entryPoint,\n                                      const char * shaderModel, ID3DBlob ** ppBlobOut)\n    {\n        UINT shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;\n\n        // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.\n        // Setting this flag improves the shader debugging experience, but still allows\n        // the shaders to be optimized and to run exactly the way they will run in\n        // the release configuration.\n        #if defined(DEBUG) || defined(_DEBUG)\n        shaderFlags |= D3DCOMPILE_DEBUG;\n        #endif // DEBUG\n\n        ComPtr<ID3DBlob> pErrorBlob;\n        HRESULT hr = D3DCompileFromFile(fileName, nullptr, nullptr, entryPoint, shaderModel,\n                                        shaderFlags, 0, ppBlobOut, pErrorBlob.GetAddressOf());\n        if (FAILED(hr))\n        {\n            auto * details = (pErrorBlob ? static_cast<const char *>(pErrorBlob->GetBufferPointer()) : \"<no info>\");\n            panicF(\"Failed to compile shader! Error info: %s\", details);\n        }\n    }\n};\n\n// ========================================================\n// RenderInterfaceD3D11\n// ========================================================\n\nclass RenderInterfaceD3D11 final\n    : public dd::RenderInterface\n{\npublic:\n\n    RenderInterfaceD3D11(const ComPtr<ID3D11Device> & pDevice, const ComPtr<ID3D11DeviceContext> & pContext)\n        : d3dDevice(pDevice)\n        , deviceContext(pContext)\n    {\n        initShaders();\n        initBuffers();\n    }\n\n    void setMvpMatrixPtr(const float * const mtx)\n    {\n        constantBufferData.mvpMatrix = DirectX::XMMATRIX(mtx);\n    }\n\n    void setCameraFrame(const Vector3 & up, const Vector3 & right, const Vector3 & origin)\n    {\n        camUp = up; camRight = right; camOrigin = origin;\n    }\n\n    //\n    // dd::RenderInterface overrides:\n    //\n\n    void beginDraw() override\n    {\n        // Update and set the constant buffer for this frame\n        deviceContext->UpdateSubresource(constantBuffer.Get(), 0, nullptr, &constantBufferData, 0, 0);\n        deviceContext->VSSetConstantBuffers(0, 1, constantBuffer.GetAddressOf());\n\n        // Disable culling for the screen text\n        deviceContext->RSSetState(rasterizerState.Get());\n    }\n\n    void endDraw() override\n    {\n        // No work done here at the moment.\n    }\n\n    dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override\n    {\n        UINT numQualityLevels = 0;\n        d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8_UNORM, 1, &numQualityLevels);\n\n        D3D11_TEXTURE2D_DESC tex2dDesc  = {};\n        tex2dDesc.Usage                 = D3D11_USAGE_DEFAULT;\n        tex2dDesc.BindFlags             = D3D11_BIND_SHADER_RESOURCE;\n        tex2dDesc.Format                = DXGI_FORMAT_R8_UNORM;\n        tex2dDesc.Width                 = width;\n        tex2dDesc.Height                = height;\n        tex2dDesc.MipLevels             = 1;\n        tex2dDesc.ArraySize             = 1;\n        tex2dDesc.SampleDesc.Count      = 1;\n        tex2dDesc.SampleDesc.Quality    = numQualityLevels - 1;\n\n        D3D11_SAMPLER_DESC samplerDesc  = {};\n        samplerDesc.Filter              = D3D11_FILTER_MIN_MAG_MIP_LINEAR;\n        samplerDesc.AddressU            = D3D11_TEXTURE_ADDRESS_CLAMP;\n        samplerDesc.AddressV            = D3D11_TEXTURE_ADDRESS_CLAMP;\n        samplerDesc.AddressW            = D3D11_TEXTURE_ADDRESS_CLAMP;\n        samplerDesc.ComparisonFunc      = D3D11_COMPARISON_ALWAYS;\n        samplerDesc.MaxAnisotropy       = 1;\n        samplerDesc.MipLODBias          = 0.0f;\n        samplerDesc.MinLOD              = 0.0f;\n        samplerDesc.MaxLOD              = D3D11_FLOAT32_MAX;\n\n        D3D11_SUBRESOURCE_DATA initData = {};\n        initData.pSysMem                = pixels;\n        initData.SysMemPitch            = width;\n\n        auto * texImpl = new TextureImpl{};\n\n        if (FAILED(d3dDevice->CreateTexture2D(&tex2dDesc, &initData, &texImpl->d3dTexPtr)))\n        {\n            errorF(\"CreateTexture2D failed!\");\n            destroyGlyphTexture(texImpl);\n            return nullptr;\n        }\n        if (FAILED(d3dDevice->CreateShaderResourceView(texImpl->d3dTexPtr, nullptr, &texImpl->d3dTexSRV)))\n        {\n            errorF(\"CreateShaderResourceView failed!\");\n            destroyGlyphTexture(texImpl);\n            return nullptr;\n        }\n        if (FAILED(d3dDevice->CreateSamplerState(&samplerDesc, &texImpl->d3dSampler)))\n        {\n            errorF(\"CreateSamplerState failed!\");\n            destroyGlyphTexture(texImpl);\n            return nullptr;\n        }\n\n        return static_cast<dd::GlyphTextureHandle>(texImpl);\n    }\n\n    void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override\n    {\n        auto * texImpl = static_cast<TextureImpl *>(glyphTex);\n        if (texImpl)\n        {\n            if (texImpl->d3dSampler) { texImpl->d3dSampler->Release(); }\n            if (texImpl->d3dTexSRV)  { texImpl->d3dTexSRV->Release();  }\n            if (texImpl->d3dTexPtr)  { texImpl->d3dTexPtr->Release();  }\n            delete texImpl;\n        }\n    }\n\n    void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(glyphs != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        auto * texImpl = static_cast<TextureImpl *>(glyphTex);\n        assert(texImpl != nullptr);\n\n        // Map the vertex buffer:\n        D3D11_MAPPED_SUBRESOURCE mapInfo;\n        if (FAILED(deviceContext->Map(glyphVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo)))\n        {\n            panicF(\"Failed to map vertex buffer!\");\n        }\n\n        // Copy into mapped buffer:\n        auto * verts = static_cast<Vertex *>(mapInfo.pData);\n        for (int v = 0; v < count; ++v)\n        {\n            verts[v].pos.x = glyphs[v].glyph.x;\n            verts[v].pos.y = glyphs[v].glyph.y;\n            verts[v].pos.z = 0.0f;\n            verts[v].pos.w = 1.0f;\n\n            verts[v].uv.x = glyphs[v].glyph.u;\n            verts[v].uv.y = glyphs[v].glyph.v;\n            verts[v].uv.z = 0.0f;\n            verts[v].uv.w = 0.0f;\n\n            verts[v].color.x = glyphs[v].glyph.r;\n            verts[v].color.y = glyphs[v].glyph.g;\n            verts[v].color.z = glyphs[v].glyph.b;\n            verts[v].color.w = 1.0f;\n        }\n\n        // Unmap and draw:\n        deviceContext->Unmap(glyphVertexBuffer.Get(), 0);\n\n        // Bind texture & sampler (t0, s0):\n        deviceContext->PSSetShaderResources(0, 1, &texImpl->d3dTexSRV);\n        deviceContext->PSSetSamplers(0, 1, &texImpl->d3dSampler);\n\n        const float blendFactor[] = {1.0f, 1.0f, 1.0f, 1.0f};\n        deviceContext->OMSetBlendState(blendStateText.Get(), blendFactor, 0xFFFFFFFF);\n\n        // Draw with the current buffer:\n        drawHelper(count, glyphShaders, glyphVertexBuffer.Get(), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\n\n        // Restore default blend state.\n        deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF);\n    }\n\n    void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override\n    {\n        (void)depthEnabled; // TODO: not implemented yet - not required by this sample\n\n        // Emulating points as billboarded quads, so each point will use 6 vertexes.\n        // D3D11 doesn't support \"point sprites\" like OpenGL (gl_PointSize).\n        const int maxVerts = DEBUG_DRAW_VERTEX_BUFFER_SIZE / 6;\n\n        // OpenGL point size scaling produces gigantic points with the billboarding fallback.\n        // This is some arbitrary down-scaling factor to more or less match the OpenGL samples.\n        const float D3DPointSpriteScalingFactor = 0.01f;\n\n        assert(points != nullptr);\n        assert(count > 0 && count <= maxVerts);\n\n       // Map the vertex buffer:\n        D3D11_MAPPED_SUBRESOURCE mapInfo;\n        if (FAILED(deviceContext->Map(pointVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo)))\n        {\n            panicF(\"Failed to map vertex buffer!\");\n        }\n\n        const int numVerts = count * 6;\n        const int indexes[6] = {0, 1, 2, 2, 3, 0};\n\n        int v = 0;\n        auto * verts = static_cast<Vertex *>(mapInfo.pData);\n\n        // Expand each point into a quad:\n        for (int p = 0; p < count; ++p)\n        {\n            const float ptSize      = points[p].point.size * D3DPointSpriteScalingFactor;\n            const Vector3 halfWidth = (ptSize * 0.5f) * camRight; // X\n            const Vector3 halfHeigh = (ptSize * 0.5f) * camUp;    // Y\n            const Vector3 origin    = Vector3{ points[p].point.x, points[p].point.y, points[p].point.z };\n\n            Vector3 corners[4];\n            corners[0] = origin + halfWidth + halfHeigh;\n            corners[1] = origin - halfWidth + halfHeigh;\n            corners[2] = origin - halfWidth - halfHeigh;\n            corners[3] = origin + halfWidth - halfHeigh;\n\n            for (int i : indexes)\n            {\n                verts[v].pos.x = corners[i].getX();\n                verts[v].pos.y = corners[i].getY();\n                verts[v].pos.z = corners[i].getZ();\n                verts[v].pos.w = 1.0f;\n\n                verts[v].color.x = points[p].point.r;\n                verts[v].color.y = points[p].point.g;\n                verts[v].color.z = points[p].point.b;\n                verts[v].color.w = 1.0f;\n\n                ++v;\n            }\n        }\n        assert(v == numVerts);\n\n        // Unmap and draw:\n        deviceContext->Unmap(pointVertexBuffer.Get(), 0);\n\n        // Draw with the current buffer:\n        drawHelper(numVerts, pointShaders, pointVertexBuffer.Get(), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\n    }\n\n    void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override\n    {\n        (void)depthEnabled; // TODO: not implemented yet - not required by this sample\n\n        assert(lines != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        // Map the vertex buffer:\n        D3D11_MAPPED_SUBRESOURCE mapInfo;\n        if (FAILED(deviceContext->Map(lineVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo)))\n        {\n            panicF(\"Failed to map vertex buffer!\");\n        }\n\n        // Copy into mapped buffer:\n        auto * verts = static_cast<Vertex *>(mapInfo.pData);\n        for (int v = 0; v < count; ++v)\n        {\n            verts[v].pos.x = lines[v].line.x;\n            verts[v].pos.y = lines[v].line.y;\n            verts[v].pos.z = lines[v].line.z;\n            verts[v].pos.w = 1.0f;\n\n            verts[v].color.x = lines[v].line.r;\n            verts[v].color.y = lines[v].line.g;\n            verts[v].color.z = lines[v].line.b;\n            verts[v].color.w = 1.0f;\n        }\n\n        // Unmap and draw:\n        deviceContext->Unmap(lineVertexBuffer.Get(), 0);\n\n        // Draw with the current buffer:\n        drawHelper(count, lineShaders, lineVertexBuffer.Get(), D3D11_PRIMITIVE_TOPOLOGY_LINELIST);\n    }\n\nprivate:\n\n    //\n    // Local types:\n    //\n\n    struct ConstantBufferData\n    {\n        DirectX::XMMATRIX mvpMatrix        = DirectX::XMMatrixIdentity();\n        DirectX::XMFLOAT4 screenDimensions = {float(WindowWidth), float(WindowHeight), 0.0f, 0.0f};\n    };\n\n    struct Vertex\n    {\n        DirectX::XMFLOAT4A pos;   // 3D position\n        DirectX::XMFLOAT4A uv;    // Texture coordinates\n        DirectX::XMFLOAT4A color; // RGBA float\n    };\n\n    struct TextureImpl : public dd::OpaqueTextureType\n    {\n        ID3D11Texture2D          * d3dTexPtr  = nullptr;\n        ID3D11ShaderResourceView * d3dTexSRV  = nullptr;\n        ID3D11SamplerState       * d3dSampler = nullptr;\n    };\n\n    //\n    // Members:\n    //\n\n    ComPtr<ID3D11Device>          d3dDevice;\n    ComPtr<ID3D11DeviceContext>   deviceContext;\n    ComPtr<ID3D11RasterizerState> rasterizerState;\n    ComPtr<ID3D11BlendState>      blendStateText;\n\n    ComPtr<ID3D11Buffer>          constantBuffer;\n    ConstantBufferData            constantBufferData;\n\n    ComPtr<ID3D11Buffer>          lineVertexBuffer;\n    ShaderSetD3D11                lineShaders;\n\n    ComPtr<ID3D11Buffer>          pointVertexBuffer;\n    ShaderSetD3D11                pointShaders;\n\n    ComPtr<ID3D11Buffer>          glyphVertexBuffer;\n    ShaderSetD3D11                glyphShaders;\n\n    // Camera vectors for the emulated point sprites\n    Vector3                       camUp     = Vector3{0.0f};\n    Vector3                       camRight  = Vector3{0.0f};\n    Vector3                       camOrigin = Vector3{0.0f};\n\n    void initShaders()\n    {\n        // Same vertex format used by all buffers to simplify things.\n        const D3D11_INPUT_ELEMENT_DESC layout[] = {\n            { \"POSITION\", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },\n            { \"TEXCOORD\", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n            { \"COLOR\",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n        };\n        const ShaderSetD3D11::InputLayoutDesc inputDesc{ layout, int(ARRAYSIZE(layout)) };\n\n        // 3D lines shader:\n        lineShaders.loadFromFxFile(d3dDevice.Get(), L\"ddShader.fx\",\n                                   \"VS_LinePoint\", \"PS_LinePoint\", inputDesc);\n\n        // 3D points shader:\n        pointShaders.loadFromFxFile(d3dDevice.Get(), L\"ddShader.fx\",\n                                    \"VS_LinePoint\", \"PS_LinePoint\", inputDesc);\n\n        // 2D glyphs shader:\n        glyphShaders.loadFromFxFile(d3dDevice.Get(), L\"ddShader.fx\",\n                                    \"VS_TextGlyph\", \"PS_TextGlyph\", inputDesc);\n\n        // Rasterizer state for the screen text:\n        D3D11_RASTERIZER_DESC rsDesc = {};\n        rsDesc.FillMode              = D3D11_FILL_SOLID;\n        rsDesc.CullMode              = D3D11_CULL_NONE;\n        rsDesc.FrontCounterClockwise = true;\n        rsDesc.DepthBias             = 0;\n        rsDesc.DepthBiasClamp        = 0.0f;\n        rsDesc.SlopeScaledDepthBias  = 0.0f;\n        rsDesc.DepthClipEnable       = false;\n        rsDesc.ScissorEnable         = false;\n        rsDesc.MultisampleEnable     = false;\n        rsDesc.AntialiasedLineEnable = false;\n        if (FAILED(d3dDevice->CreateRasterizerState(&rsDesc, rasterizerState.GetAddressOf())))\n        {\n            errorF(\"CreateRasterizerState failed!\");\n        }\n\n        // Blend state for the screen text:\n        D3D11_BLEND_DESC bsDesc                      = {};\n        bsDesc.RenderTarget[0].BlendEnable           = true;\n        bsDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n        bsDesc.RenderTarget[0].SrcBlend              = D3D11_BLEND_SRC_ALPHA;\n        bsDesc.RenderTarget[0].DestBlend             = D3D11_BLEND_INV_SRC_ALPHA;\n        bsDesc.RenderTarget[0].BlendOp               = D3D11_BLEND_OP_ADD;\n        bsDesc.RenderTarget[0].SrcBlendAlpha         = D3D11_BLEND_ONE;\n        bsDesc.RenderTarget[0].DestBlendAlpha        = D3D11_BLEND_ZERO;\n        bsDesc.RenderTarget[0].BlendOpAlpha          = D3D11_BLEND_OP_ADD;\n        if (FAILED(d3dDevice->CreateBlendState(&bsDesc, blendStateText.GetAddressOf())))\n        {\n            errorF(\"CreateBlendState failed!\");\n        }\n    }\n\n    void initBuffers()\n    {\n        D3D11_BUFFER_DESC bd;\n\n        // Create the shared constant buffer:\n        bd                = {};\n        bd.Usage          = D3D11_USAGE_DEFAULT;\n        bd.ByteWidth      = sizeof(ConstantBufferData);\n        bd.BindFlags      = D3D11_BIND_CONSTANT_BUFFER;\n        bd.CPUAccessFlags = 0;\n        if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, constantBuffer.GetAddressOf())))\n        {\n            panicF(\"Failed to create shader constant buffer!\");\n        }\n\n        // Create the vertex buffers for lines/points/glyphs:\n        bd                = {};\n        bd.Usage          = D3D11_USAGE_DYNAMIC;\n        bd.ByteWidth      = sizeof(Vertex) * DEBUG_DRAW_VERTEX_BUFFER_SIZE;\n        bd.BindFlags      = D3D11_BIND_VERTEX_BUFFER;\n        bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n\n        if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, lineVertexBuffer.GetAddressOf())))\n        {\n            panicF(\"Failed to create lines vertex buffer!\");\n        }\n        if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, pointVertexBuffer.GetAddressOf())))\n        {\n            panicF(\"Failed to create points vertex buffer!\");\n        }\n        if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, glyphVertexBuffer.GetAddressOf())))\n        {\n            panicF(\"Failed to create glyphs vertex buffer!\");\n        }\n    }\n\n    void drawHelper(const int numVerts, const ShaderSetD3D11 & ss,\n                    ID3D11Buffer * vb, const D3D11_PRIMITIVE_TOPOLOGY topology)\n    {\n        const UINT offset = 0;\n        const UINT stride = sizeof(Vertex);\n        deviceContext->IASetVertexBuffers(0, 1, &vb, &stride, &offset);\n        deviceContext->IASetPrimitiveTopology(topology);\n        deviceContext->IASetInputLayout(ss.vertexLayout.Get());\n        deviceContext->VSSetShader(ss.vs.Get(), nullptr, 0);\n        deviceContext->PSSetShader(ss.ps.Get(), nullptr, 0);\n        deviceContext->Draw(numVerts, 0);\n    }\n};\n\n// ========================================================\n// Sample drawing\n// ========================================================\n\nstatic void drawGrid(dd::ContextHandle ctx)\n{\n    if (!keys.showGrid)\n    {\n        return;\n    }\n\n    // Grid from -50 to +50 in both X & Z\n    dd::xzSquareGrid(ctx, -50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green);\n}\n\nstatic void drawLabel(dd::ContextHandle ctx, ddVec3_In pos, const char * name)\n{\n    if (!keys.showLabels)\n    {\n        return;\n    }\n\n    // Only draw labels inside the camera frustum.\n    if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2]))\n    {\n        const ddVec3 textColor = { 0.8f, 0.8f, 1.0f };\n        dd::projectedText(ctx, name, pos, textColor, toFloatPtr(camera.vpMatrix),\n                          0, 0, WindowWidth, WindowHeight, 0.5f);\n    }\n}\n\nstatic void drawMiscObjects(dd::ContextHandle ctx)\n{\n    // Start a row of objects at this position:\n    ddVec3 origin = { -15.0f, 0.0f, 0.0f };\n\n    // Box with a point at it's center:\n    drawLabel(ctx, origin, \"box\");\n    dd::box(ctx, origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n    origin[0] += 3.0f;\n\n    // Sphere with a point at its center\n    drawLabel(ctx, origin, \"sphere\");\n    dd::sphere(ctx, origin, dd::colors::Red, 1.0f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Two cones, one open and one closed:\n    const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f };\n    origin[1] -= 1.0f;\n\n    drawLabel(ctx, origin, \"cone (open)\");\n    dd::cone(ctx, origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    drawLabel(ctx, origin, \"cone (closed)\");\n    dd::cone(ctx, origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Axis-aligned bounding box:\n    const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f };\n    const ddVec3 bbMaxs = {  1.0f,  2.2f,  1.0f };\n    const ddVec3 bbCenter = {\n        (bbMins[0] + bbMaxs[0]) * 0.5f,\n        (bbMins[1] + bbMaxs[1]) * 0.5f,\n        (bbMins[2] + bbMaxs[2]) * 0.5f\n    };\n    drawLabel(ctx, origin, \"AABB\");\n    dd::aabb(ctx, bbMins, bbMaxs, dd::colors::Orange);\n    dd::point(ctx, bbCenter, dd::colors::White, 15.0f);\n\n    // Move along the Z for another row:\n    origin[0] = -15.0f;\n    origin[2] += 5.0f;\n\n    // A big arrow pointing up:\n    const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] };\n    const ddVec3 arrowTo   = { origin[0], origin[1] + 5.0f, origin[2] };\n    drawLabel(ctx, arrowFrom, \"arrow\");\n    dd::arrow(ctx, arrowFrom, arrowTo, dd::colors::Magenta, 1.0f);\n    dd::point(ctx, arrowFrom, dd::colors::White, 15.0f);\n    dd::point(ctx, arrowTo, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Plane with normal vector:\n    const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f };\n    drawLabel(ctx, origin, \"plane\");\n    dd::plane(ctx, origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Circle on the Y plane:\n    drawLabel(ctx, origin, \"circle\");\n    dd::circle(ctx, origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n    origin[0] += 3.2f;\n\n    // Tangent basis vectors:\n    const ddVec3 normal    = { 0.0f, 1.0f, 0.0f };\n    const ddVec3 tangent   = { 1.0f, 0.0f, 0.0f };\n    const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f };\n    origin[1] += 0.1f;\n    drawLabel(ctx, origin, \"tangent basis\");\n    dd::tangentBasis(ctx, origin, normal, tangent, bitangent, 2.5f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n\n    // And a set of intersecting axes:\n    origin[0] += 4.0f;\n    origin[1] += 1.0f;\n    drawLabel(ctx, origin, \"cross\");\n    dd::cross(ctx, origin, 2.0f);\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n}\n\nstatic void drawFrustum(dd::ContextHandle ctx)\n{\n    const ddVec3 color  = {  0.8f, 0.3f, 1.0f  };\n    const ddVec3 origin = { -8.0f, 0.5f, 14.0f };\n    drawLabel(ctx, origin, \"frustum + axes\");\n\n    // The frustum will depict a fake camera:\n    const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f);\n    const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis());\n    const Matrix4 clip = inverse(proj * view);\n    dd::frustum(ctx, toFloatPtr(clip), color);\n\n    // A white dot at the eye position:\n    dd::point(ctx, origin, dd::colors::White, 15.0f);\n\n    // A set of arrows at the camera's origin/eye:\n    const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f));\n    dd::axisTriad(ctx, toFloatPtr(transform), 0.3f, 2.0f);\n}\n\nstatic void drawText(dd::ContextHandle ctx)\n{\n    // HUD text:\n    const ddVec3 textColor = { 1.0f,  1.0f,  1.0f };\n    const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f };\n    dd::screenText(ctx, \"Welcome to the D3D11 Debug Draw demo.\\n\\n\"\n                        \"[SPACE]  to toggle labels on/off\\n\"\n                        \"[RETURN] to toggle grid on/off\",\n                        textPos2D, textColor, 0.55f);\n}\n\nstatic void inputUpdate(const Window & win)\n{\n    if (GetForegroundWindow() != win.hWindow)\n    {\n        return; // Don't update if window out of focus.\n    }\n\n    auto testKeyPressed = [](int key) -> bool\n    {\n        return (GetKeyState(key) & 0x80) > 0;\n    };\n\n    // Keyboard movement keys:\n    keys.wDown = testKeyPressed('W') || testKeyPressed(VK_UP);\n    keys.sDown = testKeyPressed('S') || testKeyPressed(VK_DOWN);\n    keys.aDown = testKeyPressed('A') || testKeyPressed(VK_LEFT);\n    keys.dDown = testKeyPressed('D') || testKeyPressed(VK_RIGHT);\n\n    // Mouse buttons:\n    mouse.leftButtonDown  = testKeyPressed(VK_LBUTTON);\n    mouse.rightButtonDown = testKeyPressed(VK_RBUTTON);\n}\n\n// ========================================================\n// WinMain\n// ========================================================\n\nint APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)\n{\n    printDDBuildConfig();\n\n    RenderWindowD3D11 renderWindow(hInstance, nCmdShow);\n    RenderInterfaceD3D11 renderInterface(renderWindow.d3dDevice, renderWindow.deviceContext);\n\n    dd::ContextHandle ddContext = nullptr;\n    dd::initialize(&ddContext, &renderInterface);\n\n    renderWindow.renderCallback = [ddContext, &renderWindow, &renderInterface]()\n    {\n        const double t0s = getTimeSeconds();\n\n        inputUpdate(renderWindow);\n        camera.checkKeyboardMovement();\n        camera.checkMouseRotation();\n        camera.updateMatrices();\n\n        const Matrix4 mvpMatrix = transpose(camera.vpMatrix);\n        renderInterface.setMvpMatrixPtr(toFloatPtr(mvpMatrix));\n        renderInterface.setCameraFrame(camera.up, camera.right, camera.eye);\n\n        // Call some DD functions to add stuff to the debug draw queues:\n        drawGrid(ddContext);\n        drawMiscObjects(ddContext);\n        drawFrustum(ddContext);\n        drawText(ddContext);\n\n        // Flush the draw queues:\n        dd::flush(ddContext);\n\n        const double t1s = getTimeSeconds();\n\n        deltaTime.seconds      = static_cast<float>(t1s - t0s);\n        deltaTime.milliseconds = static_cast<std::int64_t>(deltaTime.seconds * 1000.0);\n    };\n\n    renderWindow.runMessageLoop();\n    dd::shutdown(ddContext);\n    return 0;\n}\n\n// ========================================================\n"
  },
  {
    "path": "samples/sample_gl_core.cpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   sample_gl_core.cpp\n// Author: Guilherme R. Lampert\n// Brief:  Debug Draw usage sample with Core Profile OpenGL (version 3+)\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#define DEBUG_DRAW_IMPLEMENTATION\n#include \"debug_draw.hpp\"     // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here!\n#include <GL/gl3w.h>          // An OpenGL extension wrangler (https://github.com/skaslev/gl3w).\n#include \"samples_common.hpp\" // Common code shared by the samples (camera, input, etc).\n\nusing namespace ddSamplesCommon;\n\n// ========================================================\n// Debug Draw RenderInterface for Core OpenGL:\n// ========================================================\n\nclass DDRenderInterfaceCoreGL final\n    : public dd::RenderInterface\n{\npublic:\n\n    //\n    // dd::RenderInterface overrides:\n    //\n\n    void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override\n    {\n        assert(points != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        glBindVertexArray(linePointVAO);\n        glUseProgram(linePointProgram);\n\n        glUniformMatrix4fv(linePointProgram_MvpMatrixLocation,\n                           1, GL_FALSE, toFloatPtr(mvpMatrix));\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick...\n        glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), points);\n\n        // Issue the draw call:\n        glDrawArrays(GL_POINTS, 0, count);\n\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override\n    {\n        assert(lines != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        glBindVertexArray(linePointVAO);\n        glUseProgram(linePointProgram);\n\n        glUniformMatrix4fv(linePointProgram_MvpMatrixLocation,\n                           1, GL_FALSE, toFloatPtr(mvpMatrix));\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick...\n        glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), lines);\n\n        // Issue the draw call:\n        glDrawArrays(GL_LINES, 0, count);\n\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(glyphs != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        glBindVertexArray(textVAO);\n        glUseProgram(textProgram);\n\n        // These doesn't have to be reset every draw call, I'm just being lazy ;)\n        glUniform1i(textProgram_GlyphTextureLocation, 0);\n        glUniform2f(textProgram_ScreenDimensions,\n                    static_cast<GLfloat>(WindowWidth),\n                    static_cast<GLfloat>(WindowHeight));\n\n        if (glyphTex != nullptr)\n        {\n            glActiveTexture(GL_TEXTURE0);\n            glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex));\n        }\n\n        glEnable(GL_BLEND);\n        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\n        glDisable(GL_DEPTH_TEST);\n\n        glBindBuffer(GL_ARRAY_BUFFER, textVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), glyphs);\n\n        glDrawArrays(GL_TRIANGLES, 0, count); // Issue the draw call\n\n        glDisable(GL_BLEND);\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        glBindTexture(GL_TEXTURE_2D,  0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override\n    {\n        assert(width > 0 && height > 0);\n        assert(pixels != nullptr);\n\n        GLuint textureId = 0;\n        glGenTextures(1, &textureId);\n        glBindTexture(GL_TEXTURE_2D, textureId);\n\n        glPixelStorei(GL_PACK_ALIGNMENT,   1);\n        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\n        glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);\n\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\n        glBindTexture(GL_TEXTURE_2D, 0);\n        checkGLError(__FILE__, __LINE__);\n\n        return GLToHandle(textureId);\n    }\n\n    void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override\n    {\n        if (glyphTex == nullptr)\n        {\n            return;\n        }\n\n        const GLuint textureId = handleToGL(glyphTex);\n        glBindTexture(GL_TEXTURE_2D, 0);\n        glDeleteTextures(1, &textureId);\n    }\n\n    // These two can also be implemented to perform GL render\n    // state setup/cleanup, but we don't use them in this sample.\n    //void beginDraw() override { }\n    //void endDraw()   override { }\n\n    //\n    // Local methods:\n    //\n\n    DDRenderInterfaceCoreGL()\n        : mvpMatrix(Matrix4::identity())\n        , linePointProgram(0)\n        , linePointProgram_MvpMatrixLocation(-1)\n        , textProgram(0)\n        , textProgram_GlyphTextureLocation(-1)\n        , textProgram_ScreenDimensions(-1)\n        , linePointVAO(0)\n        , linePointVBO(0)\n        , textVAO(0)\n        , textVBO(0)\n    {\n        std::printf(\"\\n\");\n        std::printf(\"GL_VENDOR    : %s\\n\",   glGetString(GL_VENDOR));\n        std::printf(\"GL_RENDERER  : %s\\n\",   glGetString(GL_RENDERER));\n        std::printf(\"GL_VERSION   : %s\\n\",   glGetString(GL_VERSION));\n        std::printf(\"GLSL_VERSION : %s\\n\\n\", glGetString(GL_SHADING_LANGUAGE_VERSION));\n        std::printf(\"DDRenderInterfaceCoreGL initializing ...\\n\");\n\n        // Default OpenGL states:\n        glEnable(GL_CULL_FACE);\n        glEnable(GL_DEPTH_TEST);\n        glDisable(GL_BLEND);\n\n        // This has to be enabled since the point drawing shader will use gl_PointSize.\n        glEnable(GL_PROGRAM_POINT_SIZE);\n\n        setupShaderPrograms();\n        setupVertexBuffers();\n\n        std::printf(\"DDRenderInterfaceCoreGL ready!\\n\\n\");\n    }\n\n    ~DDRenderInterfaceCoreGL()\n    {\n        glDeleteProgram(linePointProgram);\n        glDeleteProgram(textProgram);\n\n        glDeleteVertexArrays(1, &linePointVAO);\n        glDeleteBuffers(1, &linePointVBO);\n\n        glDeleteVertexArrays(1, &textVAO);\n        glDeleteBuffers(1, &textVBO);\n    }\n\n    void setupShaderPrograms()\n    {\n        std::printf(\"> DDRenderInterfaceCoreGL::setupShaderPrograms()\\n\");\n\n        //\n        // Line/point drawing shader:\n        //\n        {\n            GLuint linePointVS = glCreateShader(GL_VERTEX_SHADER);\n            glShaderSource(linePointVS, 1, &linePointVertShaderSrc, nullptr);\n            compileShader(linePointVS);\n\n            GLint linePointFS = glCreateShader(GL_FRAGMENT_SHADER);\n            glShaderSource(linePointFS, 1, &linePointFragShaderSrc, nullptr);\n            compileShader(linePointFS);\n\n            linePointProgram = glCreateProgram();\n            glAttachShader(linePointProgram, linePointVS);\n            glAttachShader(linePointProgram, linePointFS);\n\n            glBindAttribLocation(linePointProgram, 0, \"in_Position\");\n            glBindAttribLocation(linePointProgram, 1, \"in_ColorPointSize\");\n            linkProgram(linePointProgram);\n\n            linePointProgram_MvpMatrixLocation = glGetUniformLocation(linePointProgram, \"u_MvpMatrix\");\n            if (linePointProgram_MvpMatrixLocation < 0)\n            {\n                errorF(\"Unable to get u_MvpMatrix uniform location!\");\n            }\n            checkGLError(__FILE__, __LINE__);\n        }\n\n        //\n        // Text rendering shader:\n        //\n        {\n            GLuint textVS = glCreateShader(GL_VERTEX_SHADER);\n            glShaderSource(textVS, 1, &textVertShaderSrc, nullptr);\n            compileShader(textVS);\n\n            GLint textFS = glCreateShader(GL_FRAGMENT_SHADER);\n            glShaderSource(textFS, 1, &textFragShaderSrc, nullptr);\n            compileShader(textFS);\n\n            textProgram = glCreateProgram();\n            glAttachShader(textProgram, textVS);\n            glAttachShader(textProgram, textFS);\n\n            glBindAttribLocation(textProgram, 0, \"in_Position\");\n            glBindAttribLocation(textProgram, 1, \"in_TexCoords\");\n            glBindAttribLocation(textProgram, 2, \"in_Color\");\n            linkProgram(textProgram);\n\n            textProgram_GlyphTextureLocation = glGetUniformLocation(textProgram, \"u_glyphTexture\");\n            if (textProgram_GlyphTextureLocation < 0)\n            {\n                errorF(\"Unable to get u_glyphTexture uniform location!\");\n            }\n\n            textProgram_ScreenDimensions = glGetUniformLocation(textProgram, \"u_screenDimensions\");\n            if (textProgram_ScreenDimensions < 0)\n            {\n                errorF(\"Unable to get u_screenDimensions uniform location!\");\n            }\n\n            checkGLError(__FILE__, __LINE__);\n        }\n    }\n\n    void setupVertexBuffers()\n    {\n        std::printf(\"> DDRenderInterfaceCoreGL::setupVertexBuffers()\\n\");\n\n        //\n        // Lines/points vertex buffer:\n        //\n        {\n            glGenVertexArrays(1, &linePointVAO);\n            glGenBuffers(1, &linePointVBO);\n            checkGLError(__FILE__, __LINE__);\n\n            glBindVertexArray(linePointVAO);\n            glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n\n            // RenderInterface will never be called with a batch larger than\n            // DEBUG_DRAW_VERTEX_BUFFER_SIZE vertexes, so we can allocate the same amount here.\n            glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW);\n            checkGLError(__FILE__, __LINE__);\n\n            // Set the vertex format expected by 3D points and lines:\n            std::size_t offset = 0;\n\n            glEnableVertexAttribArray(0); // in_Position (vec3)\n            glVertexAttribPointer(\n                /* index     = */ 0,\n                /* size      = */ 3,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 3;\n\n            glEnableVertexAttribArray(1); // in_ColorPointSize (vec4)\n            glVertexAttribPointer(\n                /* index     = */ 1,\n                /* size      = */ 4,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n\n            checkGLError(__FILE__, __LINE__);\n\n            // VAOs can be a pain in the neck if left enabled...\n            glBindVertexArray(0);\n            glBindBuffer(GL_ARRAY_BUFFER, 0);\n        }\n\n        //\n        // Text rendering vertex buffer:\n        //\n        {\n            glGenVertexArrays(1, &textVAO);\n            glGenBuffers(1, &textVBO);\n            checkGLError(__FILE__, __LINE__);\n\n            glBindVertexArray(textVAO);\n            glBindBuffer(GL_ARRAY_BUFFER, textVBO);\n\n            // NOTE: A more optimized implementation might consider combining\n            // both the lines/points and text buffers to save some memory!\n            glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW);\n            checkGLError(__FILE__, __LINE__);\n\n            // Set the vertex format expected by the 2D text:\n            std::size_t offset = 0;\n\n            glEnableVertexAttribArray(0); // in_Position (vec2)\n            glVertexAttribPointer(\n                /* index     = */ 0,\n                /* size      = */ 2,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 2;\n\n            glEnableVertexAttribArray(1); // in_TexCoords (vec2)\n            glVertexAttribPointer(\n                /* index     = */ 1,\n                /* size      = */ 2,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 2;\n\n            glEnableVertexAttribArray(2); // in_Color (vec4)\n            glVertexAttribPointer(\n                /* index     = */ 2,\n                /* size      = */ 4,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n\n            checkGLError(__FILE__, __LINE__);\n\n            // Ditto.\n            glBindVertexArray(0);\n            glBindBuffer(GL_ARRAY_BUFFER, 0);\n        }\n    }\n\n    static GLuint handleToGL(dd::GlyphTextureHandle handle)\n    {\n        const std::size_t temp = reinterpret_cast<std::size_t>(handle);\n        return static_cast<GLuint>(temp);\n    }\n\n    static dd::GlyphTextureHandle GLToHandle(const GLuint id)\n    {\n        const std::size_t temp = static_cast<std::size_t>(id);\n        return reinterpret_cast<dd::GlyphTextureHandle>(temp);\n    }\n\n    static void checkGLError(const char * file, const int line)\n    {\n        GLenum err;\n        while ((err = glGetError()) != GL_NO_ERROR)\n        {\n            errorF(\"%s(%d) : GL_CORE_ERROR=0x%X - %s\", file, line, err, errorToString(err));\n        }\n    }\n\n    static void compileShader(const GLuint shader)\n    {\n        glCompileShader(shader);\n        checkGLError(__FILE__, __LINE__);\n\n        GLint status;\n        glGetShaderiv(shader, GL_COMPILE_STATUS, &status);\n        checkGLError(__FILE__, __LINE__);\n\n        if (status == GL_FALSE)\n        {\n            GLchar strInfoLog[1024] = {0};\n            glGetShaderInfoLog(shader, sizeof(strInfoLog) - 1, nullptr, strInfoLog);\n            errorF(\"\\n>>> Shader compiler errors:\\n%s\", strInfoLog);\n        }\n    }\n\n    static void linkProgram(const GLuint program)\n    {\n        glLinkProgram(program);\n        checkGLError(__FILE__, __LINE__);\n\n        GLint status;\n        glGetProgramiv(program, GL_LINK_STATUS, &status);\n        checkGLError(__FILE__, __LINE__);\n\n        if (status == GL_FALSE)\n        {\n            GLchar strInfoLog[1024] = {0};\n            glGetProgramInfoLog(program, sizeof(strInfoLog) - 1, nullptr, strInfoLog);\n            errorF(\"\\n>>> Program linker errors:\\n%s\", strInfoLog);\n        }\n    }\n\n    // The \"model-view-projection\" matrix for the scene.\n    // In this demo, it consists of the camera's view and projection matrices only.\n    Matrix4 mvpMatrix;\n\nprivate:\n\n    GLuint linePointProgram;\n    GLint  linePointProgram_MvpMatrixLocation;\n\n    GLuint textProgram;\n    GLint  textProgram_GlyphTextureLocation;\n    GLint  textProgram_ScreenDimensions;\n\n    GLuint linePointVAO;\n    GLuint linePointVBO;\n\n    GLuint textVAO;\n    GLuint textVBO;\n\n    static const char * linePointVertShaderSrc;\n    static const char * linePointFragShaderSrc;\n\n    static const char * textVertShaderSrc;\n    static const char * textFragShaderSrc;\n\n}; // class DDRenderInterfaceCoreGL\n\n// ========================================================\n// Minimal shaders we need for the debug primitives:\n// ========================================================\n\nconst char * DDRenderInterfaceCoreGL::linePointVertShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec3 in_Position;\\n\"\n    \"in vec4 in_ColorPointSize;\\n\"\n    \"\\n\"\n    \"out vec4 v_Color;\\n\"\n    \"uniform mat4 u_MvpMatrix;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    gl_Position  = u_MvpMatrix * vec4(in_Position, 1.0);\\n\"\n    \"    gl_PointSize = in_ColorPointSize.w;\\n\"\n    \"    v_Color      = vec4(in_ColorPointSize.xyz, 1.0);\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::linePointFragShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in  vec4 v_Color;\\n\"\n    \"out vec4 out_FragColor;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    out_FragColor = v_Color;\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::textVertShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec2 in_Position;\\n\"\n    \"in vec2 in_TexCoords;\\n\"\n    \"in vec3 in_Color;\\n\"\n    \"\\n\"\n    \"uniform vec2 u_screenDimensions;\\n\"\n    \"\\n\"\n    \"out vec2 v_TexCoords;\\n\"\n    \"out vec4 v_Color;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    // Map to normalized clip coordinates:\\n\"\n    \"    float x = ((2.0 * (in_Position.x - 0.5)) / u_screenDimensions.x) - 1.0;\\n\"\n    \"    float y = 1.0 - ((2.0 * (in_Position.y - 0.5)) / u_screenDimensions.y);\\n\"\n    \"\\n\"\n    \"    gl_Position = vec4(x, y, 0.0, 1.0);\\n\"\n    \"    v_TexCoords = in_TexCoords;\\n\"\n    \"    v_Color     = vec4(in_Color, 1.0);\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::textFragShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec2 v_TexCoords;\\n\"\n    \"in vec4 v_Color;\\n\"\n    \"\\n\"\n    \"uniform sampler2D u_glyphTexture;\\n\"\n    \"out vec4 out_FragColor;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    out_FragColor = v_Color;\\n\"\n    \"    out_FragColor.a = texture(u_glyphTexture, v_TexCoords).r;\\n\"\n    \"}\\n\";\n\n// ========================================================\n// GLFW / window management / sample drawing:\n// ========================================================\n\nstatic void drawGrid()\n{\n    if (!keys.showGrid)\n    {\n        return;\n    }\n    dd::xzSquareGrid(-50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z\n}\n\nstatic void drawLabel(ddVec3_In pos, const char * name)\n{\n    if (!keys.showLabels)\n    {\n        return;\n    }\n\n    // Only draw labels inside the camera frustum.\n    if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2]))\n    {\n        const ddVec3 textColor = { 0.8f, 0.8f, 1.0f };\n        dd::projectedText(name, pos, textColor, toFloatPtr(camera.vpMatrix),\n                          0, 0, WindowWidth, WindowHeight, 0.5f);\n    }\n}\n\nstatic void drawMiscObjects()\n{\n    // Start a row of objects at this position:\n    ddVec3 origin = { -15.0f, 0.0f, 0.0f };\n\n    // Box with a point at it's center:\n    drawLabel(origin, \"box\");\n    dd::box(origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 3.0f;\n\n    // Sphere with a point at its center\n    drawLabel(origin, \"sphere\");\n    dd::sphere(origin, dd::colors::Red, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Two cones, one open and one closed:\n    const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f };\n    origin[1] -= 1.0f;\n\n    drawLabel(origin, \"cone (open)\");\n    dd::cone(origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    drawLabel(origin, \"cone (closed)\");\n    dd::cone(origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Axis-aligned bounding box:\n    const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f };\n    const ddVec3 bbMaxs = {  1.0f,  2.2f,  1.0f };\n    const ddVec3 bbCenter = {\n        (bbMins[0] + bbMaxs[0]) * 0.5f,\n        (bbMins[1] + bbMaxs[1]) * 0.5f,\n        (bbMins[2] + bbMaxs[2]) * 0.5f\n    };\n    drawLabel(origin, \"AABB\");\n    dd::aabb(bbMins, bbMaxs, dd::colors::Orange);\n    dd::point(bbCenter, dd::colors::White, 15.0f);\n\n    // Move along the Z for another row:\n    origin[0] = -15.0f;\n    origin[2] += 5.0f;\n\n    // A big arrow pointing up:\n    const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] };\n    const ddVec3 arrowTo   = { origin[0], origin[1] + 5.0f, origin[2] };\n    drawLabel(arrowFrom, \"arrow\");\n    dd::arrow(arrowFrom, arrowTo, dd::colors::Magenta, 1.0f);\n    dd::point(arrowFrom, dd::colors::White, 15.0f);\n    dd::point(arrowTo, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Plane with normal vector:\n    const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f };\n    drawLabel(origin, \"plane\");\n    dd::plane(origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Circle on the Y plane:\n    drawLabel(origin, \"circle\");\n    dd::circle(origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 3.2f;\n\n    // Tangent basis vectors:\n    const ddVec3 normal    = { 0.0f, 1.0f, 0.0f };\n    const ddVec3 tangent   = { 1.0f, 0.0f, 0.0f };\n    const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f };\n    origin[1] += 0.1f;\n    drawLabel(origin, \"tangent basis\");\n    dd::tangentBasis(origin, normal, tangent, bitangent, 2.5f);\n    dd::point(origin, dd::colors::White, 15.0f);\n\n    // And a set of intersecting axes:\n    origin[0] += 4.0f;\n    origin[1] += 1.0f;\n    drawLabel(origin, \"cross\");\n    dd::cross(origin, 2.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n}\n\nstatic void drawFrustum()\n{\n    const ddVec3 color  = {  0.8f, 0.3f, 1.0f  };\n    const ddVec3 origin = { -8.0f, 0.5f, 14.0f };\n    drawLabel(origin, \"frustum + axes\");\n\n    // The frustum will depict a fake camera:\n    const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f);\n    const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis());\n    const Matrix4 clip = inverse(proj * view);\n    dd::frustum(toFloatPtr(clip), color);\n\n    // A white dot at the eye position:\n    dd::point(origin, dd::colors::White, 15.0f);\n\n    // A set of arrows at the camera's origin/eye:\n    const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f));\n    dd::axisTriad(toFloatPtr(transform), 0.3f, 2.0f);\n}\n\nstatic void drawText()\n{\n    // HUD text:\n    const ddVec3 textColor = { 1.0f,  1.0f,  1.0f };\n    const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f };\n    dd::screenText(\"Welcome to the Core OpenGL Debug Draw demo.\\n\\n\"\n                   \"[SPACE]  to toggle labels on/off\\n\"\n                   \"[RETURN] to toggle grid on/off\",\n                   textPos2D, textColor, 0.55f);\n}\n\nstatic void sampleAppDraw(DDRenderInterfaceCoreGL & ddRenderIfaceGL)\n{\n    // Camera input update (the 'camera' object is declared in samples_common.hpp):\n    camera.checkKeyboardMovement();\n    camera.checkMouseRotation();\n    camera.updateMatrices();\n\n    // Send the camera matrix to the shaders:\n    ddRenderIfaceGL.mvpMatrix = camera.vpMatrix;\n\n    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);\n    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n\n    // Call some DD functions to add stuff to the debug draw queues:\n    drawGrid();\n    drawMiscObjects();\n    drawFrustum();\n    drawText();\n\n    // Drawing only really happens now (here's where RenderInterface gets called).\n    dd::flush(getTimeMilliseconds());\n}\n\nstatic void sampleAppStart()\n{\n    printDDBuildConfig();\n\n    if (!glfwInit())\n    {\n        errorF(\"Failed to initialize GLFW!\");\n        return;\n    }\n\n    // Things we need for the window / GL render context:\n    glfwWindowHint(GLFW_RESIZABLE, false);\n    glfwWindowHint(GLFW_DEPTH_BITS, 32);\n    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);\n    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);\n\n    GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight,\n                                           \"Debug Draw Sample - Core OpenGL\",\n                                           nullptr, nullptr);\n    if (!window)\n    {\n        errorF(\"Failed to create GLFW window!\");\n        return;\n    }\n\n    glfwMakeContextCurrent(window);\n\n    if (!gl3wInit())\n    {\n        errorF(\"Failed to initialize GL3W extension library!\");\n        return;\n    }\n\n    if (!gl3wIsSupported(3, 2))\n    {\n        errorF(\"This sample application requires at least OpenGL version 3.2 to run!\");\n        return;\n    }\n\n    // From samples_common.hpp\n    initInput(window);\n\n    // Set up the Debug Draw:\n    DDRenderInterfaceCoreGL ddRenderIfaceGL;\n    dd::initialize(&ddRenderIfaceGL);\n\n    // Loop until the user closes the window:\n    while (!glfwWindowShouldClose(window))\n    {\n        const double t0s = glfwGetTime();\n\n        sampleAppDraw(ddRenderIfaceGL);\n        glfwSwapBuffers(window);\n        glfwPollEvents();\n\n        const double t1s = glfwGetTime();\n\n        deltaTime.seconds      = static_cast<float>(t1s - t0s);\n        deltaTime.milliseconds = static_cast<std::int64_t>(deltaTime.seconds * 1000.0);\n    }\n\n    dd::shutdown();\n}\n\n// ========================================================\n// main():\n// ========================================================\n\nint main()\n{\n    sampleAppStart();\n    gl3wShutdown();\n    glfwTerminate();\n}\n\n"
  },
  {
    "path": "samples/sample_gl_core_multithreaded_explicit.cpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   sample_gl_core_multithreaded_explicit.cpp\n// Author: Guilherme R. Lampert\n// Brief:  Debug Draw usage sample with Core Profile OpenGL and separate rendering thread.\n//         Demonstrates the use of DEBUG_DRAW_EXPLICIT_CONTEXT with threads/async calls\n//         and multiple contexts.\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#define DEBUG_DRAW_IMPLEMENTATION\n#define DEBUG_DRAW_EXPLICIT_CONTEXT\n\n#include \"debug_draw.hpp\"     // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here!\n#include <GL/gl3w.h>          // An OpenGL extension wrangler (https://github.com/skaslev/gl3w).\n#include \"samples_common.hpp\" // Common code shared by the samples (camera, input, etc).\n\nusing namespace ddSamplesCommon;\n\n// ========================================================\n// Debug Draw RenderInterface for Core OpenGL:\n// ========================================================\n\nclass DDRenderInterfaceCoreGL final\n    : public dd::RenderInterface\n{\npublic:\n\n    //\n    // dd::RenderInterface overrides:\n    //\n\n    void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override\n    {\n        assert(points != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n        assert(isMainThread()); // GL calls from the main thread only!\n\n        glBindVertexArray(linePointVAO);\n        glUseProgram(linePointProgram);\n\n        glUniformMatrix4fv(linePointProgram_MvpMatrixLocation,\n                           1, GL_FALSE, toFloatPtr(mvpMatrix));\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick...\n        glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), points);\n\n        // Issue the draw call:\n        glDrawArrays(GL_POINTS, 0, count);\n\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override\n    {\n        assert(lines != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n        assert(isMainThread()); // GL calls from the main thread only!\n\n        glBindVertexArray(linePointVAO);\n        glUseProgram(linePointProgram);\n\n        glUniformMatrix4fv(linePointProgram_MvpMatrixLocation,\n                           1, GL_FALSE, toFloatPtr(mvpMatrix));\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick...\n        glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), lines);\n\n        // Issue the draw call:\n        glDrawArrays(GL_LINES, 0, count);\n\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(glyphs != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n        assert(isMainThread()); // GL calls from the main thread only!\n\n        glBindVertexArray(textVAO);\n        glUseProgram(textProgram);\n\n        // These doesn't have to be reset every draw call, I'm just being lazy ;)\n        glUniform1i(textProgram_GlyphTextureLocation, 0);\n        glUniform2f(textProgram_ScreenDimensions,\n                    static_cast<GLfloat>(WindowWidth),\n                    static_cast<GLfloat>(WindowHeight));\n\n        if (glyphTex != nullptr)\n        {\n            glActiveTexture(GL_TEXTURE0);\n            glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex));\n        }\n\n        glEnable(GL_BLEND);\n        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\n        glDisable(GL_DEPTH_TEST);\n\n        glBindBuffer(GL_ARRAY_BUFFER, textVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), glyphs);\n\n        glDrawArrays(GL_TRIANGLES, 0, count); // Issue the draw call\n\n        glDisable(GL_BLEND);\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        glBindTexture(GL_TEXTURE_2D,  0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override\n    {\n        assert(width > 0 && height > 0);\n        assert(pixels != nullptr);\n        assert(isMainThread()); // GL calls from the main thread only!\n\n        GLuint textureId = 0;\n        glGenTextures(1, &textureId);\n        glBindTexture(GL_TEXTURE_2D, textureId);\n\n        glPixelStorei(GL_PACK_ALIGNMENT,   1);\n        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\n        glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);\n\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\n        glBindTexture(GL_TEXTURE_2D, 0);\n        checkGLError(__FILE__, __LINE__);\n\n        return GLToHandle(textureId);\n    }\n\n    void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(isMainThread()); // GL calls from the main thread only!\n        if (glyphTex == nullptr)\n        {\n            return;\n        }\n\n        const GLuint textureId = handleToGL(glyphTex);\n        glBindTexture(GL_TEXTURE_2D, 0);\n        glDeleteTextures(1, &textureId);\n    }\n\n    void beginDraw() override { assert(isMainThread()); }\n    void endDraw()   override { assert(isMainThread()); }\n\n    //\n    // Local methods:\n    //\n\n    DDRenderInterfaceCoreGL()\n        : mvpMatrix(Matrix4::identity())\n        , linePointProgram(0)\n        , linePointProgram_MvpMatrixLocation(-1)\n        , textProgram(0)\n        , textProgram_GlyphTextureLocation(-1)\n        , textProgram_ScreenDimensions(-1)\n        , linePointVAO(0)\n        , linePointVBO(0)\n        , textVAO(0)\n        , textVBO(0)\n    {\n        std::printf(\"\\n\");\n        std::printf(\"GL_VENDOR    : %s\\n\",   glGetString(GL_VENDOR));\n        std::printf(\"GL_RENDERER  : %s\\n\",   glGetString(GL_RENDERER));\n        std::printf(\"GL_VERSION   : %s\\n\",   glGetString(GL_VERSION));\n        std::printf(\"GLSL_VERSION : %s\\n\\n\", glGetString(GL_SHADING_LANGUAGE_VERSION));\n        std::printf(\"DDRenderInterfaceCoreGL MT initializing ...\\n\");\n\n        // Default OpenGL states:\n        glEnable(GL_CULL_FACE);\n        glEnable(GL_DEPTH_TEST);\n        glDisable(GL_BLEND);\n\n        // This has to be enabled since the point drawing shader will use gl_PointSize.\n        glEnable(GL_PROGRAM_POINT_SIZE);\n\n        setupShaderPrograms();\n        setupVertexBuffers();\n\n        std::printf(\"DDRenderInterfaceCoreGL MT ready!\\n\\n\");\n    }\n\n    ~DDRenderInterfaceCoreGL()\n    {\n        glDeleteProgram(linePointProgram);\n        glDeleteProgram(textProgram);\n\n        glDeleteVertexArrays(1, &linePointVAO);\n        glDeleteBuffers(1, &linePointVBO);\n\n        glDeleteVertexArrays(1, &textVAO);\n        glDeleteBuffers(1, &textVBO);\n    }\n\n    void prepareDraw(const Matrix4 & mvp)\n    {\n        assert(isMainThread());\n\n        mvpMatrix = mvp;\n        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);\n        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n    }\n\n    void setupShaderPrograms()\n    {\n        std::printf(\"> DDRenderInterfaceCoreGL::setupShaderPrograms()\\n\");\n\n        //\n        // Line/point drawing shader:\n        //\n        {\n            GLuint linePointVS = glCreateShader(GL_VERTEX_SHADER);\n            glShaderSource(linePointVS, 1, &linePointVertShaderSrc, nullptr);\n            compileShader(linePointVS);\n\n            GLint linePointFS = glCreateShader(GL_FRAGMENT_SHADER);\n            glShaderSource(linePointFS, 1, &linePointFragShaderSrc, nullptr);\n            compileShader(linePointFS);\n\n            linePointProgram = glCreateProgram();\n            glAttachShader(linePointProgram, linePointVS);\n            glAttachShader(linePointProgram, linePointFS);\n\n            glBindAttribLocation(linePointProgram, 0, \"in_Position\");\n            glBindAttribLocation(linePointProgram, 1, \"in_ColorPointSize\");\n            linkProgram(linePointProgram);\n\n            linePointProgram_MvpMatrixLocation = glGetUniformLocation(linePointProgram, \"u_MvpMatrix\");\n            if (linePointProgram_MvpMatrixLocation < 0)\n            {\n                errorF(\"Unable to get u_MvpMatrix uniform location!\");\n            }\n            checkGLError(__FILE__, __LINE__);\n        }\n\n        //\n        // Text rendering shader:\n        //\n        {\n            GLuint textVS = glCreateShader(GL_VERTEX_SHADER);\n            glShaderSource(textVS, 1, &textVertShaderSrc, nullptr);\n            compileShader(textVS);\n\n            GLint textFS = glCreateShader(GL_FRAGMENT_SHADER);\n            glShaderSource(textFS, 1, &textFragShaderSrc, nullptr);\n            compileShader(textFS);\n\n            textProgram = glCreateProgram();\n            glAttachShader(textProgram, textVS);\n            glAttachShader(textProgram, textFS);\n\n            glBindAttribLocation(textProgram, 0, \"in_Position\");\n            glBindAttribLocation(textProgram, 1, \"in_TexCoords\");\n            glBindAttribLocation(textProgram, 2, \"in_Color\");\n            linkProgram(textProgram);\n\n            textProgram_GlyphTextureLocation = glGetUniformLocation(textProgram, \"u_glyphTexture\");\n            if (textProgram_GlyphTextureLocation < 0)\n            {\n                errorF(\"Unable to get u_glyphTexture uniform location!\");\n            }\n\n            textProgram_ScreenDimensions = glGetUniformLocation(textProgram, \"u_screenDimensions\");\n            if (textProgram_ScreenDimensions < 0)\n            {\n                errorF(\"Unable to get u_screenDimensions uniform location!\");\n            }\n\n            checkGLError(__FILE__, __LINE__);\n        }\n    }\n\n    void setupVertexBuffers()\n    {\n        std::printf(\"> DDRenderInterfaceCoreGL::setupVertexBuffers()\\n\");\n\n        //\n        // Lines/points vertex buffer:\n        //\n        {\n            glGenVertexArrays(1, &linePointVAO);\n            glGenBuffers(1, &linePointVBO);\n            checkGLError(__FILE__, __LINE__);\n\n            glBindVertexArray(linePointVAO);\n            glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n\n            // RenderInterface will never be called with a batch larger than\n            // DEBUG_DRAW_VERTEX_BUFFER_SIZE vertexes, so we can allocate the same amount here.\n            glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW);\n            checkGLError(__FILE__, __LINE__);\n\n            // Set the vertex format expected by 3D points and lines:\n            std::size_t offset = 0;\n\n            glEnableVertexAttribArray(0); // in_Position (vec3)\n            glVertexAttribPointer(\n                /* index     = */ 0,\n                /* size      = */ 3,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 3;\n\n            glEnableVertexAttribArray(1); // in_ColorPointSize (vec4)\n            glVertexAttribPointer(\n                /* index     = */ 1,\n                /* size      = */ 4,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n\n            checkGLError(__FILE__, __LINE__);\n\n            // VAOs can be a pain in the neck if left enabled...\n            glBindVertexArray(0);\n            glBindBuffer(GL_ARRAY_BUFFER, 0);\n        }\n\n        //\n        // Text rendering vertex buffer:\n        //\n        {\n            glGenVertexArrays(1, &textVAO);\n            glGenBuffers(1, &textVBO);\n            checkGLError(__FILE__, __LINE__);\n\n            glBindVertexArray(textVAO);\n            glBindBuffer(GL_ARRAY_BUFFER, textVBO);\n\n            // NOTE: A more optimized implementation might consider combining\n            // both the lines/points and text buffers to save some memory!\n            glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW);\n            checkGLError(__FILE__, __LINE__);\n\n            // Set the vertex format expected by the 2D text:\n            std::size_t offset = 0;\n\n            glEnableVertexAttribArray(0); // in_Position (vec2)\n            glVertexAttribPointer(\n                /* index     = */ 0,\n                /* size      = */ 2,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 2;\n\n            glEnableVertexAttribArray(1); // in_TexCoords (vec2)\n            glVertexAttribPointer(\n                /* index     = */ 1,\n                /* size      = */ 2,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 2;\n\n            glEnableVertexAttribArray(2); // in_Color (vec4)\n            glVertexAttribPointer(\n                /* index     = */ 2,\n                /* size      = */ 4,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n\n            checkGLError(__FILE__, __LINE__);\n\n            // Ditto.\n            glBindVertexArray(0);\n            glBindBuffer(GL_ARRAY_BUFFER, 0);\n        }\n    }\n\n    static GLuint handleToGL(dd::GlyphTextureHandle handle)\n    {\n        const std::size_t temp = reinterpret_cast<std::size_t>(handle);\n        return static_cast<GLuint>(temp);\n    }\n\n    static dd::GlyphTextureHandle GLToHandle(const GLuint id)\n    {\n        const std::size_t temp = static_cast<std::size_t>(id);\n        return reinterpret_cast<dd::GlyphTextureHandle>(temp);\n    }\n\n    static void checkGLError(const char * file, const int line)\n    {\n        GLenum err;\n        while ((err = glGetError()) != GL_NO_ERROR)\n        {\n            errorF(\"%s(%d) : GL_CORE_ERROR=0x%X - %s\", file, line, err, errorToString(err));\n        }\n    }\n\n    static void compileShader(const GLuint shader)\n    {\n        glCompileShader(shader);\n        checkGLError(__FILE__, __LINE__);\n\n        GLint status;\n        glGetShaderiv(shader, GL_COMPILE_STATUS, &status);\n        checkGLError(__FILE__, __LINE__);\n\n        if (status == GL_FALSE)\n        {\n            GLchar strInfoLog[1024] = {0};\n            glGetShaderInfoLog(shader, sizeof(strInfoLog) - 1, nullptr, strInfoLog);\n            errorF(\"\\n>>> Shader compiler errors:\\n%s\", strInfoLog);\n        }\n    }\n\n    static void linkProgram(const GLuint program)\n    {\n        glLinkProgram(program);\n        checkGLError(__FILE__, __LINE__);\n\n        GLint status;\n        glGetProgramiv(program, GL_LINK_STATUS, &status);\n        checkGLError(__FILE__, __LINE__);\n\n        if (status == GL_FALSE)\n        {\n            GLchar strInfoLog[1024] = {0};\n            glGetProgramInfoLog(program, sizeof(strInfoLog) - 1, nullptr, strInfoLog);\n            errorF(\"\\n>>> Program linker errors:\\n%s\", strInfoLog);\n        }\n    }\n\nprivate:\n\n    // The \"model-view-projection\" matrix for the scene.\n    // In this demo, it consists of the camera's view and projection matrices only.\n    Matrix4 mvpMatrix;\n\n    GLuint linePointProgram;\n    GLint  linePointProgram_MvpMatrixLocation;\n\n    GLuint textProgram;\n    GLint  textProgram_GlyphTextureLocation;\n    GLint  textProgram_ScreenDimensions;\n\n    GLuint linePointVAO;\n    GLuint linePointVBO;\n\n    GLuint textVAO;\n    GLuint textVBO;\n\n    static const char * linePointVertShaderSrc;\n    static const char * linePointFragShaderSrc;\n\n    static const char * textVertShaderSrc;\n    static const char * textFragShaderSrc;\n\n}; // class DDRenderInterfaceCoreGL\n\n// ========================================================\n// Minimal shaders we need for the debug primitives:\n// ========================================================\n\nconst char * DDRenderInterfaceCoreGL::linePointVertShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec3 in_Position;\\n\"\n    \"in vec4 in_ColorPointSize;\\n\"\n    \"\\n\"\n    \"out vec4 v_Color;\\n\"\n    \"uniform mat4 u_MvpMatrix;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    gl_Position  = u_MvpMatrix * vec4(in_Position, 1.0);\\n\"\n    \"    gl_PointSize = in_ColorPointSize.w;\\n\"\n    \"    v_Color      = vec4(in_ColorPointSize.xyz, 1.0);\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::linePointFragShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in  vec4 v_Color;\\n\"\n    \"out vec4 out_FragColor;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    out_FragColor = v_Color;\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::textVertShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec2 in_Position;\\n\"\n    \"in vec2 in_TexCoords;\\n\"\n    \"in vec3 in_Color;\\n\"\n    \"\\n\"\n    \"uniform vec2 u_screenDimensions;\\n\"\n    \"\\n\"\n    \"out vec2 v_TexCoords;\\n\"\n    \"out vec4 v_Color;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    // Map to normalized clip coordinates:\\n\"\n    \"    float x = ((2.0 * (in_Position.x - 0.5)) / u_screenDimensions.x) - 1.0;\\n\"\n    \"    float y = 1.0 - ((2.0 * (in_Position.y - 0.5)) / u_screenDimensions.y);\\n\"\n    \"\\n\"\n    \"    gl_Position = vec4(x, y, 0.0, 1.0);\\n\"\n    \"    v_TexCoords = in_TexCoords;\\n\"\n    \"    v_Color     = vec4(in_Color, 1.0);\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::textFragShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec2 v_TexCoords;\\n\"\n    \"in vec4 v_Color;\\n\"\n    \"\\n\"\n    \"uniform sampler2D u_glyphTexture;\\n\"\n    \"out vec4 out_FragColor;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    out_FragColor = v_Color;\\n\"\n    \"    out_FragColor.a = texture(u_glyphTexture, v_TexCoords).r;\\n\"\n    \"}\\n\";\n\n// ========================================================\n// GLFW / window management / sample drawing:\n// ========================================================\n\nstruct ThreadData\n{\n    dd::ContextHandle ddContext;\n    DDRenderInterfaceCoreGL * renderInterface;\n    void (*threadDrawFunc)(const ThreadData &);\n\n    void init(void (*fn)(const ThreadData &), DDRenderInterfaceCoreGL * ri)\n    {\n        ddContext       = nullptr;\n        renderInterface = ri;\n        threadDrawFunc  = fn;\n\n        dd::initialize(&ddContext, renderInterface);\n    }\n\n    void shutdown()\n    {\n        dd::shutdown(ddContext);\n\n        ddContext       = nullptr;\n        renderInterface = nullptr;\n        threadDrawFunc  = nullptr;\n    }\n};\n\n// ========================================================\n\nstatic void drawLabel(const ThreadData & td, ddVec3_In pos, const char * name)\n{\n    if (!keys.showLabels)\n    {\n        return;\n    }\n\n    // Only draw labels inside the camera frustum.\n    if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2]))\n    {\n        const ddVec3 textColor = { 0.8f, 0.8f, 1.0f };\n        dd::projectedText(td.ddContext, name, pos, textColor, toFloatPtr(camera.vpMatrix),\n                          0, 0, WindowWidth, WindowHeight, 0.5f);\n    }\n}\n\nstatic void drawGrid(const ThreadData & td)\n{\n    if (keys.showGrid)\n    {\n        dd::xzSquareGrid(td.ddContext, -50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z\n    }\n}\n\nstatic void drawMiscObjects(const ThreadData & td)\n{\n    // Start a row of objects at this position:\n    ddVec3 origin = { -15.0f, 0.0f, 0.0f };\n\n    // Box with a point at it's center:\n    drawLabel(td, origin, \"box\");\n    dd::box(td.ddContext, origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n    origin[0] += 3.0f;\n\n    // Sphere with a point at its center\n    drawLabel(td, origin, \"sphere\");\n    dd::sphere(td.ddContext, origin, dd::colors::Red, 1.0f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Two cones, one open and one closed:\n    const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f };\n    origin[1] -= 1.0f;\n\n    drawLabel(td, origin, \"cone (open)\");\n    dd::cone(td.ddContext, origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    drawLabel(td, origin, \"cone (closed)\");\n    dd::cone(td.ddContext, origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Axis-aligned bounding box:\n    const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f };\n    const ddVec3 bbMaxs = {  1.0f,  2.2f,  1.0f };\n    const ddVec3 bbCenter = {\n        (bbMins[0] + bbMaxs[0]) * 0.5f,\n        (bbMins[1] + bbMaxs[1]) * 0.5f,\n        (bbMins[2] + bbMaxs[2]) * 0.5f\n    };\n    drawLabel(td, origin, \"AABB\");\n    dd::aabb(td.ddContext, bbMins, bbMaxs, dd::colors::Orange);\n    dd::point(td.ddContext, bbCenter, dd::colors::White, 15.0f);\n\n    // Move along the Z for another row:\n    origin[0] = -15.0f;\n    origin[2] += 5.0f;\n\n    // A big arrow pointing up:\n    const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] };\n    const ddVec3 arrowTo   = { origin[0], origin[1] + 5.0f, origin[2] };\n    drawLabel(td, arrowFrom, \"arrow\");\n    dd::arrow(td.ddContext, arrowFrom, arrowTo, dd::colors::Magenta, 1.0f);\n    dd::point(td.ddContext, arrowFrom, dd::colors::White, 15.0f);\n    dd::point(td.ddContext, arrowTo, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Plane with normal vector:\n    const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f };\n    drawLabel(td, origin, \"plane\");\n    dd::plane(td.ddContext, origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Circle on the Y plane:\n    drawLabel(td, origin, \"circle\");\n    dd::circle(td.ddContext, origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n    origin[0] += 3.2f;\n\n    // Tangent basis vectors:\n    const ddVec3 normal    = { 0.0f, 1.0f, 0.0f };\n    const ddVec3 tangent   = { 1.0f, 0.0f, 0.0f };\n    const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f };\n    origin[1] += 0.1f;\n    drawLabel(td, origin, \"tangent basis\");\n    dd::tangentBasis(td.ddContext, origin, normal, tangent, bitangent, 2.5f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n\n    // And a set of intersecting axes:\n    origin[0] += 4.0f;\n    origin[1] += 1.0f;\n    drawLabel(td, origin, \"cross\");\n    dd::cross(td.ddContext, origin, 2.0f);\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n}\n\nstatic void drawFrustum(const ThreadData & td)\n{\n    const ddVec3 color  = {  0.8f, 0.3f, 1.0f  };\n    const ddVec3 origin = { -8.0f, 0.5f, 14.0f };\n    drawLabel(td, origin, \"frustum + axes\");\n\n    // The frustum will depict a fake camera:\n    const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f);\n    const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis());\n    const Matrix4 clip = inverse(proj * view);\n    dd::frustum(td.ddContext, toFloatPtr(clip), color);\n\n    // A white dot at the eye position:\n    dd::point(td.ddContext, origin, dd::colors::White, 15.0f);\n\n    // A set of arrows at the camera's origin/eye:\n    const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f));\n    dd::axisTriad(td.ddContext, toFloatPtr(transform), 0.3f, 2.0f);\n}\n\nstatic void drawText(const ThreadData & td)\n{\n    // HUD text:\n    const ddVec3 textColor = { 1.0f,  1.0f,  1.0f };\n    const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f };\n    dd::screenText(td.ddContext,\n                   \"Welcome to the multi-threaded Core OpenGL Debug Draw demo.\\n\\n\"\n                   \"[SPACE]  to toggle labels on/off\\n\"\n                   \"[RETURN] to toggle grid on/off\",\n                   textPos2D, textColor, 0.55f);\n}\n\nstatic void sampleAppDraw(DDRenderInterfaceCoreGL & ddRenderIfaceGL, ThreadData tds[4], JobQueue & jobQ)\n{\n    // Camera input update (the 'camera' object is declared in samples_common.hpp):\n    camera.checkKeyboardMovement();\n    camera.checkMouseRotation();\n    camera.updateMatrices();\n\n    // Kick async render jobs:\n    for (int i = 0; i < 4; ++i)\n    {\n        const ThreadData & td = tds[i];\n        jobQ.pushJob([td]() { td.threadDrawFunc(td); });\n    }\n\n    // Begin a frame:\n    ddRenderIfaceGL.prepareDraw(camera.vpMatrix);\n\n    // Wait async draws to complete. In a more real life scenario this would\n    // be the place to perform some other non-dependent work to avoid blocking.\n    jobQ.waitAll();\n\n    // Flush each individual context from the main thread:\n    for (int i = 0; i < 4; ++i)\n    {\n        dd::flush(tds[i].ddContext);\n    }\n}\n\nstatic void sampleAppStart()\n{\n    printDDBuildConfig();\n\n    if (!glfwInit())\n    {\n        errorF(\"Failed to initialize GLFW!\");\n        return;\n    }\n\n    // Things we need for the window / GL render context:\n    glfwWindowHint(GLFW_RESIZABLE, false);\n    glfwWindowHint(GLFW_DEPTH_BITS, 32);\n    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);\n    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);\n\n    GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight,\n                                           \"Debug Draw Sample - Core OpenGL (MT, explicit context)\",\n                                           nullptr, nullptr);\n    if (!window)\n    {\n        errorF(\"Failed to create GLFW window!\");\n        return;\n    }\n\n    glfwMakeContextCurrent(window);\n\n    if (!gl3wInit())\n    {\n        errorF(\"Failed to initialize GL3W extension library!\");\n        return;\n    }\n\n    if (!gl3wIsSupported(3, 2))\n    {\n        errorF(\"This sample application requires at least OpenGL version 3.2 to run!\");\n        return;\n    }\n\n    // From samples_common.hpp\n    initInput(window);\n\n    // Set up an OpenGL renderer:\n    DDRenderInterfaceCoreGL ddRenderIfaceGL;\n\n    // Draw contexts:\n    ThreadData threads[4];\n    threads[0].init(&drawGrid,        &ddRenderIfaceGL);\n    threads[1].init(&drawMiscObjects, &ddRenderIfaceGL);\n    threads[2].init(&drawFrustum,     &ddRenderIfaceGL);\n    threads[3].init(&drawText,        &ddRenderIfaceGL);\n\n    // Each draw function will be pushed into the async job queue\n    // by the main thread every frame, then main will wait on it\n    // and submit the GL draw commands with dd::flush().\n    JobQueue jobQ;\n    jobQ.launch();\n\n    // Loop until the user closes the window:\n    while (!glfwWindowShouldClose(window))\n    {\n        const double t0s = glfwGetTime();\n\n        sampleAppDraw(ddRenderIfaceGL, threads, jobQ);\n        glfwSwapBuffers(window);\n        glfwPollEvents();\n\n        const double t1s = glfwGetTime();\n\n        deltaTime.seconds      = static_cast<float>(t1s - t0s);\n        deltaTime.milliseconds = static_cast<std::int64_t>(deltaTime.seconds * 1000.0);\n    }\n\n    jobQ.waitAll();\n    for (int i = 0; i < 4; ++i)\n    {\n        threads[i].shutdown();\n    }\n}\n\n// ========================================================\n// main():\n// ========================================================\n\nint main()\n{\n    sampleAppStart();\n    gl3wShutdown();\n    glfwTerminate();\n}\n\n"
  },
  {
    "path": "samples/sample_gl_core_multithreaded_tls.cpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   sample_gl_core_multithreaded_tls.cpp\n// Author: Guilherme R. Lampert\n// Brief:  Debug Draw usage sample with Core Profile OpenGL and separate rendering thread.\n//         Uses the implicit context as a thread-local variable of the rendering thread.\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#define DEBUG_DRAW_IMPLEMENTATION\n#define DEBUG_DRAW_PER_THREAD_CONTEXT\n\n#include \"debug_draw.hpp\"     // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here!\n#include <GL/gl3w.h>          // An OpenGL extension wrangler (https://github.com/skaslev/gl3w).\n#include \"samples_common.hpp\" // Common code shared by the samples (camera, input, etc).\n\nusing namespace ddSamplesCommon;\n\n// ========================================================\n// Debug Draw RenderInterface for Core OpenGL:\n// ========================================================\n\nclass DDRenderInterfaceCoreGL final\n    : public dd::RenderInterface\n{\npublic:\n\n    //\n    // dd::RenderInterface overrides:\n    //\n\n    void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override\n    {\n        assert(points != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n        assert(isOwnerThreadCall());\n\n        glBindVertexArray(linePointVAO);\n        glUseProgram(linePointProgram);\n\n        glUniformMatrix4fv(linePointProgram_MvpMatrixLocation,\n                           1, GL_FALSE, toFloatPtr(mvpMatrix));\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick...\n        glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), points);\n\n        // Issue the draw call:\n        glDrawArrays(GL_POINTS, 0, count);\n\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override\n    {\n        assert(lines != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n        assert(isOwnerThreadCall());\n\n        glBindVertexArray(linePointVAO);\n        glUseProgram(linePointProgram);\n\n        glUniformMatrix4fv(linePointProgram_MvpMatrixLocation,\n                           1, GL_FALSE, toFloatPtr(mvpMatrix));\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick...\n        glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), lines);\n\n        // Issue the draw call:\n        glDrawArrays(GL_LINES, 0, count);\n\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(glyphs != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n        assert(isOwnerThreadCall());\n\n        glBindVertexArray(textVAO);\n        glUseProgram(textProgram);\n\n        // These doesn't have to be reset every draw call, I'm just being lazy ;)\n        glUniform1i(textProgram_GlyphTextureLocation, 0);\n        glUniform2f(textProgram_ScreenDimensions,\n                    static_cast<GLfloat>(WindowWidth),\n                    static_cast<GLfloat>(WindowHeight));\n\n        if (glyphTex != nullptr)\n        {\n            glActiveTexture(GL_TEXTURE0);\n            glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex));\n        }\n\n        glEnable(GL_BLEND);\n        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\n        glDisable(GL_DEPTH_TEST);\n\n        glBindBuffer(GL_ARRAY_BUFFER, textVBO);\n        glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), glyphs);\n\n        glDrawArrays(GL_TRIANGLES, 0, count); // Issue the draw call\n\n        glDisable(GL_BLEND);\n        glUseProgram(0);\n        glBindVertexArray(0);\n        glBindBuffer(GL_ARRAY_BUFFER, 0);\n        glBindTexture(GL_TEXTURE_2D,  0);\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override\n    {\n        assert(width > 0 && height > 0);\n        assert(pixels != nullptr);\n        assert(isOwnerThreadCall());\n\n        GLuint textureId = 0;\n        glGenTextures(1, &textureId);\n        glBindTexture(GL_TEXTURE_2D, textureId);\n\n        glPixelStorei(GL_PACK_ALIGNMENT,   1);\n        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);\n\n        glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);\n\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\n        glBindTexture(GL_TEXTURE_2D, 0);\n        checkGLError(__FILE__, __LINE__);\n\n        return GLToHandle(textureId);\n    }\n\n    void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(isOwnerThreadCall());\n        if (glyphTex == nullptr)\n        {\n            return;\n        }\n\n        const GLuint textureId = handleToGL(glyphTex);\n        glBindTexture(GL_TEXTURE_2D, 0);\n        glDeleteTextures(1, &textureId);\n    }\n\n    void beginDraw() override { assert(isOwnerThreadCall()); }\n    void endDraw()   override { assert(isOwnerThreadCall()); }\n\n    //\n    // Local methods:\n    //\n\n    DDRenderInterfaceCoreGL()\n        : mvpMatrix(Matrix4::identity())\n        , linePointProgram(0)\n        , linePointProgram_MvpMatrixLocation(-1)\n        , textProgram(0)\n        , textProgram_GlyphTextureLocation(-1)\n        , textProgram_ScreenDimensions(-1)\n        , linePointVAO(0)\n        , linePointVBO(0)\n        , textVAO(0)\n        , textVBO(0)\n    {\n        std::printf(\"\\n\");\n        std::printf(\"GL_VENDOR    : %s\\n\",   glGetString(GL_VENDOR));\n        std::printf(\"GL_RENDERER  : %s\\n\",   glGetString(GL_RENDERER));\n        std::printf(\"GL_VERSION   : %s\\n\",   glGetString(GL_VERSION));\n        std::printf(\"GLSL_VERSION : %s\\n\\n\", glGetString(GL_SHADING_LANGUAGE_VERSION));\n        std::printf(\"DDRenderInterfaceCoreGL MT initializing ...\\n\");\n\n        // Default OpenGL states:\n        glEnable(GL_CULL_FACE);\n        glEnable(GL_DEPTH_TEST);\n        glDisable(GL_BLEND);\n\n        // This has to be enabled since the point drawing shader will use gl_PointSize.\n        glEnable(GL_PROGRAM_POINT_SIZE);\n\n        setupShaderPrograms();\n        setupVertexBuffers();\n\n        std::printf(\"DDRenderInterfaceCoreGL MT ready!\\n\\n\");\n    }\n\n    ~DDRenderInterfaceCoreGL()\n    {\n        glDeleteProgram(linePointProgram);\n        glDeleteProgram(textProgram);\n\n        glDeleteVertexArrays(1, &linePointVAO);\n        glDeleteBuffers(1, &linePointVBO);\n\n        glDeleteVertexArrays(1, &textVAO);\n        glDeleteBuffers(1, &textVBO);\n    }\n\n    void prepareDraw(const Matrix4 & mvp)\n    {\n        assert(isOwnerThreadCall());\n\n        mvpMatrix = mvp;\n        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);\n        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n    }\n\n    void setupShaderPrograms()\n    {\n        std::printf(\"> DDRenderInterfaceCoreGL::setupShaderPrograms()\\n\");\n\n        //\n        // Line/point drawing shader:\n        //\n        {\n            GLuint linePointVS = glCreateShader(GL_VERTEX_SHADER);\n            glShaderSource(linePointVS, 1, &linePointVertShaderSrc, nullptr);\n            compileShader(linePointVS);\n\n            GLint linePointFS = glCreateShader(GL_FRAGMENT_SHADER);\n            glShaderSource(linePointFS, 1, &linePointFragShaderSrc, nullptr);\n            compileShader(linePointFS);\n\n            linePointProgram = glCreateProgram();\n            glAttachShader(linePointProgram, linePointVS);\n            glAttachShader(linePointProgram, linePointFS);\n\n            glBindAttribLocation(linePointProgram, 0, \"in_Position\");\n            glBindAttribLocation(linePointProgram, 1, \"in_ColorPointSize\");\n            linkProgram(linePointProgram);\n\n            linePointProgram_MvpMatrixLocation = glGetUniformLocation(linePointProgram, \"u_MvpMatrix\");\n            if (linePointProgram_MvpMatrixLocation < 0)\n            {\n                errorF(\"Unable to get u_MvpMatrix uniform location!\");\n            }\n            checkGLError(__FILE__, __LINE__);\n        }\n\n        //\n        // Text rendering shader:\n        //\n        {\n            GLuint textVS = glCreateShader(GL_VERTEX_SHADER);\n            glShaderSource(textVS, 1, &textVertShaderSrc, nullptr);\n            compileShader(textVS);\n\n            GLint textFS = glCreateShader(GL_FRAGMENT_SHADER);\n            glShaderSource(textFS, 1, &textFragShaderSrc, nullptr);\n            compileShader(textFS);\n\n            textProgram = glCreateProgram();\n            glAttachShader(textProgram, textVS);\n            glAttachShader(textProgram, textFS);\n\n            glBindAttribLocation(textProgram, 0, \"in_Position\");\n            glBindAttribLocation(textProgram, 1, \"in_TexCoords\");\n            glBindAttribLocation(textProgram, 2, \"in_Color\");\n            linkProgram(textProgram);\n\n            textProgram_GlyphTextureLocation = glGetUniformLocation(textProgram, \"u_glyphTexture\");\n            if (textProgram_GlyphTextureLocation < 0)\n            {\n                errorF(\"Unable to get u_glyphTexture uniform location!\");\n            }\n\n            textProgram_ScreenDimensions = glGetUniformLocation(textProgram, \"u_screenDimensions\");\n            if (textProgram_ScreenDimensions < 0)\n            {\n                errorF(\"Unable to get u_screenDimensions uniform location!\");\n            }\n\n            checkGLError(__FILE__, __LINE__);\n        }\n    }\n\n    void setupVertexBuffers()\n    {\n        std::printf(\"> DDRenderInterfaceCoreGL::setupVertexBuffers()\\n\");\n\n        //\n        // Lines/points vertex buffer:\n        //\n        {\n            glGenVertexArrays(1, &linePointVAO);\n            glGenBuffers(1, &linePointVBO);\n            checkGLError(__FILE__, __LINE__);\n\n            glBindVertexArray(linePointVAO);\n            glBindBuffer(GL_ARRAY_BUFFER, linePointVBO);\n\n            // RenderInterface will never be called with a batch larger than\n            // DEBUG_DRAW_VERTEX_BUFFER_SIZE vertexes, so we can allocate the same amount here.\n            glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW);\n            checkGLError(__FILE__, __LINE__);\n\n            // Set the vertex format expected by 3D points and lines:\n            std::size_t offset = 0;\n\n            glEnableVertexAttribArray(0); // in_Position (vec3)\n            glVertexAttribPointer(\n                /* index     = */ 0,\n                /* size      = */ 3,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 3;\n\n            glEnableVertexAttribArray(1); // in_ColorPointSize (vec4)\n            glVertexAttribPointer(\n                /* index     = */ 1,\n                /* size      = */ 4,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n\n            checkGLError(__FILE__, __LINE__);\n\n            // VAOs can be a pain in the neck if left enabled...\n            glBindVertexArray(0);\n            glBindBuffer(GL_ARRAY_BUFFER, 0);\n        }\n\n        //\n        // Text rendering vertex buffer:\n        //\n        {\n            glGenVertexArrays(1, &textVAO);\n            glGenBuffers(1, &textVBO);\n            checkGLError(__FILE__, __LINE__);\n\n            glBindVertexArray(textVAO);\n            glBindBuffer(GL_ARRAY_BUFFER, textVBO);\n\n            // NOTE: A more optimized implementation might consider combining\n            // both the lines/points and text buffers to save some memory!\n            glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW);\n            checkGLError(__FILE__, __LINE__);\n\n            // Set the vertex format expected by the 2D text:\n            std::size_t offset = 0;\n\n            glEnableVertexAttribArray(0); // in_Position (vec2)\n            glVertexAttribPointer(\n                /* index     = */ 0,\n                /* size      = */ 2,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 2;\n\n            glEnableVertexAttribArray(1); // in_TexCoords (vec2)\n            glVertexAttribPointer(\n                /* index     = */ 1,\n                /* size      = */ 2,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n            offset += sizeof(float) * 2;\n\n            glEnableVertexAttribArray(2); // in_Color (vec4)\n            glVertexAttribPointer(\n                /* index     = */ 2,\n                /* size      = */ 4,\n                /* type      = */ GL_FLOAT,\n                /* normalize = */ GL_FALSE,\n                /* stride    = */ sizeof(dd::DrawVertex),\n                /* offset    = */ reinterpret_cast<void *>(offset));\n\n            checkGLError(__FILE__, __LINE__);\n\n            // Ditto.\n            glBindVertexArray(0);\n            glBindBuffer(GL_ARRAY_BUFFER, 0);\n        }\n    }\n\n    static GLuint handleToGL(dd::GlyphTextureHandle handle)\n    {\n        const std::size_t temp = reinterpret_cast<std::size_t>(handle);\n        return static_cast<GLuint>(temp);\n    }\n\n    static dd::GlyphTextureHandle GLToHandle(const GLuint id)\n    {\n        const std::size_t temp = static_cast<std::size_t>(id);\n        return reinterpret_cast<dd::GlyphTextureHandle>(temp);\n    }\n\n    static void checkGLError(const char * file, const int line)\n    {\n        GLenum err;\n        while ((err = glGetError()) != GL_NO_ERROR)\n        {\n            errorF(\"%s(%d) : GL_CORE_ERROR=0x%X - %s\", file, line, err, errorToString(err));\n        }\n    }\n\n    static void compileShader(const GLuint shader)\n    {\n        glCompileShader(shader);\n        checkGLError(__FILE__, __LINE__);\n\n        GLint status;\n        glGetShaderiv(shader, GL_COMPILE_STATUS, &status);\n        checkGLError(__FILE__, __LINE__);\n\n        if (status == GL_FALSE)\n        {\n            GLchar strInfoLog[1024] = {0};\n            glGetShaderInfoLog(shader, sizeof(strInfoLog) - 1, nullptr, strInfoLog);\n            errorF(\"\\n>>> Shader compiler errors:\\n%s\", strInfoLog);\n        }\n    }\n\n    static void linkProgram(const GLuint program)\n    {\n        glLinkProgram(program);\n        checkGLError(__FILE__, __LINE__);\n\n        GLint status;\n        glGetProgramiv(program, GL_LINK_STATUS, &status);\n        checkGLError(__FILE__, __LINE__);\n\n        if (status == GL_FALSE)\n        {\n            GLchar strInfoLog[1024] = {0};\n            glGetProgramInfoLog(program, sizeof(strInfoLog) - 1, nullptr, strInfoLog);\n            errorF(\"\\n>>> Program linker errors:\\n%s\", strInfoLog);\n        }\n    }\n\n    void setOwnerThread(std::thread::id tid)\n    {\n        ownerThreadId = tid;\n    }\n\n    bool isOwnerThreadCall() const\n    {\n        return std::this_thread::get_id() == ownerThreadId;\n    }\n\nprivate:\n\n    std::thread::id ownerThreadId;\n\n    // The \"model-view-projection\" matrix for the scene.\n    // In this demo, it consists of the camera's view and projection matrices only.\n    Matrix4 mvpMatrix;\n\n    GLuint linePointProgram;\n    GLint  linePointProgram_MvpMatrixLocation;\n\n    GLuint textProgram;\n    GLint  textProgram_GlyphTextureLocation;\n    GLint  textProgram_ScreenDimensions;\n\n    GLuint linePointVAO;\n    GLuint linePointVBO;\n\n    GLuint textVAO;\n    GLuint textVBO;\n\n    static const char * linePointVertShaderSrc;\n    static const char * linePointFragShaderSrc;\n\n    static const char * textVertShaderSrc;\n    static const char * textFragShaderSrc;\n\n}; // class DDRenderInterfaceCoreGL\n\n// ========================================================\n// Minimal shaders we need for the debug primitives:\n// ========================================================\n\nconst char * DDRenderInterfaceCoreGL::linePointVertShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec3 in_Position;\\n\"\n    \"in vec4 in_ColorPointSize;\\n\"\n    \"\\n\"\n    \"out vec4 v_Color;\\n\"\n    \"uniform mat4 u_MvpMatrix;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    gl_Position  = u_MvpMatrix * vec4(in_Position, 1.0);\\n\"\n    \"    gl_PointSize = in_ColorPointSize.w;\\n\"\n    \"    v_Color      = vec4(in_ColorPointSize.xyz, 1.0);\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::linePointFragShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in  vec4 v_Color;\\n\"\n    \"out vec4 out_FragColor;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    out_FragColor = v_Color;\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::textVertShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec2 in_Position;\\n\"\n    \"in vec2 in_TexCoords;\\n\"\n    \"in vec3 in_Color;\\n\"\n    \"\\n\"\n    \"uniform vec2 u_screenDimensions;\\n\"\n    \"\\n\"\n    \"out vec2 v_TexCoords;\\n\"\n    \"out vec4 v_Color;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    // Map to normalized clip coordinates:\\n\"\n    \"    float x = ((2.0 * (in_Position.x - 0.5)) / u_screenDimensions.x) - 1.0;\\n\"\n    \"    float y = 1.0 - ((2.0 * (in_Position.y - 0.5)) / u_screenDimensions.y);\\n\"\n    \"\\n\"\n    \"    gl_Position = vec4(x, y, 0.0, 1.0);\\n\"\n    \"    v_TexCoords = in_TexCoords;\\n\"\n    \"    v_Color     = vec4(in_Color, 1.0);\\n\"\n    \"}\\n\";\n\nconst char * DDRenderInterfaceCoreGL::textFragShaderSrc = \"\\n\"\n    \"#version 150\\n\"\n    \"\\n\"\n    \"in vec2 v_TexCoords;\\n\"\n    \"in vec4 v_Color;\\n\"\n    \"\\n\"\n    \"uniform sampler2D u_glyphTexture;\\n\"\n    \"out vec4 out_FragColor;\\n\"\n    \"\\n\"\n    \"void main()\\n\"\n    \"{\\n\"\n    \"    out_FragColor = v_Color;\\n\"\n    \"    out_FragColor.a = texture(u_glyphTexture, v_TexCoords).r;\\n\"\n    \"}\\n\";\n\n// ========================================================\n// GLFW / window management / sample drawing:\n// ========================================================\n\n// https://stackoverflow.com/questions/4792449/c0x-has-no-semaphores-how-to-synchronize-threads\nclass Semaphore final\n{\npublic:\n    Semaphore(int n = 0) : count(n)\n    { }\n\n    void signal()\n    {\n        std::unique_lock<std::mutex> lock(mtx);\n        count++;\n        cv.notify_one();\n    }\n\n    void wait()\n    {\n        std::unique_lock<std::mutex> lock(mtx);\n        while (count == 0)\n        {\n            cv.wait(lock);\n        }\n        count--;\n    }\n\nprivate:\n    std::mutex mtx;\n    std::condition_variable cv;\n    int count;\n};\n\n// ========================================================\n\nstruct ThreadData\n{\n    volatile bool shouldQuit;\n\n    DDRenderInterfaceCoreGL * renderInterface;\n    void (*threadFunc)(ThreadData &);\n    GLFWwindow * window;\n\n    std::thread threadObject;\n    Semaphore mainDone;\n    Semaphore renderDone;\n\n    ThreadData() : mainDone(0), renderDone(1)\n    { }\n\n    void init(void (*fn)(ThreadData &), DDRenderInterfaceCoreGL * ri, GLFWwindow * win)\n    {\n        shouldQuit      = false;\n        renderInterface = ri;\n        threadFunc      = fn;\n        window          = win;\n        threadObject    = std::thread([this]{ threadFunc(*this); });\n    }\n\n    void shutdown()\n    {\n        shouldQuit = true;\n        if (threadObject.joinable())\n        {\n            threadObject.join();\n        }\n\n        renderInterface = nullptr;\n        threadFunc      = nullptr;\n        window          = nullptr;\n    }\n};\n\n// ========================================================\n\nstatic void drawLabel(ddVec3_In pos, const char * name)\n{\n    if (!keys.showLabels)\n    {\n        return;\n    }\n\n    // Only draw labels inside the camera frustum.\n    if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2]))\n    {\n        const ddVec3 textColor = { 0.8f, 0.8f, 1.0f };\n        dd::projectedText(name, pos, textColor, toFloatPtr(camera.vpMatrix),\n                          0, 0, WindowWidth, WindowHeight, 0.5f);\n    }\n}\n\nstatic void drawGrid()\n{\n    if (keys.showGrid)\n    {\n        dd::xzSquareGrid(-50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z\n    }\n}\n\nstatic void drawMiscObjects()\n{\n    // Start a row of objects at this position:\n    ddVec3 origin = { -15.0f, 0.0f, 0.0f };\n\n    // Box with a point at it's center:\n    drawLabel(origin, \"box\");\n    dd::box(origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 3.0f;\n\n    // Sphere with a point at its center\n    drawLabel(origin, \"sphere\");\n    dd::sphere(origin, dd::colors::Red, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Two cones, one open and one closed:\n    const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f };\n    origin[1] -= 1.0f;\n\n    drawLabel(origin, \"cone (open)\");\n    dd::cone(origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    drawLabel(origin, \"cone (closed)\");\n    dd::cone(origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Axis-aligned bounding box:\n    const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f };\n    const ddVec3 bbMaxs = {  1.0f,  2.2f,  1.0f };\n    const ddVec3 bbCenter = {\n        (bbMins[0] + bbMaxs[0]) * 0.5f,\n        (bbMins[1] + bbMaxs[1]) * 0.5f,\n        (bbMins[2] + bbMaxs[2]) * 0.5f\n    };\n    drawLabel(origin, \"AABB\");\n    dd::aabb(bbMins, bbMaxs, dd::colors::Orange);\n    dd::point(bbCenter, dd::colors::White, 15.0f);\n\n    // Move along the Z for another row:\n    origin[0] = -15.0f;\n    origin[2] += 5.0f;\n\n    // A big arrow pointing up:\n    const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] };\n    const ddVec3 arrowTo   = { origin[0], origin[1] + 5.0f, origin[2] };\n    drawLabel(arrowFrom, \"arrow\");\n    dd::arrow(arrowFrom, arrowTo, dd::colors::Magenta, 1.0f);\n    dd::point(arrowFrom, dd::colors::White, 15.0f);\n    dd::point(arrowTo, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Plane with normal vector:\n    const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f };\n    drawLabel(origin, \"plane\");\n    dd::plane(origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Circle on the Y plane:\n    drawLabel(origin, \"circle\");\n    dd::circle(origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 3.2f;\n\n    // Tangent basis vectors:\n    const ddVec3 normal    = { 0.0f, 1.0f, 0.0f };\n    const ddVec3 tangent   = { 1.0f, 0.0f, 0.0f };\n    const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f };\n    origin[1] += 0.1f;\n    drawLabel(origin, \"tangent basis\");\n    dd::tangentBasis(origin, normal, tangent, bitangent, 2.5f);\n    dd::point(origin, dd::colors::White, 15.0f);\n\n    // And a set of intersecting axes:\n    origin[0] += 4.0f;\n    origin[1] += 1.0f;\n    drawLabel(origin, \"cross\");\n    dd::cross(origin, 2.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n}\n\nstatic void drawFrustum()\n{\n    const ddVec3 color  = {  0.8f, 0.3f, 1.0f  };\n    const ddVec3 origin = { -8.0f, 0.5f, 14.0f };\n    drawLabel(origin, \"frustum + axes\");\n\n    // The frustum will depict a fake camera:\n    const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f);\n    const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis());\n    const Matrix4 clip = inverse(proj * view);\n    dd::frustum(toFloatPtr(clip), color);\n\n    // A white dot at the eye position:\n    dd::point(origin, dd::colors::White, 15.0f);\n\n    // A set of arrows at the camera's origin/eye:\n    const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f));\n    dd::axisTriad(toFloatPtr(transform), 0.3f, 2.0f);\n}\n\nstatic void drawText()\n{\n    // HUD text:\n    const ddVec3 textColor = { 1.0f,  1.0f,  1.0f };\n    const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f };\n    dd::screenText(\"Welcome to the multi-threaded Core OpenGL Debug Draw demo.\\n\\n\"\n                   \"[SPACE]  to toggle labels on/off\\n\"\n                   \"[RETURN] to toggle grid on/off\",\n                   textPos2D, textColor, 0.55f);\n}\n\nstatic void sampleAppRenderThread(ThreadData & td)\n{\n    std::printf(\"Render thread starting...\\n\");\n\n    // Take ownership of the OpenGL context for this thread:\n    glfwMakeContextCurrent(td.window);\n    td.renderInterface->setOwnerThread(std::this_thread::get_id());\n\n    dd::initialize(td.renderInterface);\n\n    while (!td.shouldQuit)\n    {\n        td.mainDone.wait();\n\n        td.renderInterface->prepareDraw(camera.vpMatrix);\n\n        // Call some DD functions to add stuff to the debug draw queues:\n        drawGrid();\n        drawMiscObjects();\n        drawFrustum();\n        drawText();\n\n        dd::flush(getTimeMilliseconds());\n        glfwSwapBuffers(td.window);\n\n        td.renderDone.signal();\n    }\n\n    std::printf(\"Render thread exiting...\\n\");\n    dd::shutdown();\n}\n\nstatic void sampleAppStart()\n{\n    printDDBuildConfig();\n\n    if (!glfwInit())\n    {\n        errorF(\"Failed to initialize GLFW!\");\n        return;\n    }\n\n    // Things we need for the window / GL render context:\n    glfwWindowHint(GLFW_RESIZABLE, false);\n    glfwWindowHint(GLFW_DEPTH_BITS, 32);\n    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);\n    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);\n\n    GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight,\n                                           \"Debug Draw Sample - Core OpenGL (MT, implicit context)\",\n                                           nullptr, nullptr);\n    if (!window)\n    {\n        errorF(\"Failed to create GLFW window!\");\n        return;\n    }\n\n    glfwMakeContextCurrent(window);\n\n    if (!gl3wInit())\n    {\n        errorF(\"Failed to initialize GL3W extension library!\");\n        return;\n    }\n\n    if (!gl3wIsSupported(3, 2))\n    {\n        errorF(\"This sample application requires at least OpenGL version 3.2 to run!\");\n        return;\n    }\n\n    // From samples_common.hpp\n    initInput(window);\n\n    // Set up an OpenGL renderer:\n    DDRenderInterfaceCoreGL ddRenderIfaceGL;\n\n    // Launch the rendering thread that will call the DD functions:\n    ThreadData renderThread;\n    renderThread.init(&sampleAppRenderThread, &ddRenderIfaceGL, window);\n\n    // Loop until the user closes the window:\n    while (!glfwWindowShouldClose(window))\n    {\n        const double t0s = glfwGetTime();\n\n        renderThread.renderDone.wait();\n\n        camera.checkKeyboardMovement();\n        camera.checkMouseRotation();\n        camera.updateMatrices();\n\n        glfwPollEvents();\n\n        renderThread.mainDone.signal();\n\n        const double t1s = glfwGetTime();\n\n        deltaTime.seconds      = static_cast<float>(t1s - t0s);\n        deltaTime.milliseconds = static_cast<std::int64_t>(deltaTime.seconds * 1000.0);\n    }\n\n    renderThread.shutdown();\n}\n\n// ========================================================\n// main():\n// ========================================================\n\nint main()\n{\n    sampleAppStart();\n    gl3wShutdown();\n    glfwTerminate();\n}\n\n"
  },
  {
    "path": "samples/sample_gl_legacy.cpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   sample_gl_legacy.cpp\n// Author: Guilherme R. Lampert\n// Brief:  Debug Draw usage sample with legacy (AKA fixed function) OpenGL.\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#define DEBUG_DRAW_IMPLEMENTATION\n#include \"debug_draw.hpp\"     // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here!\n#include \"samples_common.hpp\" // Common code shared by the samples (camera, input, etc).\n\nusing namespace ddSamplesCommon;\n\n// ========================================================\n// Debug Draw RenderInterface for legacy OpenGL:\n// ========================================================\n\nclass DDRenderInterfaceLegacyGL final\n    : public dd::RenderInterface\n{\npublic:\n\n    //\n    // dd::RenderInterface overrides:\n    //\n\n    void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override\n    {\n        assert(points != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        for (int i = 0; i < count; ++i, ++points)\n        {\n            const dd::DrawVertex & v = *points;\n\n            // PoinSize cannot be called between Begin/End,\n            // so we can't hoist them out of this loop\n            glPointSize(v.point.size);\n\n            glBegin(GL_POINTS);\n            glColor3f(v.point.r, v.point.g, v.point.b);\n            glVertex3f(v.point.x, v.point.y, v.point.z);\n            glEnd();\n        }\n\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override\n    {\n        assert(lines != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        if (depthEnabled)\n        {\n            glEnable(GL_DEPTH_TEST);\n        }\n        else\n        {\n            glDisable(GL_DEPTH_TEST);\n        }\n\n        glBegin(GL_LINES);\n        for (int i = 0; i < count; ++i, ++lines)\n        {\n            const dd::DrawVertex & v = *lines;\n            glColor3f(v.line.r, v.line.g, v.line.b);\n            glVertex3f(v.line.x, v.line.y, v.line.z);\n        }\n        glEnd();\n\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override\n    {\n        assert(glyphs != nullptr);\n        assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n\n        // Legacy 2D draw settings:\n        glMatrixMode(GL_PROJECTION);\n        glLoadIdentity();\n        glOrtho(0, WindowWidth, WindowHeight, 0, -99999, 99999);\n        glMatrixMode(GL_MODELVIEW);\n        glLoadIdentity();\n\n        glDisable(GL_DEPTH_TEST);\n        glDisable(GL_CULL_FACE);\n\n        glEnable(GL_BLEND);\n        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\n\n        if (glyphTex != nullptr)\n        {\n            glEnable(GL_TEXTURE_2D);\n            glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex));\n        }\n\n        // DD will send the glyphs already triangulated to make\n        // integration easier with modern OpenGL, which deprecated\n        // GL_QUADS. But in this legacy GL sample we can still use it,\n        // so two vertexes out of every six just get thrown away.\n        glBegin(GL_QUADS);\n        for (int i = 0; i < count; i += 6)\n        {\n            const dd::DrawVertex & t0_v0 = *glyphs++;\n            const dd::DrawVertex & t0_v1 = *glyphs++;\n            const dd::DrawVertex & t0_v2 = *glyphs++;\n\n            /*const dd::DrawVertex & t1_v0 = */glyphs++;\n            /*const dd::DrawVertex & t1_v1 = */glyphs++;\n            const dd::DrawVertex & t1_v2 = *glyphs++;\n\n            glColor3f(t0_v0.glyph.r, t0_v0.glyph.g, t0_v0.glyph.b);\n            glTexCoord2f(t0_v0.glyph.u, t0_v0.glyph.v);\n            glVertex2f(t0_v0.glyph.x, t0_v0.glyph.y);\n\n            glColor3f(t0_v2.glyph.r, t0_v2.glyph.g, t0_v2.glyph.b);\n            glTexCoord2f(t0_v2.glyph.u, t0_v2.glyph.v);\n            glVertex2f(t0_v2.glyph.x, t0_v2.glyph.y);\n\n            glColor3f(t1_v2.glyph.r, t1_v2.glyph.g, t1_v2.glyph.b);\n            glTexCoord2f(t1_v2.glyph.u, t1_v2.glyph.v);\n            glVertex2f(t1_v2.glyph.x, t1_v2.glyph.y);\n\n            glColor3f(t0_v1.glyph.r, t0_v1.glyph.g, t0_v1.glyph.b);\n            glTexCoord2f(t0_v1.glyph.u, t0_v1.glyph.v);\n            glVertex2f(t0_v1.glyph.x, t0_v1.glyph.y);\n        }\n        glEnd();\n\n        glDisable(GL_BLEND);\n        if (glyphTex != nullptr)\n        {\n            glDisable(GL_TEXTURE_2D);\n        }\n\n        checkGLError(__FILE__, __LINE__);\n    }\n\n    dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override\n    {\n        assert(width > 0 && height > 0);\n        assert(pixels != nullptr);\n\n        GLuint textureId = 0;\n        glGenTextures(1, &textureId);\n        glBindTexture(GL_TEXTURE_2D, textureId);\n\n        //\n        // I don't recall if there was a way of getting\n        // similar behavior to GL_RED/GL_R8 in legacy OpenGL...\n        // Tried GL_LUMINANCE/GL_ALPHA but it didn't work.\n        //\n        // Simplest way is to just expand the texture to RGBA manually.\n        // Takes another memory allocation though, but this is a\n        // sample, so performance is not paramount ;)\n        //\n\n        struct RGBA\n        {\n            std::uint8_t r, g, b, a;\n        };\n\n        RGBA * expanded = new RGBA[width * height];\n        const std::uint8_t * p = static_cast<const std::uint8_t *>(pixels);\n\n        // Expand graymap the RGBA:\n        for (int i = 0; i < width * height; ++i)\n        {\n            expanded[i].r = 255;\n            expanded[i].g = 255;\n            expanded[i].b = 255;\n            expanded[i].a = p[i];\n        }\n\n        glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, expanded);\n        delete[] expanded;\n\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\n        glBindTexture(GL_TEXTURE_2D, 0);\n        checkGLError(__FILE__, __LINE__);\n\n        return GLToHandle(textureId);\n    }\n\n    void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override\n    {\n        if (glyphTex == nullptr)\n        {\n            return;\n        }\n\n        const GLuint textureId = handleToGL(glyphTex);\n        glBindTexture(GL_TEXTURE_2D, 0);\n        glDeleteTextures(1, &textureId);\n    }\n\n    // These two can also be implemented to perform GL render\n    // state setup/cleanup, but we don't use them in this sample.\n    //void beginDraw() override { }\n    //void endDraw()   override { }\n\n    //\n    // Local methods:\n    //\n\n    DDRenderInterfaceLegacyGL()\n    {\n        std::printf(\"\\n\");\n        std::printf(\"GL_VENDOR   : %s\\n\",   glGetString(GL_VENDOR));\n        std::printf(\"GL_RENDERER : %s\\n\",   glGetString(GL_RENDERER));\n        std::printf(\"GL_VERSION  : %s\\n\\n\", glGetString(GL_VERSION));\n        std::printf(\"DDRenderInterfaceLegacyGL initializing ...\\n\");\n\n        // Default OpenGL states:\n        glEnable(GL_CULL_FACE);\n        glEnable(GL_DEPTH_TEST);\n        glDisable(GL_BLEND);\n\n        std::printf(\"DDRenderInterfaceLegacyGL ready!\\n\\n\");\n    }\n\n    static GLuint handleToGL(dd::GlyphTextureHandle handle)\n    {\n        const std::size_t temp = reinterpret_cast<std::size_t>(handle);\n        return static_cast<GLuint>(temp);\n    }\n\n    static dd::GlyphTextureHandle GLToHandle(const GLuint id)\n    {\n        const std::size_t temp = static_cast<std::size_t>(id);\n        return reinterpret_cast<dd::GlyphTextureHandle>(temp);\n    }\n\n    static void checkGLError(const char * file, const int line)\n    {\n        GLenum err;\n        while ((err = glGetError()) != GL_NO_ERROR)\n        {\n            errorF(\"%s(%d) : GL_ERROR=0x%X - %s\", file, line, err, errorToString(err));\n        }\n    }\n}; // class DDRenderInterfaceLegacyGL\n\n// ========================================================\n// GLFW / window management / sample drawing:\n// ========================================================\n\nstatic void drawGrid()\n{\n    if (!keys.showGrid)\n    {\n        return;\n    }\n    dd::xzSquareGrid(-50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z\n}\n\nstatic void drawLabel(ddVec3_In pos, const char * name)\n{\n    if (!keys.showLabels)\n    {\n        return;\n    }\n\n    // Only draw labels inside the camera frustum.\n    if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2]))\n    {\n        const ddVec3 textColor = { 0.8f, 0.8f, 1.0f };\n        dd::projectedText(name, pos, textColor, toFloatPtr(camera.vpMatrix),\n                          0, 0, WindowWidth, WindowHeight, 0.5f);\n    }\n}\n\nstatic void drawMiscObjects()\n{\n    // Start a row of objects at this position:\n    ddVec3 origin = { -15.0f, 0.0f, 0.0f };\n\n    // Box with a point at it's center:\n    drawLabel(origin, \"box\");\n    dd::box(origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 3.0f;\n\n    // Sphere with a point at its center\n    drawLabel(origin, \"sphere\");\n    dd::sphere(origin, dd::colors::Red, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Two cones, one open and one closed:\n    const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f };\n    origin[1] -= 1.0f;\n\n    drawLabel(origin, \"cone (open)\");\n    dd::cone(origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    drawLabel(origin, \"cone (closed)\");\n    dd::cone(origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Axis-aligned bounding box:\n    const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f };\n    const ddVec3 bbMaxs = {  1.0f,  2.2f,  1.0f };\n    const ddVec3 bbCenter = {\n        (bbMins[0] + bbMaxs[0]) * 0.5f,\n        (bbMins[1] + bbMaxs[1]) * 0.5f,\n        (bbMins[2] + bbMaxs[2]) * 0.5f\n    };\n    drawLabel(origin, \"AABB\");\n    dd::aabb(bbMins, bbMaxs, dd::colors::Orange);\n    dd::point(bbCenter, dd::colors::White, 15.0f);\n\n    // Move along the Z for another row:\n    origin[0] = -15.0f;\n    origin[2] += 5.0f;\n\n    // A big arrow pointing up:\n    const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] };\n    const ddVec3 arrowTo   = { origin[0], origin[1] + 5.0f, origin[2] };\n    drawLabel(arrowFrom, \"arrow\");\n    dd::arrow(arrowFrom, arrowTo, dd::colors::Magenta, 1.0f);\n    dd::point(arrowFrom, dd::colors::White, 15.0f);\n    dd::point(arrowTo, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Plane with normal vector:\n    const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f };\n    drawLabel(origin, \"plane\");\n    dd::plane(origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 4.0f;\n\n    // Circle on the Y plane:\n    drawLabel(origin, \"circle\");\n    dd::circle(origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n    origin[0] += 3.2f;\n\n    // Tangent basis vectors:\n    const ddVec3 normal    = { 0.0f, 1.0f, 0.0f };\n    const ddVec3 tangent   = { 1.0f, 0.0f, 0.0f };\n    const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f };\n    origin[1] += 0.1f;\n    drawLabel(origin, \"tangent basis\");\n    dd::tangentBasis(origin, normal, tangent, bitangent, 2.5f);\n    dd::point(origin, dd::colors::White, 15.0f);\n\n    // And a set of intersecting axes:\n    origin[0] += 4.0f;\n    origin[1] += 1.0f;\n    drawLabel(origin, \"cross\");\n    dd::cross(origin, 2.0f);\n    dd::point(origin, dd::colors::White, 15.0f);\n}\n\nstatic void drawFrustum()\n{\n    const ddVec3 color  = {  0.8f, 0.3f, 1.0f  };\n    const ddVec3 origin = { -8.0f, 0.5f, 14.0f };\n    drawLabel(origin, \"frustum + axes\");\n\n    // The frustum will depict a fake camera:\n    const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f);\n    const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis());\n    const Matrix4 clip = inverse(proj * view);\n    dd::frustum(toFloatPtr(clip), color);\n\n    // A white dot at the eye position:\n    dd::point(origin, dd::colors::White, 15.0f);\n\n    // A set of arrows at the camera's origin/eye:\n    const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f));\n    dd::axisTriad(toFloatPtr(transform), 0.3f, 2.0f);\n}\n\nstatic void drawText()\n{\n    // HUD text:\n    const ddVec3 textColor = { 1.0f,  1.0f,  1.0f };\n    const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f };\n    dd::screenText(\"Welcome to the legacy OpenGL Debug Draw demo.\\n\\n\"\n                   \"[SPACE]  to toggle labels on/off\\n\"\n                   \"[RETURN] to toggle grid on/off\",\n                   textPos2D, textColor, 0.55f);\n}\n\nstatic void sampleAppDraw()\n{\n    // Camera input update (the 'camera' object is declared in samples_common.hpp):\n    camera.checkKeyboardMovement();\n    camera.checkMouseRotation();\n    camera.updateMatrices();\n\n    glMatrixMode(GL_PROJECTION);\n    glLoadMatrixf(toFloatPtr(camera.projMatrix));\n\n    glMatrixMode(GL_MODELVIEW);\n    glLoadMatrixf(toFloatPtr(camera.viewMatrix));\n\n    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);\n    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n\n    // Call some DD functions to add stuff to the debug draw queues:\n    drawGrid();\n    drawMiscObjects();\n    drawFrustum();\n    drawText();\n\n    // Drawing only really happens now (here's where RenderInterface gets called).\n    dd::flush(getTimeMilliseconds());\n}\n\nstatic void sampleAppStart()\n{\n    printDDBuildConfig();\n\n    if (!glfwInit())\n    {\n        errorF(\"Failed to initialize GLFW!\");\n        return;\n    }\n\n    // Things we need for the window / GL render context:\n    glfwWindowHint(GLFW_RESIZABLE, false);\n    glfwWindowHint(GLFW_DEPTH_BITS, 32);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);\n\n    GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight,\n                                           \"Debug Draw Sample - Legacy OpenGL\",\n                                           nullptr, nullptr);\n    if (!window)\n    {\n        errorF(\"Failed to create GLFW window!\");\n        return;\n    }\n\n    glfwMakeContextCurrent(window);\n\n    // From samples_common.hpp\n    initInput(window);\n\n    // Set up the Debug Draw:\n    DDRenderInterfaceLegacyGL ddRenderIfaceGL;\n    dd::initialize(&ddRenderIfaceGL);\n\n    // Loop until the user closes the window:\n    while (!glfwWindowShouldClose(window))\n    {\n        const double t0s = glfwGetTime();\n\n        sampleAppDraw();\n        glfwSwapBuffers(window);\n        glfwPollEvents();\n\n        const double t1s = glfwGetTime();\n\n        deltaTime.seconds      = static_cast<float>(t1s - t0s);\n        deltaTime.milliseconds = static_cast<std::int64_t>(deltaTime.seconds * 1000.0);\n    }\n\n    dd::shutdown();\n}\n\n// ========================================================\n// main():\n// ========================================================\n\nint main()\n{\n    sampleAppStart();\n    glfwTerminate();\n}\n\n"
  },
  {
    "path": "samples/sample_null_renderer.cpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   sample_null_renderer.cpp\n// Author: Guilherme R. Lampert\n// Brief:  Minimal Debug Draw usage sample that does nothing (a null renderer).\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#define DEBUG_DRAW_IMPLEMENTATION\n#include \"debug_draw.hpp\"\n\nclass DDRenderInterfaceNull final\n    : public dd::RenderInterface\n{\npublic:\n    ~DDRenderInterfaceNull() { }\n};\n\nint main()\n{\n    DDRenderInterfaceNull ddRenderIfaceNull;\n\n    dd::initialize(&ddRenderIfaceNull);\n\n    dd::flush();\n\n    dd::shutdown();\n}\n\n"
  },
  {
    "path": "samples/samples_common.hpp",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   samples_common.hpp\n// Author: Guilherme R. Lampert\n// Brief:  Common code shared by the Debug Draw samples.\n//\n// This software is in the public domain. Where that dedication is not recognized,\n// you are granted a perpetual, irrevocable license to copy, distribute, and modify\n// this file as you see fit.\n// ================================================================================================\n\n#ifndef DD_SAMPLES_COMMON_HPP\n#define DD_SAMPLES_COMMON_HPP\n\n// #define DD_SAMPLES_NOGL to exclude all OpenGL/GLFW\n// related code (e.g.: for the D3D Win32 samples)\n\n#include <cassert>\n#include <cmath>\n#include <cstdarg>\n#include <cstddef>\n#include <cstdint>\n#include <cstdio>\n#include <cstring>\n\n#include <chrono>\n#include <condition_variable>\n#include <functional>\n#include <mutex>\n#include <queue>\n#include <thread>\n#include <vectormath.h>\n\n#ifndef DD_SAMPLES_NOGL\n    #include <GLFW/glfw3.h>\n#endif // DD_SAMPLES_NOGL\n\nnamespace ddSamplesCommon\n{\n\n// App window dimensions; Not resizable.\nstatic const int WindowWidth  = 1024;\nstatic const int WindowHeight = 768;\n\n// Angle in degrees to angle in radians for sin/cos/etc.\nstatic inline float degToRad(const float degrees)\n{\n    return (degrees * 3.1415926535897931f / 180.0f);\n}\n\n#ifndef DD_SAMPLES_NOGL\n\n// Time in milliseconds since the application started.\nstatic inline std::int64_t getTimeMilliseconds()\n{\n    const double seconds = glfwGetTime();\n    return static_cast<std::int64_t>(seconds * 1000.0);\n}\n\n// Time in seconds since the application started.\nstatic inline double getTimeSeconds()\n{\n    return glfwGetTime();\n}\n\n// GL error enum to printable string.\nstatic inline const char * errorToString(const GLenum errorCode)\n{\n    switch (errorCode)\n    {\n    case GL_NO_ERROR          : return \"GL_NO_ERROR\";\n    case GL_INVALID_ENUM      : return \"GL_INVALID_ENUM\";\n    case GL_INVALID_VALUE     : return \"GL_INVALID_VALUE\";\n    case GL_INVALID_OPERATION : return \"GL_INVALID_OPERATION\";\n    case GL_OUT_OF_MEMORY     : return \"GL_OUT_OF_MEMORY\";\n    case GL_STACK_UNDERFLOW   : return \"GL_STACK_UNDERFLOW\"; // Legacy; not used on GL3+\n    case GL_STACK_OVERFLOW    : return \"GL_STACK_OVERFLOW\";  // Legacy; not used on GL3+\n    default                   : return \"Unknown GL error\";\n    } // switch (errorCode)\n}\n\n#else // DD_SAMPLES_NOGL defined\n\nusing TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;\nstatic TimePoint startupTime = std::chrono::high_resolution_clock::now();\n\nstatic inline std::int64_t getTimeMilliseconds()\n{\n    const auto currentTime = std::chrono::high_resolution_clock::now();\n    return std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startupTime).count();\n}\n\nstatic inline double getTimeSeconds()\n{\n    return getTimeMilliseconds() * 0.001f;\n}\n\n#endif // DD_SAMPLES_NOGL\n\n// Prints error to standard error stream.\nstatic inline void errorF(const char * format, ...)\n{\n    va_list args;\n    va_start(args, format);\n    std::vfprintf(stderr, format, args);\n    va_end(args);\n\n    // Default newline and flush (like std::endl)\n    std::fputc('\\n', stderr);\n    std::fflush(stderr);\n}\n\n// Prints some of the compile-time build settings to stdout.\nstatic inline void printDDBuildConfig()\n{\n    std::printf(\"\\n\");\n\n    #ifdef DEBUG_DRAW_CXX11_SUPPORTED\n    std::printf(\"DEBUG_DRAW_CXX11_SUPPORTED    = %u\\n\", DEBUG_DRAW_CXX11_SUPPORTED);\n    #endif // DEBUG_DRAW_CXX11_SUPPORTED\n\n    #ifdef DEBUG_DRAW_PER_THREAD_CONTEXT\n    std::printf(\"DEBUG_DRAW_PER_THREAD_CONTEXT = %u\\n\", /*DEBUG_DRAW_PER_THREAD_CONTEXT*/1);\n    #endif // DEBUG_DRAW_PER_THREAD_CONTEXT\n\n    #ifdef DEBUG_DRAW_EXPLICIT_CONTEXT\n    std::printf(\"DEBUG_DRAW_EXPLICIT_CONTEXT   = %u\\n\", /*DEBUG_DRAW_EXPLICIT_CONTEXT*/1);\n    #endif // DEBUG_DRAW_EXPLICIT_CONTEXT\n\n    std::printf(\"DEBUG_DRAW_USE_STD_MATH       = %u\\n\", DEBUG_DRAW_USE_STD_MATH);\n    std::printf(\"DEBUG_DRAW_MAX_STRINGS        = %u\\n\", DEBUG_DRAW_MAX_STRINGS);\n    std::printf(\"DEBUG_DRAW_MAX_POINTS         = %u\\n\", DEBUG_DRAW_MAX_POINTS);\n    std::printf(\"DEBUG_DRAW_MAX_LINES          = %u\\n\", DEBUG_DRAW_MAX_LINES);\n    std::printf(\"DEBUG_DRAW_VERTEX_BUFFER_SIZE = %u\\n\", DEBUG_DRAW_VERTEX_BUFFER_SIZE);\n}\n\n// ========================================================\n// Key/Mouse input + A simple 3D camera:\n// ========================================================\n\nstruct Keys\n{\n    // For the first-person camera controls.\n    bool wDown;\n    bool sDown;\n    bool aDown;\n    bool dDown;\n    // Flags:\n    bool showLabels; // True if object labels are drawn. Toggle with the space bar.\n    bool showGrid;   // True if the ground grid is drawn. Toggle with the return key.\n} keys;\n\nstruct Mouse\n{\n    enum { MaxDelta = 100 };\n    int  deltaX;\n    int  deltaY;\n    int  lastPosX;\n    int  lastPosY;\n    bool leftButtonDown;\n    bool rightButtonDown;\n} mouse;\n\nstruct Time\n{\n    float seconds;\n    std::int64_t milliseconds;\n} deltaTime;\n\nstruct Camera\n{\n    //\n    // Camera Axes:\n    //\n    //    (up)\n    //    +Y   +Z (forward)\n    //    |   /\n    //    |  /\n    //    | /\n    //    + ------ +X (right)\n    //  (eye)\n    //\n    Vector3 right;\n    Vector3 up;\n    Vector3 forward;\n    Vector3 eye;\n    Matrix4 viewMatrix;\n    Matrix4 projMatrix;\n    Matrix4 vpMatrix;\n\n    // Frustum planes for clipping:\n    enum { A, B, C, D };\n    Vector4 planes[6];\n\n    // Tunable values:\n    float movementSpeed = 3.0f;\n    float lookSpeed     = 6.0f;\n\n    enum MoveDir\n    {\n        Forward, // Move forward relative to the camera's space\n        Back,    // Move backward relative to the camera's space\n        Left,    // Move left relative to the camera's space\n        Right    // Move right relative to the camera's space\n    };\n\n    Camera()\n    {\n        right      = Vector3(1.0f, 0.0f, 0.0f);\n        up         = Vector3(0.0f, 1.0f, 0.0f);\n        forward    = Vector3(0.0f, 0.0f, 1.0f);\n        eye        = Vector3(0.0f, 0.0f, 0.0f);\n        viewMatrix = Matrix4::identity();\n        vpMatrix   = Matrix4::identity();\n\n        const float fovY   = degToRad(60.0f);\n        const float aspect = static_cast<float>(WindowWidth) / static_cast<float>(WindowHeight);\n        projMatrix = Matrix4::perspective(fovY, aspect, 0.1f, 1000.0f);\n\n        for (int i = 0; i < 6; ++i)\n        {\n            planes[i] = Vector4(0.0f);\n        }\n    }\n\n    void pitch(const float angle)\n    {\n        // Pitches camera by 'angle' radians.\n        forward = rotateAroundAxis(forward, right, angle); // Calculate new forward.\n        up      = cross(forward, right);                   // Calculate new camera up vector.\n    }\n\n    void rotate(const float angle)\n    {\n        // Rotates around world Y-axis by the given angle (in radians).\n        const float sinAng = std::sin(angle);\n        const float cosAng = std::cos(angle);\n        float xxx, zzz;\n\n        // Rotate forward vector:\n        xxx = forward[0];\n        zzz = forward[2];\n        forward[0] = xxx *  cosAng + zzz * sinAng;\n        forward[2] = xxx * -sinAng + zzz * cosAng;\n\n        // Rotate up vector:\n        xxx = up[0];\n        zzz = up[2];\n        up[0] = xxx *  cosAng + zzz * sinAng;\n        up[2] = xxx * -sinAng + zzz * cosAng;\n\n        // Rotate right vector:\n        xxx = right[0];\n        zzz = right[2];\n        right[0] = xxx *  cosAng + zzz * sinAng;\n        right[2] = xxx * -sinAng + zzz * cosAng;\n    }\n\n    void move(const MoveDir dir, const float amount)\n    {\n        switch (dir)\n        {\n        case Camera::Forward : eye += forward * amount; break;\n        case Camera::Back    : eye -= forward * amount; break;\n        case Camera::Left    : eye += right   * amount; break;\n        case Camera::Right   : eye -= right   * amount; break;\n        }\n    }\n\n    void checkKeyboardMovement()\n    {\n        const float moveSpeed = movementSpeed * deltaTime.seconds;\n        if (keys.aDown) { move(Camera::Left,    moveSpeed); }\n        if (keys.dDown) { move(Camera::Right,   moveSpeed); }\n        if (keys.wDown) { move(Camera::Forward, moveSpeed); }\n        if (keys.sDown) { move(Camera::Back,    moveSpeed); }\n    }\n\n    void checkMouseRotation()\n    {\n        static const float maxAngle = 89.5f; // Max degrees of rotation\n        static float pitchAmt;\n\n        if (!mouse.leftButtonDown)\n        {\n            return;\n        }\n\n        const float rotateSpeed = lookSpeed * deltaTime.seconds;\n\n        // Rotate left/right:\n        float amt = static_cast<float>(mouse.deltaX) * rotateSpeed;\n        rotate(degToRad(-amt));\n\n        // Calculate amount to rotate up/down:\n        amt = static_cast<float>(mouse.deltaY) * rotateSpeed;\n\n        // Clamp pitch amount:\n        if ((pitchAmt + amt) <= -maxAngle)\n        {\n            amt = -maxAngle - pitchAmt;\n            pitchAmt = -maxAngle;\n        }\n        else if ((pitchAmt + amt) >= maxAngle)\n        {\n            amt = maxAngle - pitchAmt;\n            pitchAmt = maxAngle;\n        }\n        else\n        {\n            pitchAmt += amt;\n        }\n\n        pitch(degToRad(-amt));\n    }\n\n    void updateMatrices()\n    {\n        viewMatrix = Matrix4::lookAt(Point3(eye), getTarget(), up);\n        vpMatrix   = projMatrix * viewMatrix; // Vectormath lib uses column-major OGL style, so multiply P*V*M\n\n        // Compute and normalize the 6 frustum planes:\n        const float * const m = toFloatPtr(vpMatrix);\n        planes[0][A] = m[3]  - m[0];\n        planes[0][B] = m[7]  - m[4];\n        planes[0][C] = m[11] - m[8];\n        planes[0][D] = m[15] - m[12];\n        planes[0] = normalize(planes[0]);\n        planes[1][A] = m[3]  + m[0];\n        planes[1][B] = m[7]  + m[4];\n        planes[1][C] = m[11] + m[8];\n        planes[1][D] = m[15] + m[12];\n        planes[1] = normalize(planes[1]);\n        planes[2][A] = m[3]  + m[1];\n        planes[2][B] = m[7]  + m[5];\n        planes[2][C] = m[11] + m[9];\n        planes[2][D] = m[15] + m[13];\n        planes[2] = normalize(planes[2]);\n        planes[3][A] = m[3]  - m[1];\n        planes[3][B] = m[7]  - m[5];\n        planes[3][C] = m[11] - m[9];\n        planes[3][D] = m[15] - m[13];\n        planes[3] = normalize(planes[3]);\n        planes[4][A] = m[3]  - m[2];\n        planes[4][B] = m[7]  - m[6];\n        planes[4][C] = m[11] - m[10];\n        planes[4][D] = m[15] - m[14];\n        planes[4] = normalize(planes[4]);\n        planes[5][A] = m[3]  + m[2];\n        planes[5][B] = m[7]  + m[6];\n        planes[5][C] = m[11] + m[10];\n        planes[5][D] = m[15] + m[14];\n        planes[5] = normalize(planes[5]);\n    }\n\n    Point3 getTarget() const\n    {\n        return Point3(eye[0] + forward[0], eye[1] + forward[1], eye[2] + forward[2]);\n    }\n\n    bool isPointInsideFrustum(const float x, const float y, const float z) const\n    {\n        for (int i = 0; i < 6; ++i)\n        {\n            if ((planes[i][A] * x + planes[i][B] * y + planes[i][C] * z + planes[i][D]) <= 0.0f)\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    static Vector3 rotateAroundAxis(const Vector3 & vec, const Vector3 & axis, const float angle)\n    {\n        const float sinAng = std::sin(angle);\n        const float cosAng = std::cos(angle);\n        const float oneMinusCosAng = (1.0f - cosAng);\n\n        const float aX = axis[0];\n        const float aY = axis[1];\n        const float aZ = axis[2];\n\n        float x = (aX * aX * oneMinusCosAng + cosAng)      * vec[0] +\n                  (aX * aY * oneMinusCosAng + aZ * sinAng) * vec[1] +\n                  (aX * aZ * oneMinusCosAng - aY * sinAng) * vec[2];\n\n        float y = (aX * aY * oneMinusCosAng - aZ * sinAng) * vec[0] +\n                  (aY * aY * oneMinusCosAng + cosAng)      * vec[1] +\n                  (aY * aZ * oneMinusCosAng + aX * sinAng) * vec[2];\n\n        float z = (aX * aZ * oneMinusCosAng + aY * sinAng) * vec[0] +\n                  (aY * aZ * oneMinusCosAng - aX * sinAng) * vec[1] +\n                  (aZ * aZ * oneMinusCosAng + cosAng)      * vec[2];\n\n        return Vector3(x, y, z);\n    }\n} camera;\n\n#ifndef DD_SAMPLES_NOGL\n\n// ========================================================\n// Input callbacks for GLFW:\n// ========================================================\n\nstatic void mousePositionCallback(GLFWwindow * window, const double xPos, const double yPos)\n{\n    (void)window; // Unused.\n\n    int mx = static_cast<int>(xPos);\n    int my = static_cast<int>(yPos);\n\n    // Clamp to window bounds:\n    if      (mx > WindowWidth)  { mx = WindowWidth;  }\n    else if (mx < 0)            { mx = 0;            }\n    if      (my > WindowHeight) { my = WindowHeight; }\n    else if (my < 0)            { my = 0;            }\n\n    mouse.deltaX = mx - mouse.lastPosX;\n    mouse.deltaY = my - mouse.lastPosY;\n    mouse.lastPosX = mx;\n    mouse.lastPosY = my;\n\n    // Clamp between -/+ max delta:\n    if      (mouse.deltaX >  Mouse::MaxDelta) { mouse.deltaX =  Mouse::MaxDelta; }\n    else if (mouse.deltaX < -Mouse::MaxDelta) { mouse.deltaX = -Mouse::MaxDelta; }\n    if      (mouse.deltaY >  Mouse::MaxDelta) { mouse.deltaY =  Mouse::MaxDelta; }\n    else if (mouse.deltaY < -Mouse::MaxDelta) { mouse.deltaY = -Mouse::MaxDelta; }\n}\n\nstatic void mouseButtonCallback(GLFWwindow * window, const int button, const int action, const int mods)\n{\n    // Unused.\n    (void)window;\n    (void)mods;\n\n    if (button == GLFW_MOUSE_BUTTON_LEFT)\n    {\n        mouse.leftButtonDown = (action != GLFW_RELEASE);\n    }\n    else if (button == GLFW_MOUSE_BUTTON_RIGHT)\n    {\n        mouse.rightButtonDown = (action != GLFW_RELEASE);\n    }\n}\n\nstatic void keyCallback(GLFWwindow * window, const int key, const int scancode, const int action, const int mods)\n{\n    // Unused.\n    (void)window;\n    (void)scancode;\n    (void)mods;\n\n    if      (key == GLFW_KEY_A || key == GLFW_KEY_LEFT)  { keys.aDown = (action != GLFW_RELEASE); }\n    else if (key == GLFW_KEY_D || key == GLFW_KEY_RIGHT) { keys.dDown = (action != GLFW_RELEASE); }\n    else if (key == GLFW_KEY_W || key == GLFW_KEY_UP)    { keys.wDown = (action != GLFW_RELEASE); }\n    else if (key == GLFW_KEY_S || key == GLFW_KEY_DOWN)  { keys.sDown = (action != GLFW_RELEASE); }\n    // Toggleable flags:\n    else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)\n    {\n        keys.showLabels = !keys.showLabels;\n    }\n    else if (key == GLFW_KEY_ENTER && action == GLFW_PRESS)\n    {\n        keys.showGrid = !keys.showGrid;\n    }\n}\n\nstatic void initInput(GLFWwindow * window)\n{\n    std::memset(&keys,  0, sizeof(keys));\n    std::memset(&mouse, 0, sizeof(mouse));\n\n    // GLFW input callbacks:\n    glfwSetCursorPosCallback(window,   &mousePositionCallback);\n    glfwSetMouseButtonCallback(window, &mouseButtonCallback);\n    glfwSetKeyCallback(window,         &keyCallback);\n}\n\n#endif // DD_SAMPLES_NOGL\n\n// ========================================================\n// MainThreadChecker - test if the calling thread is main()\n// ========================================================\n\nstruct MainThreadChecker\n{\n    const std::thread::id mainThreadId;\n\n    MainThreadChecker()\n        : mainThreadId(std::this_thread::get_id())\n    { }\n\n    bool operator()() const\n    {\n        return std::this_thread::get_id() == mainThreadId;\n    }\n} isMainThread;\n\n// ========================================================\n// class JobQueue\n// ========================================================\n\nclass JobQueue final\n{\npublic:\n    typedef std::function<void()> Job;\n\n    // Wait for the worker thread to exit.\n    ~JobQueue()\n    {\n        if (worker.joinable())\n        {\n            waitAll();\n            mutex.lock();\n            terminating = true;\n            condition.notify_one();\n            mutex.unlock();\n            worker.join();\n        }\n    }\n\n    // Launch the worker thread.\n    void launch()\n    {\n        assert(!worker.joinable()); // Not already launched!\n        worker = std::thread(&JobQueue::queueLoop, this);\n    }\n\n    // Add a new job to the thread's queue.\n    void pushJob(Job job)\n    {\n        std::lock_guard<std::mutex> lock(mutex);\n        queue.push(std::move(job));\n        condition.notify_one();\n    }\n\n    // Wait until all work items have been completed.\n    void waitAll()\n    {\n        std::unique_lock<std::mutex> lock(mutex);\n        condition.wait(lock, [this]() { return queue.empty(); });\n    }\n\nprivate:\n    void queueLoop()\n    {\n        for (;;)\n        {\n            Job job;\n            {\n                std::unique_lock<std::mutex> lock(mutex);\n                condition.wait(lock, [this] { return !queue.empty() || terminating; });\n                if (terminating)\n                {\n                    break;\n                }\n                job = queue.front();\n            }\n\n            job();\n\n            {\n                std::lock_guard<std::mutex> lock(mutex);\n                queue.pop();\n                condition.notify_one();\n            }\n        }\n    }\n\n    bool terminating = false;\n\n    std::thread worker;\n    std::queue<Job> queue;\n\n    std::mutex mutex;\n    std::condition_variable condition;\n};\n\n} // namespace ddSamplesCommon\n\n#endif // DD_SAMPLES_COMMON_HPP\n\n"
  },
  {
    "path": "samples/vectormath/LICENSE",
    "content": " Vector Math library for 3-D linear algebra (vector, matrix, quaternion)\n   SIMD support for SSE, PowerPC (PPU) and the SPU.\n   Also includes generic multi-platform scalar version. \n\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. \n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" \n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n \n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/boolInVec.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _BOOLINVEC_H\n#define _BOOLINVEC_H\n\n#include \"defines.h\"\n#include <math.h>\n\nnamespace Vectormath {\n\nclass floatInVec;\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec class\n//\n\n_VECTORMATH_ALIGNED_TYPE_1 class boolInVec {\n\nprivate:\n\n        __m128 mData;\n\n        inline boolInVec(__m128 vec);\n\npublic:\n\n        inline boolInVec() {}\n\n        // matches standard type conversions\n        //\n        inline boolInVec(const floatInVec &vec);\n\n        // explicit cast from bool\n        //\n        explicit inline boolInVec(bool scalar);\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n        // explicit cast to bool\n        //\n        inline bool getAsBool() const;\n#else\n        // implicit cast to bool\n        //\n        inline operator bool() const;\n#endif\n\n        // get vector data\n        // bool value is splatted across all word slots of vector as 0 (false) or -1 (true)\n        //\n        inline __m128 get128() const;\n\n        // operators\n        //\n        inline const boolInVec operator ! () const;\n        inline boolInVec& operator = (const boolInVec &vec);\n        inline boolInVec& operator &= (const boolInVec &vec);\n        inline boolInVec& operator ^= (const boolInVec &vec);\n        inline boolInVec& operator |= (const boolInVec &vec);\n\n        // friend functions\n        //\n        friend inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1);\n        friend inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1);\n        friend inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1);\n        friend inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1);\n        friend inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1);\n        friend inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1);\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec functions\n//\n\n// operators\n//\ninline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1);\ninline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1);\ninline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1);\ninline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1);\ninline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1);\n\n// select between vec0 and vec1 using boolInVec.\n// false selects vec0, true selects vec1\n//\ninline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1);\n\n} // namespace Vectormath\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec implementation\n//\n\n#include \"floatInVec.h\"\n\nnamespace Vectormath {\n\ninline\nboolInVec::boolInVec(__m128 vec)\n{\n    mData = vec;\n}\n\ninline\nboolInVec::boolInVec(const floatInVec &vec)\n{\n    *this = (vec != floatInVec(0.0f));\n}\n\ninline\nboolInVec::boolInVec(bool scalar)\n{\n    unsigned int mask = -(int)scalar;\n\tmData = _mm_set1_ps(*(float *)&mask); // TODO: Union\n}\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline\nbool\nboolInVec::getAsBool() const\n#else\ninline\nboolInVec::operator bool() const\n#endif\n{\n\treturn *(bool *)&mData;\n}\n\ninline\n__m128\nboolInVec::get128() const\n{\n    return mData;\n}\n\ninline\nconst boolInVec\nboolInVec::operator ! () const\n{\n    return boolInVec(_mm_andnot_ps(mData, _mm_cmpneq_ps(_mm_setzero_ps(),_mm_setzero_ps())));\n}\n\ninline\nboolInVec&\nboolInVec::operator = (const boolInVec &vec)\n{\n    mData = vec.mData;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator &= (const boolInVec &vec)\n{\n    *this = *this & vec;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator ^= (const boolInVec &vec)\n{\n    *this = *this ^ vec;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator |= (const boolInVec &vec)\n{\n    *this = *this | vec;\n    return *this;\n}\n\ninline\nconst boolInVec\noperator == (const boolInVec &vec0, const boolInVec &vec1)\n{\n\treturn boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator != (const boolInVec &vec0, const boolInVec &vec1)\n{\n\treturn boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator & (const boolInVec &vec0, const boolInVec &vec1)\n{\n\treturn boolInVec(_mm_and_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator | (const boolInVec &vec0, const boolInVec &vec1)\n{\n\treturn boolInVec(_mm_or_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator ^ (const boolInVec &vec0, const boolInVec &vec1)\n{\n\treturn boolInVec(_mm_xor_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\nselect(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1)\n{\n\treturn boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));\n}\n\n} // namespace Vectormath\n\n#endif // boolInVec_h\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/defines.h",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File: defines.h\n// Author: Guilherme R. Lampert\n// Created on: 22/03/13\n// Brief: Added this header with some defines to make the SSE library Unix friendly.\n// ================================================================================================\n\n#ifndef _VECTORMATH_DEFINES_H\n#define _VECTORMATH_DEFINES_H\n\n#if defined (_MSC_VER)\n\t// Visual Studio (MS compiler)\n\t#define _VECTORMATH_ALIGNED(type)  __declspec(align(16)) type\n\t#define _VECTORMATH_ALIGNED_TYPE_1 __declspec(align(16))\n\t#define _VECTORMATH_ALIGNED_TYPE_2\n#elif defined (__GNUC__)\n\t// GCC\n\t#define _VECTORMATH_ALIGNED(type) type __attribute__((aligned(16)))\n\t#define _VECTORMATH_ALIGNED_TYPE_1\n\t#define _VECTORMATH_ALIGNED_TYPE_2 __attribute__((aligned(16)))\n#else\n\t// Unknown\n\t#error \"Define _VECTORMATH_ALIGNED for your compiler\"\n#endif\n\n#endif // _VECTORMATH_DEFINES_H\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/floatInVec.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _FLOATINVEC_H\n#define _FLOATINVEC_H\n\n#include <math.h>\n#include <xmmintrin.h>\n\nnamespace Vectormath {\n\nclass boolInVec;\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec class\n//\n\n_VECTORMATH_ALIGNED_TYPE_1 class floatInVec {\n\nprivate:\n\n        __m128 mData;\n\npublic:\n\n        inline floatInVec(__m128 vec);\n\n        inline floatInVec() {}\n\n        // matches standard type conversions\n        //\n        inline floatInVec(const boolInVec &vec);\n\n        // construct from a slot of __m128\n        //\n        inline floatInVec(__m128 vec, int slot);\n\n        // explicit cast from float\n        //\n        explicit inline floatInVec(float scalar);\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n        // explicit cast to float\n        //\n        inline float getAsFloat() const;\n#else\n        // implicit cast to float\n        //\n        inline operator float() const;\n#endif\n\n        // get vector data\n        // float value is splatted across all word slots of vector\n        //\n        inline __m128 get128() const;\n\n        // operators\n        //\n        inline const floatInVec operator ++ (int);\n        inline const floatInVec operator -- (int);\n        inline floatInVec& operator ++ ();\n        inline floatInVec& operator -- ();\n        inline const floatInVec operator - () const;\n        inline floatInVec& operator = (const floatInVec &vec);\n        inline floatInVec& operator *= (const floatInVec &vec);\n        inline floatInVec& operator /= (const floatInVec &vec);\n        inline floatInVec& operator += (const floatInVec &vec);\n        inline floatInVec& operator -= (const floatInVec &vec);\n\n        // friend functions\n        //\n        friend inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1);\n        friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1);\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec functions\n//\n\n// operators\n//\ninline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1);\ninline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1);\ninline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1);\ninline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1);\ninline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1);\ninline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1);\ninline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1);\ninline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1);\ninline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1);\ninline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1);\n\n// select between vec0 and vec1 using boolInVec.\n// false selects vec0, true selects vec1\n//\ninline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1);\n\n} // namespace Vectormath\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec implementation\n//\n\n#include \"boolInVec.h\"\n\nnamespace Vectormath {\n\ninline\nfloatInVec::floatInVec(__m128 vec)\n{\n    mData = vec;\n}\n\ninline\nfloatInVec::floatInVec(const boolInVec &vec)\n{\n\tmData = vec_sel(_mm_setzero_ps(), _mm_set1_ps(1.0f), vec.get128());\n}\n\ninline\nfloatInVec::floatInVec(__m128 vec, int slot)\n{\n\tSSEFloat v;\n\tv.m128 = vec;\n\tmData = _mm_set1_ps(v.f[slot]);\n}\n\ninline\nfloatInVec::floatInVec(float scalar)\n{\n\tmData = _mm_set1_ps(scalar);\n}\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline\nfloat\nfloatInVec::getAsFloat() const\n#else\ninline\nfloatInVec::operator float() const\n#endif\n{\n    return *((float *)&mData);\n}\n\ninline\n__m128\nfloatInVec::get128() const\n{\n    return mData;\n}\n\ninline\nconst floatInVec\nfloatInVec::operator ++ (int)\n{\n    __m128 olddata = mData;\n    operator ++();\n    return floatInVec(olddata);\n}\n\ninline\nconst floatInVec\nfloatInVec::operator -- (int)\n{\n    __m128 olddata = mData;\n    operator --();\n    return floatInVec(olddata);\n}\n\ninline\nfloatInVec&\nfloatInVec::operator ++ ()\n{\n    *this += floatInVec(_mm_set1_ps(1.0f));\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator -- ()\n{\n    *this -= floatInVec(_mm_set1_ps(1.0f));\n    return *this;\n}\n\ninline\nconst floatInVec\nfloatInVec::operator - () const\n{\n    return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData));\n}\n\ninline\nfloatInVec&\nfloatInVec::operator = (const floatInVec &vec)\n{\n    mData = vec.mData;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator *= (const floatInVec &vec)\n{\n    *this = *this * vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator /= (const floatInVec &vec)\n{\n    *this = *this / vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator += (const floatInVec &vec)\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator -= (const floatInVec &vec)\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline\nconst floatInVec\noperator * (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst floatInVec\noperator / (const floatInVec &num, const floatInVec &den)\n{\n    return floatInVec(_mm_div_ps(num.get128(), den.get128()));\n}\n\ninline\nconst floatInVec\noperator + (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst floatInVec\noperator - (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator < (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128()));\n}\n\ninline\nconst boolInVec\noperator <= (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128()));\n}\n\ninline\nconst boolInVec\noperator > (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator >= (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator == (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator != (const floatInVec &vec0, const floatInVec &vec1)\n{\n    return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst floatInVec\nselect(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1)\n{\n    return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));\n}\n\n} // namespace Vectormath\n\n#endif // floatInVec_h\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_CPP_H\n#define _VECTORMATH_MAT_AOS_CPP_H\n\n#include \"defines.h\"\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Constants\n// for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z })\n#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y })\n#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\ninline Matrix3::Matrix3( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n}\n\ninline Matrix3::Matrix3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( const floatInVec &scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( const Quat &unitQuat )\n{\n    __m128 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2;\n    __m128 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n\n\t_VECTORMATH_ALIGNED(unsigned int sx[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int sz[4]) = {0, 0, 0xffffffff, 0};\n\n\t__m128 select_x = _mm_load_ps((float *)sx);\n\t__m128 select_z = _mm_load_ps((float *)sz);\n\n    xyzw_2 = _mm_add_ps( unitQuat.get128(), unitQuat.get128() );\n    wwww = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,3,3,3) );\n\tyzxw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,0,2,1) );\n\tzxyw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,1,0,2) );\n    yzxw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,0,2,1) );\n    zxyw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,1,0,2) );\n\n    tmp0 = _mm_mul_ps( yzxw_2, wwww );\t\t\t\t\t\t\t\t\t// tmp0 = 2yw, 2zw, 2xw, 2w2\n\ttmp1 = _mm_sub_ps( _mm_set1_ps(1.0f), _mm_mul_ps(yzxw, yzxw_2) );\t// tmp1 = 1 - 2y2, 1 - 2z2, 1 - 2x2, 1 - 2w2\n    tmp2 = _mm_mul_ps( yzxw, xyzw_2 );\t\t\t\t\t\t\t\t\t// tmp2 = 2xy, 2yz, 2xz, 2w2\n    tmp0 = _mm_add_ps( _mm_mul_ps(zxyw, xyzw_2), tmp0 );\t\t\t\t// tmp0 = 2yw + 2zx, 2zw + 2xy, 2xw + 2yz, 2w2 + 2w2\n    tmp1 = _mm_sub_ps( tmp1, _mm_mul_ps(zxyw, zxyw_2) );\t\t\t\t// tmp1 = 1 - 2y2 - 2z2, 1 - 2z2 - 2x2, 1 - 2x2 - 2y2, 1 - 2w2 - 2w2\n    tmp2 = _mm_sub_ps( tmp2, _mm_mul_ps(zxyw_2, wwww) );\t\t\t\t// tmp2 = 2xy - 2zw, 2yz - 2xw, 2xz - 2yw, 2w2 -2w2\n\n    tmp3 = vec_sel( tmp0, tmp1, select_x );\n    tmp4 = vec_sel( tmp1, tmp2, select_x );\n    tmp5 = vec_sel( tmp2, tmp0, select_x );\n    mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) );\n    mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) );\n    mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) );\n}\n\ninline Matrix3::Matrix3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n}\n\ninline Matrix3 & Matrix3::setCol0( const Vector3 &_col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol1( const Vector3 &_col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol2( const Vector3 &_col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol( int col, const Vector3 &vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setRow( int row, const Vector3 &vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, const floatInVec &val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline const floatInVec Matrix3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Matrix3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Matrix3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Matrix3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Matrix3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::getRow( int row ) const\n{\n    return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) );\n}\n\ninline Vector3 & Matrix3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix3 & Matrix3::operator =( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    return *this;\n}\n\ninline const Matrix3 transpose( const Matrix3 & mat )\n{\n    __m128 tmp0, tmp1, res0, res1, res2;\n    tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() );\n    res0 = vec_mergeh( tmp0, mat.getCol1().get128() );\n    //res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX );\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\tres1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2));\n\tres1 = vec_sel(res1, mat.getCol1().get128(), select_y);\n    //res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX );\n\tres2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0));\n\tres2 = vec_sel(res2, vec_splat(mat.getCol1().get128(), 2), select_y);\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 inverse( const Matrix3 & mat )\n{\n    __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2;\n    tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() );\n    tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() );\n    tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() );\n    dot = _vmathVfDot3( tmp2, mat.getCol2().get128() );\n    dot = vec_splat( dot, 0 );\n    invdet = recipf4( dot );\n    tmp3 = vec_mergeh( tmp0, tmp2 );\n    tmp4 = vec_mergel( tmp0, tmp2 );\n    inv0 = vec_mergeh( tmp3, tmp1 );\n    //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX );\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\tinv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2));\n\tinv1 = vec_sel(inv1, tmp1, select_y);\n    //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX );\n\tinv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0));\n\tinv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y);\n    inv0 = vec_mul( inv0, invdet );\n    inv1 = vec_mul( inv1, invdet );\n\tinv2 = vec_mul( inv2, invdet );\n    return Matrix3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 )\n    );\n}\n\ninline const floatInVec determinant( const Matrix3 & mat )\n{\n    return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) );\n}\n\ninline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 )\n    );\n}\n\ninline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator +=( const Matrix3 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::operator -=( const Matrix3 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix3 Matrix3::operator -( ) const\n{\n    return Matrix3(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 )\n    );\n}\n\ninline const Matrix3 absPerElem( const Matrix3 & mat )\n{\n    return Matrix3(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Matrix3 Matrix3::operator *( const floatInVec &scalar ) const\n{\n    return Matrix3(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( float scalar )\n{\n    return *this *= floatInVec(scalar);\n}\n\ninline Matrix3 & Matrix3::operator *=( const floatInVec &scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix3 operator *( float scalar, const Matrix3 & mat )\n{\n    return floatInVec(scalar) * mat;\n}\n\ninline const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector3 Matrix3::operator *( const Vector3 &vec ) const\n{\n    __m128 res;\n    __m128 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec.get128(), 0 );\n    yyyy = vec_splat( vec.get128(), 1 );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_mul( mCol0.get128(), xxxx );\n    res = vec_madd( mCol1.get128(), yyyy, res );\n    res = vec_madd( mCol2.get128(), zzzz, res );\n    return Vector3( res );\n}\n\ninline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( const Matrix3 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 )\n{\n    return Matrix3(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::identity( )\n{\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Matrix3 Matrix3::rotationX( const floatInVec &radians )\n{\n    __m128 s, c, res1, res2;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Matrix3 Matrix3::rotationY( const floatInVec &radians )\n{\n    __m128 s, c, res0, res2;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3::yAxis( ),\n        Vector3( res2 )\n\t);\n}\n\ninline const Matrix3 Matrix3::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Matrix3 Matrix3::rotationZ( const floatInVec &radians )\n{\n    __m128 s, c, res0, res1;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3::zAxis( )\n\t);\n}\n\ninline const Matrix3 Matrix3::rotationZYX( const Vector3 &radiansXYZ )\n{\n    __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    angles = Vector4( radiansXYZ, 0.0f ).get128();\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n\t_VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0};\n    Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) );\n\tY0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) );\n\tY1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_mul( Z0, Y1 );\n    return Matrix3(\n        Vector3( vec_mul( Z0, Y0 ) ),\n        Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ),\n        Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( float radians, const Vector3 &unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Matrix3 Matrix3::rotation( const floatInVec &radians, const Vector3 &unitVec )\n{\n    __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2;\n    axis = unitVec.get128();\n    sincosf4( radians.get128(), &s, &c );\n    xxxx = vec_splat( axis, 0 );\n    yyyy = vec_splat( axis, 1 );\n    zzzz = vec_splat( axis, 2 );\n    oneMinusC = vec_sub( _mm_set1_ps(1.0f), c );\n    axisS = vec_mul( axis, s );\n    negAxisS = negatef4( axisS );\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX );\n\ttmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) );\n\ttmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z);\n    //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX );\n\ttmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x );\n    //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX );\n\ttmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) );\n\ttmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y);\n    tmp0 = vec_sel( tmp0, c, select_x );\n    tmp1 = vec_sel( tmp1, c, select_y );\n    tmp2 = vec_sel( tmp2, c, select_z );\n    return Matrix3(\n        Vector3( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ),\n        Vector3( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ),\n        Vector3( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( const Quat &unitQuat )\n{\n    return Matrix3( unitQuat );\n}\n\ninline const Matrix3 Matrix3::scale( const Vector3 &scaleVec )\n{\n    __m128 zero = _mm_setzero_ps();\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    return Matrix3(\n        Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), select_z ) )\n    );\n}\n\ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec )\n{\n    return Matrix3(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) )\n    );\n}\n\ninline const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat )\n{\n    return Matrix3(\n        mulPerElem( mat.getCol0(), scaleVec ),\n        mulPerElem( mat.getCol1(), scaleVec ),\n        mulPerElem( mat.getCol2(), scaleVec )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix3 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n}\n\ninline void print( const Matrix3 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Matrix4::Matrix4( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n}\n\ninline Matrix4::Matrix4( float scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const floatInVec &scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const Transform3 & mat )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( mat.getCol3(), 1.0f );\n}\n\ninline Matrix4::Matrix4( const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 &translateVec )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4::Matrix4( const Quat &unitQuat, const Vector3 &translateVec )\n{\n    Matrix3 mat;\n    mat = Matrix3( unitQuat );\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4 & Matrix4::setCol0( const Vector4 &_col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol1( const Vector4 &_col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol2( const Vector4 &_col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol3( const Vector4 &_col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol( int col, const Vector4 &vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setRow( int row, const Vector4 &vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, const floatInVec &val )\n{\n    Vector4 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline const floatInVec Matrix4::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector4 Matrix4::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector4 Matrix4::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector4 Matrix4::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector4 Matrix4::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector4 Matrix4::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector4 & Matrix4::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix4 & Matrix4::operator =( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n    return *this;\n}\n\ninline const Matrix4 transpose( const Matrix4 & mat )\n{\n    __m128 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3;\n    tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() );\n    tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() );\n    res0 = vec_mergeh( tmp0, tmp1 );\n    res1 = vec_mergel( tmp0, tmp1 );\n    res2 = vec_mergeh( tmp2, tmp3 );\n    res3 = vec_mergel( tmp2, tmp3 );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4( res1 ),\n        Vector4( res2 ),\n        Vector4( res3 )\n    );\n}\n\ninline const Matrix4 inverse( const Matrix4 & mat )\n{\n\tstatic _VECTORMATH_ALIGNED(const unsigned int _vmathPNPN[4]) = {0x00000000, 0x80000000, 0x00000000, 0x80000000};\n\tstatic _VECTORMATH_ALIGNED(const unsigned int _vmathNPNP[4]) = {0x80000000, 0x00000000, 0x80000000, 0x00000000};\n\tstatic _VECTORMATH_ALIGNED(const float _vmathZERONE[4]) = {1.0f, 0.0f, 0.0f, 1.0f};\n\n\t__m128 Va,Vb,Vc;\n\t__m128 r1,r2,r3,tt,tt2;\n\t__m128 sum,Det,RDet;\n\t__m128 trns0,trns1,trns2,trns3;\n\n\t__m128 _L1 = mat.getCol0().get128();\n\t__m128 _L2 = mat.getCol1().get128();\n\t__m128 _L3 = mat.getCol2().get128();\n\t__m128 _L4 = mat.getCol3().get128();\n\t// Calculating the minterms for the first line.\n\n\t// _mm_ror_ps is just a macro using _mm_shuffle_ps().\n\ttt = _L4; tt2 = _mm_ror_ps(_L3,1);\n\tVc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0));\t\t\t\t\t// V3'V4\n\tVa = _mm_mul_ps(tt2,_mm_ror_ps(tt,2));\t\t\t\t\t// V3'V4\"\n\tVb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3));\t\t\t\t\t// V3'V4^\n\n\tr1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2));\t\t// V3\"V4^ - V3^V4\"\n\tr2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0));\t\t// V3^V4' - V3'V4^\n\tr3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1));\t\t// V3'V4\" - V3\"V4'\n\n\ttt = _L2;\n\tVa = _mm_ror_ps(tt,1);\t\tsum = _mm_mul_ps(Va,r1);\n\tVb = _mm_ror_ps(tt,2);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));\n\tVc = _mm_ror_ps(tt,3);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));\n\n\t// Calculating the determinant.\n\tDet = _mm_mul_ps(sum,_L1);\n\tDet = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));\n\n\tconst __m128 Sign_PNPN = _mm_load_ps((float *)_vmathPNPN);\n\tconst __m128 Sign_NPNP = _mm_load_ps((float *)_vmathNPNP);\n\n\t__m128 mtL1 = _mm_xor_ps(sum,Sign_PNPN);\n\n\t// Calculating the minterms of the second line (using previous results).\n\ttt = _mm_ror_ps(_L1,1);\t\tsum = _mm_mul_ps(tt,r1);\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));\n\t__m128 mtL2 = _mm_xor_ps(sum,Sign_NPNP);\n\n\t// Testing the determinant.\n\tDet = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));\n\n\t// Calculating the minterms of the third line.\n\ttt = _mm_ror_ps(_L1,1);\n\tVa = _mm_mul_ps(tt,Vb);\t\t\t\t\t\t\t\t\t// V1'V2\"\n\tVb = _mm_mul_ps(tt,Vc);\t\t\t\t\t\t\t\t\t// V1'V2^\n\tVc = _mm_mul_ps(tt,_L2);\t\t\t\t\t\t\t\t// V1'V2\n\n\tr1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2));\t\t// V1\"V2^ - V1^V2\"\n\tr2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0));\t\t// V1^V2' - V1'V2^\n\tr3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1));\t\t// V1'V2\" - V1\"V2'\n\n\ttt = _mm_ror_ps(_L4,1);\t\tsum = _mm_mul_ps(tt,r1);\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));\n\t__m128 mtL3 = _mm_xor_ps(sum,Sign_PNPN);\n\n\t// Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs).\n\tRDet = _mm_div_ss(_mm_load_ss((float *)&_vmathZERONE), Det); // TODO: just 1.0f?\n\tRDet = _mm_shuffle_ps(RDet,RDet,0x00);\n\n\t// Devide the first 12 minterms with the determinant.\n\tmtL1 = _mm_mul_ps(mtL1, RDet);\n\tmtL2 = _mm_mul_ps(mtL2, RDet);\n\tmtL3 = _mm_mul_ps(mtL3, RDet);\n\n\t// Calculate the minterms of the forth line and devide by the determinant.\n\ttt = _mm_ror_ps(_L3,1);\t\tsum = _mm_mul_ps(tt,r1);\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));\n\t__m128 mtL4 = _mm_xor_ps(sum,Sign_NPNP);\n\tmtL4 = _mm_mul_ps(mtL4, RDet);\n\n\t// Now we just have to transpose the minterms matrix.\n\ttrns0 = _mm_unpacklo_ps(mtL1,mtL2);\n\ttrns1 = _mm_unpacklo_ps(mtL3,mtL4);\n\ttrns2 = _mm_unpackhi_ps(mtL1,mtL2);\n\ttrns3 = _mm_unpackhi_ps(mtL3,mtL4);\n\t_L1 = _mm_movelh_ps(trns0,trns1);\n\t_L2 = _mm_movehl_ps(trns1,trns0);\n\t_L3 = _mm_movelh_ps(trns2,trns3);\n\t_L4 = _mm_movehl_ps(trns3,trns2);\n\n    return Matrix4(\n        Vector4( _L1 ),\n        Vector4( _L2 ),\n        Vector4( _L3 ),\n        Vector4( _L4 )\n    );\n}\n\ninline const Matrix4 affineInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( inverse( affineMat ) );\n}\n\ninline const Matrix4 orthoInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( orthoInverse( affineMat ) );\n}\n\ninline const floatInVec determinant( const Matrix4 & mat )\n{\n\t__m128 Va,Vb,Vc;\n\t__m128 r1,r2,r3,tt,tt2;\n\t__m128 sum,Det;\n\n\t__m128 _L1 = mat.getCol0().get128();\n\t__m128 _L2 = mat.getCol1().get128();\n\t__m128 _L3 = mat.getCol2().get128();\n\t__m128 _L4 = mat.getCol3().get128();\n\t// Calculating the minterms for the first line.\n\n\t// _mm_ror_ps is just a macro using _mm_shuffle_ps().\n\ttt = _L4; tt2 = _mm_ror_ps(_L3,1);\n\tVc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0));\t\t\t\t\t// V3'V4\n\tVa = _mm_mul_ps(tt2,_mm_ror_ps(tt,2));\t\t\t\t\t// V3'V4\"\n\tVb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3));\t\t\t\t\t// V3'V4^\n\n\tr1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2));\t\t// V3\"V4^ - V3^V4\"\n\tr2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0));\t\t// V3^V4' - V3'V4^\n\tr3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1));\t\t// V3'V4\" - V3\"V4'\n\n\ttt = _L2;\n\tVa = _mm_ror_ps(tt,1);\t\tsum = _mm_mul_ps(Va,r1);\n\tVb = _mm_ror_ps(tt,2);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2));\n\tVc = _mm_ror_ps(tt,3);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3));\n\n\t// Calculating the determinant.\n\tDet = _mm_mul_ps(sum,_L1);\n\tDet = _mm_add_ps(Det,_mm_movehl_ps(Det,Det));\n\n\t// Calculating the minterms of the second line (using previous results).\n\ttt = _mm_ror_ps(_L1,1);\t\tsum = _mm_mul_ps(tt,r1);\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r2));\n\ttt = _mm_ror_ps(tt,1);\t\tsum = _mm_add_ps(sum,_mm_mul_ps(tt,r3));\n\n\t// Testing the determinant.\n\tDet = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1));\n\treturn floatInVec(Det, 0);\n}\n\ninline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 ),\n        ( mCol3 + mat.mCol3 )\n    );\n}\n\ninline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 ),\n        ( mCol3 - mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator +=( const Matrix4 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::operator -=( const Matrix4 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator -( ) const\n{\n    return Matrix4(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 ),\n        ( -mCol3 )\n    );\n}\n\ninline const Matrix4 absPerElem( const Matrix4 & mat )\n{\n    return Matrix4(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() ),\n        absPerElem( mat.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Matrix4 Matrix4::operator *( const floatInVec &scalar ) const\n{\n    return Matrix4(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar ),\n        ( mCol3 * scalar )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( float scalar )\n{\n    return *this *= floatInVec(scalar);\n}\n\ninline Matrix4 & Matrix4::operator *=( const floatInVec &scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix4 operator *( float scalar, const Matrix4 & mat )\n{\n    return floatInVec(scalar) * mat;\n}\n\ninline const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector4 Matrix4::operator *( const Vector4 &vec ) const\n{\n    return Vector4(\n\t\t_mm_add_ps(\n\t\t\t_mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))),\n\t\t\t_mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2))), _mm_mul_ps(mCol3.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(3,3,3,3)))))\n\t\t);\n}\n\ninline const Vector4 Matrix4::operator *( const Vector3 &vec ) const\n{\n    return Vector4(\n\t\t_mm_add_ps(\n\t\t\t_mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))),\n\t\t\t_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2))))\n\t\t);\n}\n\ninline const Vector4 Matrix4::operator *( const Point3 &pnt ) const\n{\n    return Vector4(\n\t\t_mm_add_ps(\n\t\t\t_mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(1,1,1,1)))),\n\t\t\t_mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(2,2,2,2))), mCol3.get128()))\n\t\t);\n}\n\ninline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 ),\n        ( *this * mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Matrix4 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const\n{\n    return Matrix4(\n        ( *this * tfrm.getCol0() ),\n        ( *this * tfrm.getCol1() ),\n        ( *this * tfrm.getCol2() ),\n        ( *this * Point3( tfrm.getCol3() ) )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 )\n{\n    return Matrix4(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() ),\n        mulPerElem( mat0.getCol3(), mat1.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::identity( )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 )\n{\n    mCol0.setXYZ( mat3.getCol0() );\n    mCol1.setXYZ( mat3.getCol1() );\n    mCol2.setXYZ( mat3.getCol2() );\n    return *this;\n}\n\ninline const Matrix3 Matrix4::getUpper3x3( ) const\n{\n    return Matrix3(\n        mCol0.getXYZ( ),\n        mCol1.getXYZ( ),\n        mCol2.getXYZ( )\n    );\n}\n\ninline Matrix4 & Matrix4::setTranslation( const Vector3 &translateVec )\n{\n    mCol3.setXYZ( translateVec );\n    return *this;\n}\n\ninline const Vector3 Matrix4::getTranslation( ) const\n{\n    return mCol3.getXYZ( );\n}\n\ninline const Matrix4 Matrix4::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Matrix4 Matrix4::rotationX( const floatInVec &radians )\n{\n    __m128 s, c, res1, res2;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4( res1 ),\n        Vector4( res2 ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Matrix4 Matrix4::rotationY( const floatInVec &radians )\n{\n    __m128 s, c, res0, res2;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4::yAxis( ),\n        Vector4( res2 ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Matrix4 Matrix4::rotationZ( const floatInVec &radians )\n{\n    __m128 s, c, res0, res1;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4( res1 ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZYX( const Vector3 &radiansXYZ )\n{\n    __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    angles = Vector4( radiansXYZ, 0.0f ).get128();\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n\t_VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0};\n    Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) );\n\tY0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) );\n\tY1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_mul( Z0, Y1 );\n    return Matrix4(\n        Vector4( vec_mul( Z0, Y0 ) ),\n        Vector4( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ),\n        Vector4( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( float radians, const Vector3 &unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Matrix4 Matrix4::rotation( const floatInVec &radians, const Vector3 &unitVec )\n{\n    __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2;\n    axis = unitVec.get128();\n    sincosf4( radians.get128(), &s, &c );\n    xxxx = vec_splat( axis, 0 );\n    yyyy = vec_splat( axis, 1 );\n    zzzz = vec_splat( axis, 2 );\n    oneMinusC = vec_sub( _mm_set1_ps(1.0f), c );\n    axisS = vec_mul( axis, s );\n    negAxisS = negatef4( axisS );\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX );\n\ttmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) );\n\ttmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z);\n    //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX );\n\ttmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x );\n    //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX );\n\ttmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) );\n\ttmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y);\n    tmp0 = vec_sel( tmp0, c, select_x );\n    tmp1 = vec_sel( tmp1, c, select_y );\n    tmp2 = vec_sel( tmp2, c, select_z );\n\t_VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0};\n    axis = vec_and( axis, _mm_load_ps( (float *)select_xyz ) );\n    tmp0 = vec_and( tmp0, _mm_load_ps( (float *)select_xyz ) );\n    tmp1 = vec_and( tmp1, _mm_load_ps( (float *)select_xyz ) );\n    tmp2 = vec_and( tmp2, _mm_load_ps( (float *)select_xyz ) );\n    return Matrix4(\n        Vector4( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ),\n        Vector4( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ),\n        Vector4( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( const Quat &unitQuat )\n{\n    return Matrix4( Transform3::rotation( unitQuat ) );\n}\n\ninline const Matrix4 Matrix4::scale( const Vector3 &scaleVec )\n{\n    __m128 zero = _mm_setzero_ps();\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    return Matrix4(\n        Vector4( vec_sel( zero, scaleVec.get128(), select_x ) ),\n        Vector4( vec_sel( zero, scaleVec.get128(), select_y ) ),\n        Vector4( vec_sel( zero, scaleVec.get128(), select_z ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec )\n{\n    return Matrix4(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) ),\n        mat.getCol3()\n    );\n}\n\ninline const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat )\n{\n    Vector4 scale4;\n    scale4 = Vector4( scaleVec, 1.0f );\n    return Matrix4(\n        mulPerElem( mat.getCol0(), scale4 ),\n        mulPerElem( mat.getCol1(), scale4 ),\n        mulPerElem( mat.getCol2(), scale4 ),\n        mulPerElem( mat.getCol3(), scale4 )\n    );\n}\n\ninline const Matrix4 Matrix4::translation( const Vector3 &translateVec )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4( translateVec, 1.0f )\n    );\n}\n\ninline const Matrix4 Matrix4::lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec )\n{\n    Matrix4 m4EyeFrame;\n    Vector3 v3X, v3Y, v3Z;\n    v3Y = normalize( upVec );\n    v3Z = normalize( ( eyePos - lookAtPos ) );\n    v3X = normalize( cross( v3Y, v3Z ) );\n    v3Y = cross( v3Z, v3X );\n    m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) );\n    return orthoInverse( m4EyeFrame );\n}\n\ninline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    __m128 zero, col0, col1, col2, col3;\n    union { __m128 v; float s[4]; } tmp;\n    f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f );\n    rangeInv = 1.0f / ( zNear - zFar );\n    zero = _mm_setzero_ps();\n    tmp.v = zero;\n    tmp.s[0] = f / aspect;\n    col0 = tmp.v;\n    tmp.v = zero;\n    tmp.s[1] = f;\n    col1 = tmp.v;\n    tmp.v = zero;\n    tmp.s[2] = ( zNear + zFar ) * rangeInv;\n    tmp.s[3] = -1.0f;\n    col2 = tmp.v;\n    tmp.v = zero;\n    tmp.s[2] = zNear * zFar * rangeInv * 2.0f;\n    col3 = tmp.v;\n    return Matrix4(\n        Vector4( col0 ),\n        Vector4( col1 ),\n        Vector4( col2 ),\n        Vector4( col3 )\n    );\n}\n\ninline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    __m128 lbf, rtn;\n    __m128 diff, sum, inv_diff;\n    __m128 diagonal, column, near2;\n    __m128 zero = _mm_setzero_ps();\n    union { __m128 v; float s[4]; } l, f, r, n, b, t; // TODO: Union?\n    l.s[0] = left;\n    f.s[0] = zFar;\n    r.s[0] = right;\n    n.s[0] = zNear;\n    b.s[0] = bottom;\n    t.s[0] = top;\n    lbf = vec_mergeh( l.v, f.v );\n    rtn = vec_mergeh( r.v, n.v );\n    lbf = vec_mergeh( lbf, b.v );\n    rtn = vec_mergeh( rtn, t.v );\n    diff = vec_sub( rtn, lbf );\n    sum  = vec_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    near2 = vec_splat( n.v, 0 );\n    near2 = vec_add( near2, near2 );\n    diagonal = vec_mul( near2, inv_diff );\n    column = vec_mul( sum, inv_diff );\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_w[4]) = {0, 0, 0, 0xffffffff};\n    return Matrix4(\n        Vector4( vec_sel( zero, diagonal, select_x ) ),\n        Vector4( vec_sel( zero, diagonal, select_y ) ),\n        Vector4( vec_sel( column, _mm_set1_ps(-1.0f), select_w ) ),\n        Vector4( vec_sel( zero, vec_mul( diagonal, vec_splat( f.v, 0 ) ), select_z ) )\n\t);\n}\n\ninline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    __m128 lbf, rtn;\n    __m128 diff, sum, inv_diff, neg_inv_diff;\n    __m128 diagonal, column;\n    __m128 zero = _mm_setzero_ps();\n    union { __m128 v; float s[4]; } l, f, r, n, b, t;\n    l.s[0] = left;\n    f.s[0] = zFar;\n    r.s[0] = right;\n    n.s[0] = zNear;\n    b.s[0] = bottom;\n    t.s[0] = top;\n    lbf = vec_mergeh( l.v, f.v );\n    rtn = vec_mergeh( r.v, n.v );\n    lbf = vec_mergeh( lbf, b.v );\n    rtn = vec_mergeh( rtn, t.v );\n    diff = vec_sub( rtn, lbf );\n    sum  = vec_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    neg_inv_diff = negatef4( inv_diff );\n    diagonal = vec_add( inv_diff, inv_diff );\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_w[4]) = {0, 0, 0, 0xffffffff};\n    column = vec_mul( sum, vec_sel( neg_inv_diff, inv_diff, select_z ) ); // TODO: no madds with zero\n    return Matrix4(\n        Vector4( vec_sel( zero, diagonal, select_x ) ),\n        Vector4( vec_sel( zero, diagonal, select_y ) ),\n        Vector4( vec_sel( zero, diagonal, select_z ) ),\n        Vector4( vec_sel( column, _mm_set1_ps(1.0f), select_w ) )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix4 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n    print( mat.getRow( 3 ) );\n}\n\ninline void print( const Matrix4 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Transform3::Transform3( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n}\n\ninline Transform3::Transform3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( const floatInVec &scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 &translateVec )\n{\n    this->setUpper3x3( tfrm );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( const Quat &unitQuat, const Vector3 &translateVec )\n{\n    this->setUpper3x3( Matrix3( unitQuat ) );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3 & Transform3::setCol0( const Vector3 &_col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol1( const Vector3 &_col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol2( const Vector3 &_col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol3( const Vector3 &_col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol( int col, const Vector3 &vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Transform3 & Transform3::setRow( int row, const Vector4 &vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, const floatInVec &val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline const floatInVec Transform3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Transform3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Transform3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Transform3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Transform3::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector3 Transform3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Transform3::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector3 & Transform3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Transform3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Transform3 & Transform3::operator =( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n    return *this;\n}\n\ninline const Transform3 inverse( const Transform3 & tfrm )\n{\n    __m128 inv0, inv1, inv2, inv3;\n    __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet;\n    __m128 xxxx, yyyy, zzzz;\n    tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() );\n    tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() );\n    tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() );\n    inv3 = negatef4( tfrm.getCol3().get128() );\n    dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() );\n    dot = vec_splat( dot, 0 );\n    invdet = recipf4( dot );\n    tmp3 = vec_mergeh( tmp0, tmp2 );\n    tmp4 = vec_mergel( tmp0, tmp2 );\n    inv0 = vec_mergeh( tmp3, tmp1 );\n    xxxx = vec_splat( inv3, 0 );\n    //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX );\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\tinv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2));\n\tinv1 = vec_sel(inv1, tmp1, select_y);\n    //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX );\n\tinv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0));\n\tinv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y);\n    yyyy = vec_splat( inv3, 1 );\n    zzzz = vec_splat( inv3, 2 );\n    inv3 = vec_mul( inv0, xxxx );\n    inv3 = vec_madd( inv1, yyyy, inv3 );\n    inv3 = vec_madd( inv2, zzzz, inv3 );\n    inv0 = vec_mul( inv0, invdet );\n    inv1 = vec_mul( inv1, invdet );\n    inv2 = vec_mul( inv2, invdet );\n    inv3 = vec_mul( inv3, invdet );\n    return Transform3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 ),\n        Vector3( inv3 )\n    );\n}\n\ninline const Transform3 orthoInverse( const Transform3 & tfrm )\n{\n    __m128 inv0, inv1, inv2, inv3;\n    __m128 tmp0, tmp1;\n    __m128 xxxx, yyyy, zzzz;\n    tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() );\n    tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() );\n    inv3 = negatef4( tfrm.getCol3().get128() );\n    inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() );\n    xxxx = vec_splat( inv3, 0 );\n    //inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX );\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\tinv1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2));\n\tinv1 = vec_sel(inv1, tfrm.getCol1().get128(), select_y);\n    //inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX );\n\tinv2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0));\n\tinv2 = vec_sel(inv2, vec_splat(tfrm.getCol1().get128(), 2), select_y);\n    yyyy = vec_splat( inv3, 1 );\n    zzzz = vec_splat( inv3, 2 );\n    inv3 = vec_mul( inv0, xxxx );\n    inv3 = vec_madd( inv1, yyyy, inv3 );\n    inv3 = vec_madd( inv2, zzzz, inv3 );\n    return Transform3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 ),\n        Vector3( inv3 )\n    );\n}\n\ninline const Transform3 absPerElem( const Transform3 & tfrm )\n{\n    return Transform3(\n        absPerElem( tfrm.getCol0() ),\n        absPerElem( tfrm.getCol1() ),\n        absPerElem( tfrm.getCol2() ),\n        absPerElem( tfrm.getCol3() )\n    );\n}\n\ninline const Vector3 Transform3::operator *( const Vector3 &vec ) const\n{\n    __m128 res;\n    __m128 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec.get128(), 0 );\n    yyyy = vec_splat( vec.get128(), 1 );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_mul( mCol0.get128(), xxxx );\n    res = vec_madd( mCol1.get128(), yyyy, res );\n    res = vec_madd( mCol2.get128(), zzzz, res );\n    return Vector3( res );\n}\n\ninline const Point3 Transform3::operator *( const Point3 &pnt ) const\n{\n    __m128 tmp0, tmp1, res;\n    __m128 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( pnt.get128(), 0 );\n    yyyy = vec_splat( pnt.get128(), 1 );\n    zzzz = vec_splat( pnt.get128(), 2 );\n    tmp0 = vec_mul( mCol0.get128(), xxxx );\n    tmp1 = vec_mul( mCol1.get128(), yyyy );\n    tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = vec_add( mCol3.get128(), tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    return Point3( res );\n}\n\ninline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const\n{\n    return Transform3(\n        ( *this * tfrm.mCol0 ),\n        ( *this * tfrm.mCol1 ),\n        ( *this * tfrm.mCol2 ),\n        Vector3( ( *this * Point3( tfrm.mCol3 ) ) )\n    );\n}\n\ninline Transform3 & Transform3::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 )\n{\n    return Transform3(\n        mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ),\n        mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ),\n        mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ),\n        mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() )\n    );\n}\n\ninline const Transform3 Transform3::identity( )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm )\n{\n    mCol0 = tfrm.getCol0();\n    mCol1 = tfrm.getCol1();\n    mCol2 = tfrm.getCol2();\n    return *this;\n}\n\ninline const Matrix3 Transform3::getUpper3x3( ) const\n{\n    return Matrix3( mCol0, mCol1, mCol2 );\n}\n\ninline Transform3 & Transform3::setTranslation( const Vector3 &translateVec )\n{\n    mCol3 = translateVec;\n    return *this;\n}\n\ninline const Vector3 Transform3::getTranslation( ) const\n{\n    return mCol3;\n}\n\ninline const Transform3 Transform3::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Transform3 Transform3::rotationX( const floatInVec &radians )\n{\n    __m128 s, c, res1, res2;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3( res1 ),\n        Vector3( res2 ),\n        Vector3( _mm_setzero_ps() )\n    );\n}\n\ninline const Transform3 Transform3::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Transform3 Transform3::rotationY( const floatInVec &radians )\n{\n    __m128 s, c, res0, res2;\n    __m128 zero;\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    return Transform3(\n        Vector3( res0 ),\n        Vector3::yAxis( ),\n        Vector3( res2 ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Transform3 Transform3::rotationZ( const floatInVec &radians )\n{\n    __m128 s, c, res0, res1;\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n    __m128 zero = _mm_setzero_ps();\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    return Transform3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZYX( const Vector3 &radiansXYZ )\n{\n    __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    angles = Vector4( radiansXYZ, 0.0f ).get128();\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n\t_VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0};\n    Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) );\n\tY0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) );\n\tY1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_mul( Z0, Y1 );\n    return Transform3(\n        Vector3( vec_mul( Z0, Y0 ) ),\n        Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ),\n        Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotation( float radians, const Vector3 &unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Transform3 Transform3::rotation( const floatInVec &radians, const Vector3 &unitVec )\n{\n    return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::rotation( const Quat &unitQuat )\n{\n    return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::scale( const Vector3 &scaleVec )\n{\n    __m128 zero = _mm_setzero_ps();\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    return Transform3(\n        Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec )\n{\n    return Transform3(\n        ( tfrm.getCol0() * scaleVec.getX( ) ),\n        ( tfrm.getCol1() * scaleVec.getY( ) ),\n        ( tfrm.getCol2() * scaleVec.getZ( ) ),\n        tfrm.getCol3()\n    );\n}\n\ninline const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm )\n{\n    return Transform3(\n        mulPerElem( tfrm.getCol0(), scaleVec ),\n        mulPerElem( tfrm.getCol1(), scaleVec ),\n        mulPerElem( tfrm.getCol2(), scaleVec ),\n        mulPerElem( tfrm.getCol3(), scaleVec )\n    );\n}\n\ninline const Transform3 Transform3::translation( const Vector3 &translateVec )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        translateVec\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Transform3 & tfrm )\n{\n    print( tfrm.getRow( 0 ) );\n    print( tfrm.getRow( 1 ) );\n    print( tfrm.getRow( 2 ) );\n}\n\ninline void print( const Transform3 & tfrm, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( tfrm );\n}\n\n#endif\n\ninline Quat::Quat( const Matrix3 & tfrm )\n{\n    __m128 res;\n    __m128 col0, col1, col2;\n    __m128 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff;\n    __m128 zy_xz_yx, yz_zx_xy, sum, diff;\n    __m128 radicand, invSqrt, scale;\n    __m128 res0, res1, res2, res3;\n    __m128 xx, yy, zz;\n\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_w[4]) = {0, 0, 0, 0xffffffff};\n\n    col0 = tfrm.getCol0().get128();\n    col1 = tfrm.getCol1().get128();\n    col2 = tfrm.getCol2().get128();\n\n    /* four cases: */\n    /* trace > 0 */\n    /* else */\n    /*    xx largest diagonal element */\n    /*    yy largest diagonal element */\n    /*    zz largest diagonal element */\n\n    /* compute quaternion for each case */\n\n    xx_yy = vec_sel( col0, col1, select_y );\n    //xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX );\n    //yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY );\n    //zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC );\n    xx_yy_zz_xx = _mm_shuffle_ps( xx_yy, xx_yy, _MM_SHUFFLE(0,0,1,0) );\n    xx_yy_zz_xx = vec_sel( xx_yy_zz_xx, col2, select_z ); // TODO: Ck\n    yy_zz_xx_yy = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1,0,2,1) );\n    zz_xx_yy_zz = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2,1,0,2) );\n\n    diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), _mm_set1_ps(1.0f) );\n \t//invSqrt = rsqrtf4( radicand );\n\tinvSqrt = newtonrapson_rsqrt4( radicand );\n\n    zy_xz_yx = vec_sel( col0, col1, select_z );\t\t\t\t\t\t\t\t\t// zy_xz_yx = 00 01 12 03\n    //zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX );\n\tzy_xz_yx = _mm_shuffle_ps( zy_xz_yx, zy_xz_yx, _MM_SHUFFLE(0,1,2,2) );\t\t// zy_xz_yx = 12 12 01 00\n    zy_xz_yx = vec_sel( zy_xz_yx, vec_splat(col2, 0), select_y );\t\t\t\t// zy_xz_yx = 12 20 01 00\n    yz_zx_xy = vec_sel( col0, col1, select_x );\t\t\t\t\t\t\t\t\t// yz_zx_xy = 10 01 02 03\n    //yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX );\n\tyz_zx_xy = _mm_shuffle_ps( yz_zx_xy, yz_zx_xy, _MM_SHUFFLE(0,0,2,0) );\t\t// yz_zx_xy = 10 02 10 10\n\tyz_zx_xy = vec_sel( yz_zx_xy, vec_splat(col2, 1), select_x );\t\t\t\t// yz_zx_xy = 21 02 10 10\n\n    sum = vec_add( zy_xz_yx, yz_zx_xy );\n    diff = vec_sub( zy_xz_yx, yz_zx_xy );\n\n    scale = vec_mul( invSqrt, _mm_set1_ps(0.5f) );\n\n    //res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA );\n\tres0 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,1,2,0) );\n\tres0 = vec_sel( res0, vec_splat(diff, 0), select_w );  // TODO: Ck\n    //res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB );\n\tres1 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,2) );\n\tres1 = vec_sel( res1, vec_splat(diff, 1), select_w );  // TODO: Ck\n    //res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC );\n\tres2 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,1) );\n\tres2 = vec_sel( res2, vec_splat(diff, 2), select_w );  // TODO: Ck\n    res3 = diff;\n    res0 = vec_sel( res0, radicand, select_x );\n    res1 = vec_sel( res1, radicand, select_y );\n    res2 = vec_sel( res2, radicand, select_z );\n    res3 = vec_sel( res3, radicand, select_w );\n    res0 = vec_mul( res0, vec_splat( scale, 0 ) );\n    res1 = vec_mul( res1, vec_splat( scale, 1 ) );\n    res2 = vec_mul( res2, vec_splat( scale, 2 ) );\n    res3 = vec_mul( res3, vec_splat( scale, 3 ) );\n\n    /* determine case and select answer */\n\n    xx = vec_splat( col0, 0 );\n    yy = vec_splat( col1, 1 );\n    zz = vec_splat( col2, 2 );\n    res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) );\n    res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) );\n    res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), _mm_setzero_ps() ) );\n    mVec128 = res;\n}\n\ninline const Matrix3 outer( const Vector3 &tfrm0, const Vector3 &tfrm1 )\n{\n    return Matrix3(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) )\n    );\n}\n\ninline const Matrix4 outer( const Vector4 &tfrm0, const Vector4 &tfrm1 )\n{\n    return Matrix4(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) ),\n        ( tfrm0 * tfrm1.getW( ) )\n    );\n}\n\ninline const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat )\n{\n    __m128 tmp0, tmp1, mcol0, mcol1, mcol2, res;\n    __m128 xxxx, yyyy, zzzz;\n    tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() );\n    xxxx = vec_splat( vec.get128(), 0 );\n    mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() );\n    //mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX );\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\tmcol1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2));\n\tmcol1 = vec_sel(mcol1, mat.getCol1().get128(), select_y);\n    //mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX );\n\tmcol2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0));\n\tmcol2 = vec_sel(mcol2, vec_splat(mat.getCol1().get128(), 2), select_y);\n    yyyy = vec_splat( vec.get128(), 1 );\n    res = vec_mul( mcol0, xxxx );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_madd( mcol1, yyyy, res );\n    res = vec_madd( mcol2, zzzz, res );\n    return Vector3( res );\n}\n\ninline const Matrix3 crossMatrix( const Vector3 &vec )\n{\n    __m128 neg, res0, res1, res2;\n    neg = negatef4( vec.get128() );\n\t_VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0};\n    //res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX );\n\tres0 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,2,2,0) );\n\tres0 = vec_sel(res0, vec_splat(neg, 1), select_z);\n    //res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX );\n\tres1 = vec_sel(vec_splat(vec.get128(), 0), vec_splat(neg, 2), select_x);\n    //res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX );\n\tres2 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,1,1) );\n\tres2 = vec_sel(res2, vec_splat(neg, 0), select_y);\n\t_VECTORMATH_ALIGNED(unsigned int filter_x[4]) = {0, 0xffffffff, 0xffffffff, 0xffffffff};\n\t_VECTORMATH_ALIGNED(unsigned int filter_y[4]) = {0xffffffff, 0, 0xffffffff, 0xffffffff};\n\t_VECTORMATH_ALIGNED(unsigned int filter_z[4]) = {0xffffffff, 0xffffffff, 0, 0xffffffff};\n    res0 = vec_and( res0, _mm_load_ps((float *)filter_x ) );\n    res1 = vec_and( res1, _mm_load_ps((float *)filter_y ) );\n    res2 = vec_and( res2, _mm_load_ps((float *)filter_z ) ); // TODO: Use selects?\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat )\n{\n    return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) );\n}\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_CPP_H\n#define _VECTORMATH_QUAT_AOS_CPP_H\n\n#include \"defines.h\"\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\ninline Quat::Quat( float _x, float _y, float _z, float _w )\n{\n    mVec128 = _mm_setr_ps(_x, _y, _z, _w);\n}\n\ninline Quat::Quat( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w )\n{\n\tmVec128 = _mm_unpacklo_ps(\n\t\t_mm_unpacklo_ps( _x.get128(), _z.get128() ),\n\t\t_mm_unpacklo_ps( _y.get128(), _w.get128() ) );\n}\n\ninline Quat::Quat( const Vector3 &xyz, float _w )\n{\n    mVec128 = xyz.get128();\n    _vmathVfSetElement(mVec128, _w, 3);\n}\n\ninline Quat::Quat( const Vector3 &xyz, const floatInVec &_w )\n{\n    mVec128 = xyz.get128();\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n}\n\ninline Quat::Quat( const Vector4 &vec )\n{\n    mVec128 = vec.get128();\n}\n\ninline Quat::Quat( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Quat::Quat( const floatInVec &scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Quat::Quat( __m128 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Quat Quat::identity( )\n{\n    return Quat( _VECTORMATH_UNIT_0001 );\n}\n\ninline const Quat lerp( float t, const Quat &quat0, const Quat &quat1 )\n{\n    return lerp( floatInVec(t), quat0, quat1 );\n}\n\ninline const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 )\n{\n    return ( quat0 + ( ( quat1 - quat0 ) * t ) );\n}\n\ninline const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 )\n{\n    return slerp( floatInVec(t), unitQuat0, unitQuat1 );\n}\n\ninline const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 )\n{\n    Quat start;\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() );\n    selectMask = (vec_uint4)vec_cmpgt( _mm_setzero_ps(), cosAngle );\n    cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) );\n    selectMask = (vec_uint4)vec_cmpgt( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = t.get128();\n    oneMinusT = vec_sub( _mm_set1_ps(1.0f), tttt );\n    angles = vec_mergeh( _mm_set1_ps(1.0f), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, _mm_setzero_ps() );\n    sines = sinf4( angles );\n    scales = _mm_div_ps( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    return Quat( vec_madd( start.get128(), scale0, vec_mul( unitQuat1.get128(), scale1 ) ) );\n}\n\ninline const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 )\n{\n    return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 );\n}\n\ninline const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 )\n{\n    return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), slerp( t, unitQuat0, unitQuat3 ), slerp( t, unitQuat1, unitQuat2 ) );\n}\n\ninline __m128 Quat::get128( ) const\n{\n    return mVec128;\n}\n\ninline Quat & Quat::operator =( const Quat &quat )\n{\n    mVec128 = quat.mVec128;\n    return *this;\n}\n\ninline Quat & Quat::setXYZ( const Vector3 &vec )\n{\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff};\n\tmVec128 = vec_sel( vec.get128(), mVec128, sw );\n    return *this;\n}\n\ninline const Vector3 Quat::getXYZ( ) const\n{\n    return Vector3( mVec128 );\n}\n\ninline Quat & Quat::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Quat & Quat::setX( const floatInVec &_x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Quat::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Quat & Quat::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Quat & Quat::setY( const floatInVec &_y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Quat::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Quat & Quat::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Quat & Quat::setZ( const floatInVec &_z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Quat::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Quat & Quat::setW( float _w )\n{\n    _vmathVfSetElement(mVec128, _w, 3);\n    return *this;\n}\n\ninline Quat & Quat::setW( const floatInVec &_w )\n{\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n    return *this;\n}\n\ninline const floatInVec Quat::getW( ) const\n{\n    return floatInVec( mVec128, 3 );\n}\n\ninline Quat & Quat::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Quat & Quat::setElem( int idx, const floatInVec &value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Quat::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Quat::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Quat::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Quat Quat::operator +( const Quat &quat ) const\n{\n    return Quat( _mm_add_ps( mVec128, quat.mVec128 ) );\n}\n\ninline const Quat Quat::operator -( const Quat &quat ) const\n{\n    return Quat( _mm_sub_ps( mVec128, quat.mVec128 ) );\n}\n\ninline const Quat Quat::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Quat Quat::operator *( const floatInVec &scalar ) const\n{\n    return Quat( _mm_mul_ps( mVec128, scalar.get128() ) );\n}\n\ninline Quat & Quat::operator +=( const Quat &quat )\n{\n    *this = *this + quat;\n    return *this;\n}\n\ninline Quat & Quat::operator -=( const Quat &quat )\n{\n    *this = *this - quat;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( const floatInVec &scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator /( float scalar ) const\n{\n    return *this / floatInVec(scalar);\n}\n\ninline const Quat Quat::operator /( const floatInVec &scalar ) const\n{\n    return Quat( _mm_div_ps( mVec128, scalar.get128() ) );\n}\n\ninline Quat & Quat::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline Quat & Quat::operator /=( const floatInVec &scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator -( ) const\n{\n\treturn Quat(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) );\n}\n\ninline const Quat operator *( float scalar, const Quat &quat )\n{\n    return floatInVec(scalar) * quat;\n}\n\ninline const Quat operator *( const floatInVec &scalar, const Quat &quat )\n{\n    return quat * scalar;\n}\n\ninline const floatInVec dot( const Quat &quat0, const Quat &quat1 )\n{\n    return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 );\n}\n\ninline const floatInVec norm( const Quat &quat )\n{\n    return floatInVec(  _vmathVfDot4( quat.get128(), quat.get128() ), 0 );\n}\n\ninline const floatInVec length( const Quat &quat )\n{\n    return floatInVec(  _mm_sqrt_ps(_vmathVfDot4( quat.get128(), quat.get128() )), 0 );\n}\n\ninline const Quat normalize( const Quat &quat )\n{\n    return Quat( _mm_mul_ps( quat.get128(), _mm_rsqrt_ps( _vmathVfDot4( quat.get128(), quat.get128() ) ) ) );\n}\n\ninline const Quat Quat::rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 )\n{\n    Vector3 crossVec;\n    __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res;\n    cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() );\n    cosAngleX2Plus2 = vec_madd( cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f) );\n    recipCosHalfAngleX2 = _mm_rsqrt_ps( cosAngleX2Plus2 );\n    cosHalfAngleX2 = vec_mul( recipCosHalfAngleX2, cosAngleX2Plus2 );\n    crossVec = cross( unitVec0, unitVec1 );\n    res = vec_mul( crossVec.get128(), recipCosHalfAngleX2 );\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff};\n    res = vec_sel( res, vec_mul( cosHalfAngleX2, _mm_set1_ps(0.5f) ), sw );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotation( float radians, const Vector3 &unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Quat Quat::rotation( const floatInVec &radians, const Vector3 &unitVec )\n{\n    __m128 s, c, angle, res;\n    angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) );\n    sincosf4( angle, &s, &c );\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff};\n    res = vec_sel( vec_mul( unitVec.get128(), s ), c, sw );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Quat Quat::rotationX( const floatInVec &radians )\n{\n    __m128 s, c, angle, res;\n    angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) );\n    sincosf4( angle, &s, &c );\n\t_VECTORMATH_ALIGNED(unsigned int xsw[4]) = {0xffffffff, 0, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int wsw[4]) = {0, 0, 0, 0xffffffff};\n    res = vec_sel( _mm_setzero_ps(), s, xsw );\n    res = vec_sel( res, c, wsw );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Quat Quat::rotationY( const floatInVec &radians )\n{\n    __m128 s, c, angle, res;\n    angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) );\n    sincosf4( angle, &s, &c );\n\t_VECTORMATH_ALIGNED(unsigned int ysw[4]) = {0, 0xffffffff, 0, 0};\n\t_VECTORMATH_ALIGNED(unsigned int wsw[4]) = {0, 0, 0, 0xffffffff};\n    res = vec_sel( _mm_setzero_ps(), s, ysw );\n    res = vec_sel( res, c, wsw );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Quat Quat::rotationZ( const floatInVec &radians )\n{\n    __m128 s, c, angle, res;\n    angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) );\n    sincosf4( angle, &s, &c );\n\t_VECTORMATH_ALIGNED(unsigned int zsw[4]) = {0, 0, 0xffffffff, 0};\n\t_VECTORMATH_ALIGNED(unsigned int wsw[4]) = {0, 0, 0, 0xffffffff};\n    res = vec_sel( _mm_setzero_ps(), s, zsw );\n    res = vec_sel( res, c, wsw );\n    return Quat( res );\n}\n\ninline const Quat Quat::operator *( const Quat &quat ) const\n{\n    __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;\n    __m128 product, l_wxyz, r_wxyz, xy, qw;\n    ldata = mVec128;\n    rdata = quat.mVec128;\n    tmp0 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,0,2,1) );\n    tmp1 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,1,0,2) );\n    tmp2 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,1,0,2) );\n    tmp3 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,0,2,1) );\n    qv = vec_mul( vec_splat( ldata, 3 ), rdata );\n    qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv );\n    qv = vec_madd( tmp0, tmp1, qv );\n    qv = vec_nmsub( tmp2, tmp3, qv );\n    product = vec_mul( ldata, rdata );\n    l_wxyz = vec_sld( ldata, ldata, 12 );\n    r_wxyz = vec_sld( rdata, rdata, 12 );\n    qw = vec_nmsub( l_wxyz, r_wxyz, product );\n    xy = vec_madd( l_wxyz, r_wxyz, product );\n    qw = vec_sub( qw, vec_sld( xy, xy, 8 ) );\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff};\n    return Quat( vec_sel( qv, qw, sw ) );\n}\n\ninline Quat & Quat::operator *=( const Quat &quat )\n{\n    *this = *this * quat;\n    return *this;\n}\n\ninline const Vector3 rotate( const Quat &quat, const Vector3 &vec )\n{    __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res;\n    qdata = quat.get128();\n    vdata = vec.get128();\n    tmp0 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,0,2,1) );\n    tmp1 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,1,0,2) );\n    tmp2 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,1,0,2) );\n    tmp3 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,0,2,1) );\n    wwww = vec_splat( qdata, 3 );\n    qv = vec_mul( wwww, vdata );\n    qv = vec_madd( tmp0, tmp1, qv );\n    qv = vec_nmsub( tmp2, tmp3, qv );\n    product = vec_mul( qdata, vdata );\n    qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product );\n    qw = vec_add( vec_sld( product, product, 8 ), qw );\n    tmp1 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,1,0,2) );\n    tmp3 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,0,2,1) );\n    res = vec_mul( vec_splat( qw, 0 ), qdata );\n    res = vec_madd( wwww, qv, res );\n    res = vec_madd( tmp0, tmp1, res );\n    res = vec_nmsub( tmp2, tmp3, res );\n    return Vector3( res );\n}\n\ninline const Quat conj( const Quat &quat )\n{\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0x80000000,0x80000000,0x80000000,0};\n    return Quat( vec_xor( quat.get128(), _mm_load_ps((float *)sw) ) );\n}\n\ninline const Quat select( const Quat &quat0, const Quat &quat1, bool select1 )\n{\n    return select( quat0, quat1, boolInVec(select1) );\n}\n\ninline const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 )\n{\n    return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Quat &quat )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = quat.get128();\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\ninline void print( const Quat &quat, const char * name )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = quat.get128();\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_CPP_H\n#define _VECTORMATH_VEC_AOS_CPP_H\n\n#include \"defines.h\"\n\n//-----------------------------------------------------------------------------\n// Constants\n// for permutes words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A }\n#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }\n#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C }\n#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W }\n#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 }\n#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 }\n#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 }\n#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff }\n#define _VECTORMATH_UNIT_1000 _mm_setr_ps(1.0f,0.0f,0.0f,0.0f) // (__m128){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 _mm_setr_ps(0.0f,1.0f,0.0f,0.0f) // (__m128){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 _mm_setr_ps(0.0f,0.0f,1.0f,0.0f) // (__m128){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 _mm_setr_ps(0.0f,0.0f,0.0f,1.0f) // (__m128){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\nstatic inline __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 )\n{\n    __m128 result = _mm_mul_ps( vec0, vec1);\n    return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) );\n}\n\nstatic inline __m128 _vmathVfDot4( __m128 vec0, __m128 vec1 )\n{\n    __m128 result = _mm_mul_ps(vec0, vec1);\n\treturn _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(0,0,0,0)),\n\t\t\t_mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(1,1,1,1)),\n\t\t\t_mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(2,2,2,2)), _mm_shuffle_ps(result, result, _MM_SHUFFLE(3,3,3,3)))));\n}\n\nstatic inline __m128 _vmathVfCross( __m128 vec0, __m128 vec1 )\n{\n    __m128 tmp0, tmp1, tmp2, tmp3, result;\n    tmp0 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,0,2,1) );\n    tmp1 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,1,0,2) );\n    tmp2 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,1,0,2) );\n    tmp3 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,0,2,1) );\n    result = vec_mul( tmp0, tmp1 );\n    result = vec_nmsub( tmp2, tmp3, result );\n    return result;\n}\n\nstatic inline __m128 _vmathVfInsert(__m128 dst, __m128 src, int slot)\n{\n\tSSEFloat s;\n\ts.m128 = src;\n\tSSEFloat d;\n\td.m128 = dst;\n\td.f[slot] = s.f[slot];\n\treturn d.m128;\n}\n\n#define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar\n\nstatic inline __m128 _vmathVfSplatScalar(float scalar)\n{\n\treturn _mm_set1_ps(scalar);\n}\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline VecIdx::operator floatInVec() const\n{\n    return floatInVec(ref, i);\n}\n\ninline float VecIdx::getAsFloat() const\n#else\ninline VecIdx::operator float() const\n#endif\n{\n    return ((float *)&ref)[i];\n}\n\ninline float VecIdx::operator =( float scalar )\n{\n    _vmathVfSetElement(ref, scalar, i);\n    return scalar;\n}\n\ninline floatInVec VecIdx::operator =( const floatInVec &scalar )\n{\n    ref = _vmathVfInsert(ref, scalar.get128(), i);\n    return scalar;\n}\n\ninline floatInVec VecIdx::operator =( const VecIdx& scalar )\n{\n    return *this = floatInVec(scalar.ref, scalar.i);\n}\n\ninline floatInVec VecIdx::operator *=( float scalar )\n{\n    return *this *= floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator *=( const floatInVec &scalar )\n{\n    return *this = floatInVec(ref, i) * scalar;\n}\n\ninline floatInVec VecIdx::operator /=( float scalar )\n{\n    return *this /= floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator /=( const floatInVec &scalar )\n{\n    return *this = floatInVec(ref, i) / scalar;\n}\n\ninline floatInVec VecIdx::operator +=( float scalar )\n{\n    return *this += floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator +=( const floatInVec &scalar )\n{\n    return *this = floatInVec(ref, i) + scalar;\n}\n\ninline floatInVec VecIdx::operator -=( float scalar )\n{\n    return *this -= floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator -=( const floatInVec &scalar )\n{\n    return *this = floatInVec(ref, i) - scalar;\n}\n\ninline Vector3::Vector3( float _x, float _y, float _z )\n{\n    mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f);\n}\n\ninline Vector3::Vector3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z )\n{\n\t__m128 xz = _mm_unpacklo_ps( _x.get128(), _z.get128() );\n\tmVec128 = _mm_unpacklo_ps( xz, _y.get128() );\n}\n\ninline Vector3::Vector3( const Point3 &pnt )\n{\n    mVec128 = pnt.get128();\n}\n\ninline Vector3::Vector3( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Vector3::Vector3( const floatInVec &scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Vector3::Vector3( __m128 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Vector3 Vector3::xAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_1000 );\n}\n\ninline const Vector3 Vector3::yAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_0100 );\n}\n\ninline const Vector3 Vector3::zAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_0010 );\n}\n\ninline const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return lerp( floatInVec(t), vec0, vec1 );\n}\n\ninline const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 )\n{\n    return slerp( floatInVec(t), unitVec0, unitVec1 );\n}\n\ninline const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 )\n{\n    __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() );\n    __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = t.get128();\n    oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt );\n    angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t\n    angles = _mm_unpacklo_ps( angles, oneMinusT );       // angles = 1, 1-t, t, 1-t\n    angles = _mm_mul_ps( angles, angle );\n    sines = sinf4( angles );\n    scales = _mm_div_ps( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    return Vector3( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) );\n}\n\ninline __m128 Vector3::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeXYZ( const Vector3 &vec, __m128 * quad )\n{\n    __m128 dstVec = *quad;\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; // TODO: Centralize\n    dstVec = vec_sel(vec.get128(), dstVec, sw);\n    *quad = dstVec;\n}\n\ninline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads )\n{\n\tconst float *quads = (float *)threeQuads;\n    vec0 = Vector3(  _mm_load_ps(quads) );\n    vec1 = Vector3( _mm_loadu_ps(quads + 3) );\n    vec2 = Vector3( _mm_loadu_ps(quads + 6) );\n    vec3 = Vector3( _mm_loadu_ps(quads + 9) );\n}\n\ninline void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads )\n{\n\t__m128 xxxx = _mm_shuffle_ps( vec1.get128(), vec1.get128(), _MM_SHUFFLE(0, 0, 0, 0) );\n\t__m128 zzzz = _mm_shuffle_ps( vec2.get128(), vec2.get128(), _MM_SHUFFLE(2, 2, 2, 2) );\n\t_VECTORMATH_ALIGNED(unsigned int xsw[4]) = {0, 0, 0, 0xffffffff};\n\t_VECTORMATH_ALIGNED(unsigned int zsw[4]) = {0xffffffff, 0, 0, 0};\n\tthreeQuads[0] = vec_sel( vec0.get128(), xxxx, xsw );\n    threeQuads[1] = _mm_shuffle_ps( vec1.get128(), vec2.get128(), _MM_SHUFFLE(1, 0, 2, 1) );\n    threeQuads[2] = vec_sel( _mm_shuffle_ps( vec3.get128(), vec3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw );\n}\n\ninline Vector3 & Vector3::operator =( const Vector3 &vec )\n{\n    mVec128 = vec.mVec128;\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( const floatInVec &_x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Vector3::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Vector3 & Vector3::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Vector3 & Vector3::setY( const floatInVec &_y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Vector3::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Vector3 & Vector3::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Vector3 & Vector3::setZ( const floatInVec &_z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Vector3::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Vector3 & Vector3::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Vector3 & Vector3::setElem( int idx, const floatInVec &value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Vector3::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Vector3::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Vector3::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Vector3 Vector3::operator +( const Vector3 &vec ) const\n{\n    return Vector3( _mm_add_ps( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector3 Vector3::operator -( const Vector3 &vec ) const\n{\n    return Vector3( _mm_sub_ps( mVec128, vec.mVec128 ) );\n}\n\ninline const Point3 Vector3::operator +( const Point3 &pnt ) const\n{\n    return Point3( _mm_add_ps( mVec128, pnt.get128() ) );\n}\n\ninline const Vector3 Vector3::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Vector3 Vector3::operator *( const floatInVec &scalar ) const\n{\n    return Vector3( _mm_mul_ps( mVec128, scalar.get128() ) );\n}\n\ninline Vector3 & Vector3::operator +=( const Vector3 &vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator -=( const Vector3 &vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( const floatInVec &scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator /( float scalar ) const\n{\n    return *this / floatInVec(scalar);\n}\n\ninline const Vector3 Vector3::operator /( const floatInVec &scalar ) const\n{\n    return Vector3( _mm_div_ps( mVec128, scalar.get128() ) );\n}\n\ninline Vector3 & Vector3::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator /=( const floatInVec &scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator -( ) const\n{\n\treturn Vector3(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) );\n}\n\ninline const Vector3 operator *( float scalar, const Vector3 &vec )\n{\n    return floatInVec(scalar) * vec;\n}\n\ninline const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return Vector3( _mm_mul_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return Vector3( _mm_div_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 recipPerElem( const Vector3 &vec )\n{\n    return Vector3( _mm_rcp_ps( vec.get128() ) );\n}\n\ninline const Vector3 absPerElem( const Vector3 &vec )\n{\n    return Vector3( fabsf4( vec.get128() ) );\n}\n\ninline const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 )\n{\n\t__m128 vmask = toM128(0x7fffffff);\n\treturn Vector3( _mm_or_ps(\n\t\t_mm_and_ps   ( vmask, vec0.get128() ),\t\t\t// Value\n\t\t_mm_andnot_ps( vmask, vec1.get128() ) ) );\t\t// Signs\n}\n\ninline const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return Vector3( _mm_max_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec maxElem( const Vector3 &vec )\n{\n    return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) );\n}\n\ninline const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return Vector3( _mm_min_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec minElem( const Vector3 &vec )\n{\n    return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) );\n}\n\ninline const floatInVec sum( const Vector3 &vec )\n{\n    return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) );\n}\n\ninline const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 );\n}\n\ninline const floatInVec lengthSqr( const Vector3 &vec )\n{\n    return floatInVec(  _vmathVfDot3( vec.get128(), vec.get128() ), 0 );\n}\n\ninline const floatInVec length( const Vector3 &vec )\n{\n    return floatInVec(  _mm_sqrt_ps(_vmathVfDot3( vec.get128(), vec.get128() )), 0 );\n}\n\ninline const Vector3 normalizeApprox( const Vector3 &vec )\n{\n    return Vector3( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) );\n}\n\ninline const Vector3 normalize( const Vector3 &vec )\n{\n\treturn Vector3( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) );\n}\n\ninline const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 )\n{\n    return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 )\n{\n    return select( vec0, vec1, boolInVec(select1) );\n}\n\ninline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 )\n{\n\treturn Vector3(vec_sel( vec0.get128(), vec1.get128(), select1.get128() ));\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector3 &vec )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\ninline void print( const Vector3 &vec, const char * name )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\ninline Vector4::Vector4( float _x, float _y, float _z, float _w )\n{\n    mVec128 = _mm_setr_ps(_x, _y, _z, _w);\n}\n\ninline Vector4::Vector4( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w )\n{\n\tmVec128 = _mm_unpacklo_ps(\n\t\t_mm_unpacklo_ps( _x.get128(), _z.get128() ),\n\t\t_mm_unpacklo_ps( _y.get128(), _w.get128() ) );\n}\n\ninline Vector4::Vector4( const Vector3 &xyz, float _w )\n{\n    mVec128 = xyz.get128();\n    _vmathVfSetElement(mVec128, _w, 3);\n}\n\ninline Vector4::Vector4( const Vector3 &xyz, const floatInVec &_w )\n{\n    mVec128 = xyz.get128();\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n}\n\ninline Vector4::Vector4( const Vector3 &vec )\n{\n    mVec128 = vec.get128();\n    mVec128 = _vmathVfInsert(mVec128, _mm_setzero_ps(), 3);\n}\n\ninline Vector4::Vector4( const Point3 &pnt )\n{\n    mVec128 = pnt.get128();\n    mVec128 = _vmathVfInsert(mVec128, _mm_set1_ps(1.0f), 3);\n}\n\ninline Vector4::Vector4( const Quat &quat )\n{\n    mVec128 = quat.get128();\n}\n\ninline Vector4::Vector4( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Vector4::Vector4( const floatInVec &scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Vector4::Vector4( __m128 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Vector4 Vector4::xAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_1000 );\n}\n\ninline const Vector4 Vector4::yAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0100 );\n}\n\ninline const Vector4 Vector4::zAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0010 );\n}\n\ninline const Vector4 Vector4::wAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0001 );\n}\n\ninline const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return lerp( floatInVec(t), vec0, vec1 );\n}\n\ninline const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 )\n{\n    return slerp( floatInVec(t), unitVec0, unitVec1 );\n}\n\ninline const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 )\n{\n    __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() );\n    __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = t.get128();\n    oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt );\n    angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t\n    angles = _mm_unpacklo_ps( angles, oneMinusT );       // angles = 1, 1-t, t, 1-t\n    angles = _mm_mul_ps( angles, angle );\n    sines = sinf4( angles );\n    scales = _mm_div_ps( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    return Vector4( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) );\n}\n\ninline __m128 Vector4::get128( ) const\n{\n    return mVec128;\n}\n\ninline Vector4 & Vector4::operator =( const Vector4 &vec )\n{\n    mVec128 = vec.mVec128;\n    return *this;\n}\n\ninline Vector4 & Vector4::setXYZ( const Vector3 &vec )\n{\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff};\n\tmVec128 = vec_sel( vec.get128(), mVec128, sw );\n    return *this;\n}\n\ninline const Vector3 Vector4::getXYZ( ) const\n{\n    return Vector3( mVec128 );\n}\n\ninline Vector4 & Vector4::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Vector4 & Vector4::setX( const floatInVec &_x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Vector4::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Vector4 & Vector4::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Vector4 & Vector4::setY( const floatInVec &_y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Vector4::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Vector4 & Vector4::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Vector4 & Vector4::setZ( const floatInVec &_z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Vector4::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Vector4 & Vector4::setW( float _w )\n{\n    _vmathVfSetElement(mVec128, _w, 3);\n    return *this;\n}\n\ninline Vector4 & Vector4::setW( const floatInVec &_w )\n{\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n    return *this;\n}\n\ninline const floatInVec Vector4::getW( ) const\n{\n    return floatInVec( mVec128, 3 );\n}\n\ninline Vector4 & Vector4::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Vector4 & Vector4::setElem( int idx, const floatInVec &value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Vector4::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Vector4::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Vector4::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Vector4 Vector4::operator +( const Vector4 &vec ) const\n{\n    return Vector4( _mm_add_ps( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector4 Vector4::operator -( const Vector4 &vec ) const\n{\n    return Vector4( _mm_sub_ps( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector4 Vector4::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Vector4 Vector4::operator *( const floatInVec &scalar ) const\n{\n    return Vector4( _mm_mul_ps( mVec128, scalar.get128() ) );\n}\n\ninline Vector4 & Vector4::operator +=( const Vector4 &vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator -=( const Vector4 &vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( const floatInVec &scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator /( float scalar ) const\n{\n    return *this / floatInVec(scalar);\n}\n\ninline const Vector4 Vector4::operator /( const floatInVec &scalar ) const\n{\n    return Vector4( _mm_div_ps( mVec128, scalar.get128() ) );\n}\n\ninline Vector4 & Vector4::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator /=( const floatInVec &scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator -( ) const\n{\n\treturn Vector4(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) );\n}\n\ninline const Vector4 operator *( float scalar, const Vector4 &vec )\n{\n    return floatInVec(scalar) * vec;\n}\n\ninline const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return Vector4( _mm_mul_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return Vector4( _mm_div_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 recipPerElem( const Vector4 &vec )\n{\n    return Vector4( _mm_rcp_ps( vec.get128() ) );\n}\n\ninline const Vector4 absPerElem( const Vector4 &vec )\n{\n    return Vector4( fabsf4( vec.get128() ) );\n}\n\ninline const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 )\n{\n\t__m128 vmask = toM128(0x7fffffff);\n\treturn Vector4( _mm_or_ps(\n\t\t_mm_and_ps   ( vmask, vec0.get128() ),\t\t\t// Value\n\t\t_mm_andnot_ps( vmask, vec1.get128() ) ) );\t\t// Signs\n}\n\ninline const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return Vector4( _mm_max_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec maxElem( const Vector4 &vec )\n{\n    return floatInVec( _mm_max_ps(\n\t\t_mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ),\n\t\t_mm_max_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) );\n}\n\ninline const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return Vector4( _mm_min_ps( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec minElem( const Vector4 &vec )\n{\n    return floatInVec( _mm_min_ps(\n\t\t_mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ),\n\t\t_mm_min_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) );\n}\n\ninline const floatInVec sum( const Vector4 &vec )\n{\n    return floatInVec( _mm_add_ps(\n\t\t_mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ),\n\t\t_mm_add_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) );\n}\n\ninline const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 )\n{\n    return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 );\n}\n\ninline const floatInVec lengthSqr( const Vector4 &vec )\n{\n    return floatInVec(  _vmathVfDot4( vec.get128(), vec.get128() ), 0 );\n}\n\ninline const floatInVec length( const Vector4 &vec )\n{\n    return floatInVec(  _mm_sqrt_ps(_vmathVfDot4( vec.get128(), vec.get128() )), 0 );\n}\n\ninline const Vector4 normalizeApprox( const Vector4 &vec )\n{\n    return Vector4( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) );\n}\n\ninline const Vector4 normalize( const Vector4 &vec )\n{\n    return Vector4( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) );\n}\n\ninline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 )\n{\n    return select( vec0, vec1, boolInVec(select1) );\n}\n\ninline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 )\n{\n    return Vector4( vec_sel( vec0.get128(), vec1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector4 &vec )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\ninline void print( const Vector4 &vec, const char * name )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\ninline Point3::Point3( float _x, float _y, float _z )\n{\n    mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f);\n}\n\ninline Point3::Point3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z )\n{\n\tmVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _y.get128() );\n}\n\ninline Point3::Point3( const Vector3 &vec )\n{\n    mVec128 = vec.get128();\n}\n\ninline Point3::Point3( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Point3::Point3( const floatInVec &scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Point3::Point3( __m128 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return lerp( floatInVec(t), pnt0, pnt1 );\n}\n\ninline const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) );\n}\n\ninline __m128 Point3::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeXYZ( const Point3 &pnt, __m128 * quad )\n{\n    __m128 dstVec = *quad;\n\t_VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; // TODO: Centralize\n    dstVec = vec_sel(pnt.get128(), dstVec, sw);\n    *quad = dstVec;\n}\n\ninline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads )\n{\n\tconst float *quads = (float *)threeQuads;\n    pnt0 = Point3(  _mm_load_ps(quads) );\n    pnt1 = Point3( _mm_loadu_ps(quads + 3) );\n    pnt2 = Point3( _mm_loadu_ps(quads + 6) );\n    pnt3 = Point3( _mm_loadu_ps(quads + 9) );\n}\n\ninline void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads )\n{\n\t__m128 xxxx = _mm_shuffle_ps( pnt1.get128(), pnt1.get128(), _MM_SHUFFLE(0, 0, 0, 0) );\n\t__m128 zzzz = _mm_shuffle_ps( pnt2.get128(), pnt2.get128(), _MM_SHUFFLE(2, 2, 2, 2) );\n\t_VECTORMATH_ALIGNED(unsigned int xsw[4]) = {0, 0, 0, 0xffffffff};\n\t_VECTORMATH_ALIGNED(unsigned int zsw[4]) = {0xffffffff, 0, 0, 0};\n\tthreeQuads[0] = vec_sel( pnt0.get128(), xxxx, xsw );\n    threeQuads[1] = _mm_shuffle_ps( pnt1.get128(), pnt2.get128(), _MM_SHUFFLE(1, 0, 2, 1) );\n    threeQuads[2] = vec_sel( _mm_shuffle_ps( pnt3.get128(), pnt3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw );\n}\n\ninline Point3 & Point3::operator =( const Point3 &pnt )\n{\n    mVec128 = pnt.mVec128;\n    return *this;\n}\n\ninline Point3 & Point3::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Point3 & Point3::setX( const floatInVec &_x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Point3::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Point3 & Point3::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Point3 & Point3::setY( const floatInVec &_y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Point3::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Point3 & Point3::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Point3 & Point3::setZ( const floatInVec &_z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Point3::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Point3 & Point3::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Point3 & Point3::setElem( int idx, const floatInVec &value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Point3::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Point3::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Point3::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Vector3 Point3::operator -( const Point3 &pnt ) const\n{\n    return Vector3( _mm_sub_ps( mVec128, pnt.mVec128 ) );\n}\n\ninline const Point3 Point3::operator +( const Vector3 &vec ) const\n{\n    return Point3( _mm_add_ps( mVec128, vec.get128() ) );\n}\n\ninline const Point3 Point3::operator -( const Vector3 &vec ) const\n{\n    return Point3( _mm_sub_ps( mVec128, vec.get128() ) );\n}\n\ninline Point3 & Point3::operator +=( const Vector3 &vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Point3 & Point3::operator -=( const Vector3 &vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return Point3( _mm_mul_ps( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return Point3( _mm_div_ps( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 recipPerElem( const Point3 &pnt )\n{\n    return Point3( _mm_rcp_ps( pnt.get128() ) );\n}\n\ninline const Point3 absPerElem( const Point3 &pnt )\n{\n    return Point3( fabsf4( pnt.get128() ) );\n}\n\ninline const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 )\n{\n\t__m128 vmask = toM128(0x7fffffff);\n\treturn Point3( _mm_or_ps(\n\t\t_mm_and_ps   ( vmask, pnt0.get128() ),\t\t\t// Value\n\t\t_mm_andnot_ps( vmask, pnt1.get128() ) ) );\t\t// Signs\n}\n\ninline const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return Point3( _mm_max_ps( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const floatInVec maxElem( const Point3 &pnt )\n{\n    return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) );\n}\n\ninline const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return Point3( _mm_min_ps( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const floatInVec minElem( const Point3 &pnt )\n{\n    return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) );\n}\n\ninline const floatInVec sum( const Point3 &pnt )\n{\n    return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) );\n}\n\ninline const Point3 scale( const Point3 &pnt, float scaleVal )\n{\n    return scale( pnt, floatInVec( scaleVal ) );\n}\n\ninline const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal )\n{\n    return mulPerElem( pnt, Point3( scaleVal ) );\n}\n\ninline const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec )\n{\n    return mulPerElem( pnt, Point3( scaleVec ) );\n}\n\ninline const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec )\n{\n    return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 );\n}\n\ninline const floatInVec distSqrFromOrigin( const Point3 &pnt )\n{\n    return lengthSqr( Vector3( pnt ) );\n}\n\ninline const floatInVec distFromOrigin( const Point3 &pnt )\n{\n    return length( Vector3( pnt ) );\n}\n\ninline const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return lengthSqr( ( pnt1 - pnt0 ) );\n}\n\ninline const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 )\n{\n    return length( ( pnt1 - pnt0 ) );\n}\n\ninline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 )\n{\n    return select( pnt0, pnt1, boolInVec(select1) );\n}\n\ninline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 )\n{\n    return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Point3 &pnt )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = pnt.get128();\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\ninline void print( const Point3 &pnt, const char * name )\n{\n    union { __m128 v; float s[4]; } tmp;\n    tmp.v = pnt.get128();\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/vecidx_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VECIDX_AOS_H\n#define _VECTORMATH_VECIDX_AOS_H\n\n#include \"defines.h\"\n#include \"floatInVec.h\"\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// VecIdx\n// Used in setting elements of Vector3, Vector4, Point3, or Quat with the\n// subscripting operator.\n//\n\n_VECTORMATH_ALIGNED_TYPE_1 class VecIdx {\n\nprivate:\n\n   __m128 &ref;\n   int i;\n\npublic:\n\n    inline VecIdx( __m128& vec, int idx ): ref(vec) { i = idx; }\n\n    // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined\n    // in which case, implicitly casts to floatInVec, and one must call\n    // getAsFloat to convert to float.\n    //\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n    inline operator floatInVec() const;\n    inline float getAsFloat() const;\n#else\n    inline operator float() const;\n#endif\n\n    inline float operator =( float scalar );\n    inline floatInVec operator =( const floatInVec &scalar );\n    inline floatInVec operator =( const VecIdx& scalar );\n    inline floatInVec operator *=( float scalar );\n    inline floatInVec operator *=( const floatInVec &scalar );\n    inline floatInVec operator /=( float scalar );\n    inline floatInVec operator /=( const floatInVec &scalar );\n    inline floatInVec operator +=( float scalar );\n    inline floatInVec operator +=( const floatInVec &scalar );\n    inline floatInVec operator -=( float scalar );\n    inline floatInVec operator -=( const floatInVec &scalar );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/SSE/cpp/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_CPP_SSE_H\n#define _VECTORMATH_AOS_CPP_SSE_H\n\n#include \"defines.h\"\n#include <math.h>\n#include <xmmintrin.h>\n#include <emmintrin.h>\n#include <assert.h>\n\ntypedef __m128  vec_float4;\ntypedef __m128  vec_uint4;\ntypedef __m128  vec_int4;\ntypedef __m128i vec_uchar16;\ntypedef __m128i vec_ushort8;\n\n#define _mm_ror_ps(vec, i)    (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec))\n#define _mm_rol_ps(vec, i)    (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(7-i)%4,(unsigned char)(6-i)%4,(unsigned char)(5-i)%4,(unsigned char)(4-i)%4))) : (vec))\n#define _mm_abs_ps(vec)       _mm_andnot_ps(_MASKSIGN_,vec)\n#define _mm_neg_ps(vec)       _mm_xor_ps(_MASKSIGN_,vec)\n#define vec_splat(x, e)       _mm_shuffle_ps(x, x, _MM_SHUFFLE(e, e, e, e))\n#define vec_madd(a, b, c)     _mm_add_ps(c, _mm_mul_ps(a, b) )\n#define vec_sld(vec, vec2, x) _mm_ror_ps(vec, ((x)/4))\n\nunion SSEFloat\n{\n\t__m128 m128;\n\tfloat f[4];\n};\n\nstatic inline __m128 vec_sel(__m128 a, __m128 b, __m128 mask)\n{\n\treturn _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a));\n}\n\nstatic inline __m128 vec_sel(__m128 a, __m128 b, const unsigned int *_mask)\n{\n\treturn vec_sel(a, b, _mm_load_ps((float *)_mask));\n}\n\nstatic inline __m128 vec_sel(__m128 a, __m128 b, unsigned int _mask)\n{\n\treturn vec_sel(a, b, _mm_set1_ps(*(float *)&_mask));\n}\n\nstatic inline __m128 toM128(unsigned int x)\n{\n    return _mm_set1_ps( *(float *)&x );\n}\n\nstatic inline __m128 fabsf4(__m128 x)\n{\n    return _mm_and_ps(x, toM128(0x7fffffff));\n}\n/*\nunion SSE64\n{\n\t__m128 m128;\n\tstruct\n\t{\n\t\t__m64 m01;\n\t\t__m64 m23;\n\t} m64;\n};\n\nstatic inline __m128 vec_cts(__m128 x, int a)\n{\n\tassert(a == 0); // Only 2^0 supported\n\t(void)a;\n\tSSE64 sse64;\n\tsse64.m64.m01 = _mm_cvttps_pi32(x);\n\tsse64.m64.m23 = _mm_cvttps_pi32(_mm_ror_ps(x,2));\n\t_mm_empty();\n    return sse64.m128;\n}\n\nstatic inline __m128 vec_ctf(__m128 x, int a)\n{\n\tassert(a == 0); // Only 2^0 supported\n\t(void)a;\n\tSSE64 sse64;\n\tsse64.m128 = x;\n\t__m128 result =_mm_movelh_ps(\n\t\t_mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m01),\n\t\t_mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m23));\n\t_mm_empty();\n\treturn result;\n}\n*/\nstatic inline __m128 vec_cts(__m128 x, int a)\n{\n\tassert(a == 0); // Only 2^0 supported\n\t(void)a;\n\t__m128i result = _mm_cvtps_epi32(x);\n    return (__m128 &)result;\n}\n\nstatic inline __m128 vec_ctf(__m128 x, int a)\n{\n\tassert(a == 0); // Only 2^0 supported\n\t(void)a;\n\treturn _mm_cvtepi32_ps((__m128i &)x);\n}\n\n#define vec_nmsub(a, b, c) _mm_sub_ps( c, _mm_mul_ps( a, b ) )\n#define vec_sub(a, b)      _mm_sub_ps( a, b )\n#define vec_add(a, b)      _mm_add_ps( a, b )\n#define vec_mul(a, b)      _mm_mul_ps( a, b )\n#define vec_xor(a, b)      _mm_xor_ps( a, b )\n#define vec_and(a, b)      _mm_and_ps( a, b )\n#define vec_cmpeq(a, b)    _mm_cmpeq_ps( a, b )\n#define vec_cmpgt(a, b)    _mm_cmpgt_ps( a, b )\n#define vec_mergeh(a, b)   _mm_unpacklo_ps( a, b )\n#define vec_mergel(a, b)   _mm_unpackhi_ps( a, b )\n#define vec_andc(a, b)     _mm_andnot_ps( b, a )\n#define sqrtf4(x)          _mm_sqrt_ps( x )\n#define rsqrtf4(x)         _mm_rsqrt_ps( x )\n#define recipf4(x)         _mm_rcp_ps( x )\n#define negatef4(x)        _mm_sub_ps( _mm_setzero_ps(), x )\n\nstatic inline __m128 newtonrapson_rsqrt4( const __m128 v )\n{\n\t#define _half4 _mm_setr_ps(0.5f, 0.5f, 0.5f, 0.5f)\n\t#define _three _mm_setr_ps(3.0f, 3.0f, 3.0f, 3.0f)\n\tconst __m128 approx = _mm_rsqrt_ps(v);\n\tconst __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx);\n\treturn _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls) );\n}\n\nstatic inline __m128 acosf4(__m128 x)\n{\n    __m128 xabs = fabsf4(x);\n\t__m128 select = _mm_cmplt_ps( x, _mm_setzero_ps() );\n    __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs));\n\n    /* Instruction counts can be reduced if the polynomial was\n     * computed entirely from nested (dependent) fma's. However,\n     * to reduce the number of pipeline stalls, the polygon is evaluated\n     * in two halves (hi and lo).\n     */\n    __m128 xabs2 = _mm_mul_ps(xabs,  xabs);\n    __m128 xabs4 = _mm_mul_ps(xabs2, xabs2);\n    __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f),\n\t\txabs, _mm_set1_ps(0.0066700901f)),\n\t\t\txabs, _mm_set1_ps(-0.0170881256f)),\n\t\t\t\txabs, _mm_set1_ps( 0.0308918810f));\n    __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f),\n\t\txabs, _mm_set1_ps(0.0889789874f)),\n\t\t\txabs, _mm_set1_ps(-0.2145988016f)),\n\t\t\t\txabs, _mm_set1_ps( 1.5707963050f));\n\n    __m128 result = vec_madd(hi, xabs4, lo);\n\n    // Adjust the result if x is negative.\n    return vec_sel(\n\t\tvec_mul(t1, result),\t\t\t\t\t\t\t\t\t// Positive\n\t\tvec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)),\t// Negative\n\t\tselect);\n}\n\nstatic inline __m128 sinf4(vec_float4 x)\n{\n\t//\n\t// Common constants used to evaluate sinf4/cosf4/tanf4\n\t//\n\t#define _SINCOS_CC0  -0.0013602249f\n\t#define _SINCOS_CC1   0.0416566950f\n\t#define _SINCOS_CC2  -0.4999990225f\n\t#define _SINCOS_SC0  -0.0001950727f\n\t#define _SINCOS_SC1   0.0083320758f\n\t#define _SINCOS_SC2  -0.1666665247f\n\n\t#define _SINCOS_KC1  1.57079625129f\n\t#define _SINCOS_KC2  7.54978995489e-8f\n\n    vec_float4 xl,xl2,xl3,res;\n\n    // Range reduction using : xl = angle * TwoOverPi;\n    //\n    xl = vec_mul(x, _mm_set1_ps(0.63661977236f));\n\n    // Find the quadrant the angle falls in\n    // using:  q = (int) (ceil(abs(xl))*sign(xl))\n    //\n    vec_int4 q = vec_cts(xl,0);\n\n    // Compute an offset based on the quadrant that the angle falls in\n    //\n    vec_int4 offset = _mm_and_ps(q,toM128(0x3));\n\n    // Remainder in range [-pi/4..pi/4]\n    //\n    vec_float4 qf = vec_ctf(q,0);\n    xl  = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x));\n\n    // Compute x^2 and x^3\n    //\n    xl2 = vec_mul(xl,xl);\n    xl3 = vec_mul(xl2,xl);\n\n    // Compute both the sin and cos of the angles\n    // using a polynomial expression:\n    //   cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and\n    //   sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2)\n    //\n\n    vec_float4 cx =\n\t\tvec_madd(\n\t\t\tvec_madd(\n\t\t\t\tvec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f));\n    vec_float4 sx =\n\t\tvec_madd(\n\t\t\tvec_madd(\n\t\t\t\tvec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl);\n\n    // Use the cosine when the offset is odd and the sin\n    // when the offset is even\n    //\n    res = vec_sel(cx,sx,vec_cmpeq(vec_and(offset,\n                                          toM128(0x1)),\n\t\t\t\t\t\t\t\t\t\t  _mm_setzero_ps()));\n\n    // Flip the sign of the result when (offset mod 4) = 1 or 2\n    //\n    return vec_sel(\n\t\tvec_xor(toM128(0x80000000U), res),\t// Negative\n\t\tres,\t\t\t\t\t\t\t\t// Positive\n\t\tvec_cmpeq(vec_and(offset,toM128(0x2)),_mm_setzero_ps()));\n}\n\nstatic inline void sincosf4(vec_float4 x, vec_float4* s, vec_float4* c)\n{\n    vec_float4 xl,xl2,xl3;\n    vec_int4   offsetSin, offsetCos;\n\n    // Range reduction using : xl = angle * TwoOverPi;\n    //\n    xl = vec_mul(x, _mm_set1_ps(0.63661977236f));\n\n    // Find the quadrant the angle falls in\n    // using:  q = (int) (ceil(abs(xl))*sign(xl))\n    //\n    //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0);\n    vec_int4 q = vec_cts(xl,0);\n\n    // Compute the offset based on the quadrant that the angle falls in.\n    // Add 1 to the offset for the cosine.\n    //\n    offsetSin = vec_and(q,toM128((int)0x3));\n\t__m128i temp = _mm_add_epi32(_mm_set1_epi32(1),(__m128i &)offsetSin);\n\toffsetCos = (__m128 &)temp;\n\n    // Remainder in range [-pi/4..pi/4]\n    //\n    vec_float4 qf = vec_ctf(q,0);\n    xl  = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x));\n\n    // Compute x^2 and x^3\n    //\n    xl2 = vec_mul(xl,xl);\n    xl3 = vec_mul(xl2,xl);\n\n    // Compute both the sin and cos of the angles\n    // using a polynomial expression:\n    //   cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and\n    //   sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2)\n    //\n    vec_float4 cx =\n\t\tvec_madd(\n\t\t\tvec_madd(\n\t\t\t\tvec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f));\n    vec_float4 sx =\n\t\tvec_madd(\n\t\t\tvec_madd(\n\t\t\t\tvec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl);\n\n    // Use the cosine when the offset is odd and the sin\n    // when the offset is even\n    //\n    vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin,toM128(0x1)),_mm_setzero_ps());\n    vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos,toM128(0x1)),_mm_setzero_ps());\n    *s = vec_sel(cx,sx,sinMask);\n    *c = vec_sel(cx,sx,cosMask);\n\n    // Flip the sign of the result when (offset mod 4) = 1 or 2\n    //\n    sinMask = vec_cmpeq(vec_and(offsetSin,toM128(0x2)),_mm_setzero_ps());\n    cosMask = vec_cmpeq(vec_and(offsetCos,toM128(0x2)),_mm_setzero_ps());\n\n    *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*s),*s,sinMask);\n    *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*c),*c,cosMask);\n}\n\n#include \"vecidx_aos.h\"\n#include \"floatInVec.h\"\n#include \"boolInVec.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Forward Declarations\n//\n\nclass Vector3;\nclass Vector4;\nclass Point3;\nclass Quat;\nclass Matrix3;\nclass Matrix4;\nclass Transform3;\n\n// A 3-D vector in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Vector3 {\n\nprivate:\n\n    __m128 mVec128;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Vector3( ) { };\n\n    // Construct a 3-D vector from x, y, and z elements\n    //\n    inline Vector3( float x, float y, float z );\n\n    // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type)\n    //\n    inline Vector3( const floatInVec &x, const floatInVec &y, const floatInVec &z );\n\n    // Copy elements from a 3-D point into a 3-D vector\n    //\n    explicit inline Vector3( const Point3 &pnt );\n\n    // Set all elements of a 3-D vector to the same scalar value\n    //\n    explicit inline Vector3( float scalar );\n\n    // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Vector3( const floatInVec &scalar );\n\n    // Set vector float data in a 3-D vector\n    //\n    explicit inline Vector3( __m128 vf4 );\n\n    // Get vector float data from a 3-D vector\n    //\n    inline __m128 get128( ) const;\n\n    // Assign one 3-D vector to another\n    //\n    inline Vector3 & operator =( const Vector3 &vec );\n\n    // Set the x element of a 3-D vector\n    //\n    inline Vector3 & setX( float x );\n\n    // Set the y element of a 3-D vector\n    //\n    inline Vector3 & setY( float y );\n\n    // Set the z element of a 3-D vector\n    //\n    inline Vector3 & setZ( float z );\n\n    // Set the x element of a 3-D vector (scalar data contained in vector data type)\n    //\n    inline Vector3 & setX( const floatInVec &x );\n\n    // Set the y element of a 3-D vector (scalar data contained in vector data type)\n    //\n    inline Vector3 & setY( const floatInVec &y );\n\n    // Set the z element of a 3-D vector (scalar data contained in vector data type)\n    //\n    inline Vector3 & setZ( const floatInVec &z );\n\n    // Get the x element of a 3-D vector\n    //\n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a 3-D vector\n    //\n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a 3-D vector\n    //\n    inline const floatInVec getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D vector by index\n    //\n    inline Vector3 & setElem( int idx, float value );\n\n    // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type)\n    //\n    inline Vector3 & setElem( int idx, const floatInVec &value );\n\n    // Get an x, y, or z element of a 3-D vector by index\n    //\n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    //\n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    //\n    inline const floatInVec operator []( int idx ) const;\n\n    // Add two 3-D vectors\n    //\n    inline const Vector3 operator +( const Vector3 &vec ) const;\n\n    // Subtract a 3-D vector from another 3-D vector\n    //\n    inline const Vector3 operator -( const Vector3 &vec ) const;\n\n    // Add a 3-D vector to a 3-D point\n    //\n    inline const Point3 operator +( const Point3 &pnt ) const;\n\n    // Multiply a 3-D vector by a scalar\n    //\n    inline const Vector3 operator *( float scalar ) const;\n\n    // Divide a 3-D vector by a scalar\n    //\n    inline const Vector3 operator /( float scalar ) const;\n\n    // Multiply a 3-D vector by a scalar (scalar data contained in vector data type)\n    //\n    inline const Vector3 operator *( const floatInVec &scalar ) const;\n\n    // Divide a 3-D vector by a scalar (scalar data contained in vector data type)\n    //\n    inline const Vector3 operator /( const floatInVec &scalar ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    //\n    inline Vector3 & operator +=( const Vector3 &vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    //\n    inline Vector3 & operator -=( const Vector3 &vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    //\n    inline Vector3 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    //\n    inline Vector3 & operator /=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    //\n    inline Vector3 & operator *=( const floatInVec &scalar );\n\n    // Perform compound assignment and division by a scalar (scalar data contained in vector data type)\n    //\n    inline Vector3 & operator /=( const floatInVec &scalar );\n\n    // Negate all elements of a 3-D vector\n    //\n    inline const Vector3 operator -( ) const;\n\n    // Construct x axis\n    //\n    static inline const Vector3 xAxis( );\n\n    // Construct y axis\n    //\n    static inline const Vector3 yAxis( );\n\n    // Construct z axis\n    //\n    static inline const Vector3 zAxis( );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Multiply a 3-D vector by a scalar\n//\ninline const Vector3 operator *( float scalar, const Vector3 &vec );\n\n// Multiply a 3-D vector by a scalar (scalar data contained in vector data type)\n//\ninline const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec );\n\n// Multiply two 3-D vectors per element\n//\ninline const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Divide two 3-D vectors per element\n// NOTE:\n// Floating-point behavior matches standard library function divf4.\n//\ninline const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Compute the reciprocal of a 3-D vector per element\n// NOTE:\n// Floating-point behavior matches standard library function recipf4.\n//\ninline const Vector3 recipPerElem( const Vector3 &vec );\n\n// Compute the absolute value of a 3-D vector per element\n//\ninline const Vector3 absPerElem( const Vector3 &vec );\n\n// Copy sign from one 3-D vector to another, per element\n//\ninline const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Maximum of two 3-D vectors per element\n//\ninline const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Minimum of two 3-D vectors per element\n//\ninline const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Maximum element of a 3-D vector\n//\ninline const floatInVec maxElem( const Vector3 &vec );\n\n// Minimum element of a 3-D vector\n//\ninline const floatInVec minElem( const Vector3 &vec );\n\n// Compute the sum of all elements of a 3-D vector\n//\ninline const floatInVec sum( const Vector3 &vec );\n\n// Compute the dot product of two 3-D vectors\n//\ninline const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Compute the square of the length of a 3-D vector\n//\ninline const floatInVec lengthSqr( const Vector3 &vec );\n\n// Compute the length of a 3-D vector\n//\ninline const floatInVec length( const Vector3 &vec );\n\n// Normalize a 3-D vector\n// NOTE:\n// The result is unpredictable when all elements of vec are at or near zero.\n//\ninline const Vector3 normalize( const Vector3 &vec );\n\n// Compute cross product of two 3-D vectors\n//\ninline const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Outer product of two 3-D vectors\n//\ninline const Matrix3 outer( const Vector3 &vec0, const Vector3 &vec1 );\n\n// Pre-multiply a row vector by a 3x3 matrix\n// NOTE:\n// Slower than column post-multiply.\n//\ninline const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat );\n\n// Cross-product matrix of a 3-D vector\n//\ninline const Matrix3 crossMatrix( const Vector3 &vec );\n\n// Create cross-product matrix and multiply\n// NOTE:\n// Faster than separately creating a cross-product matrix and multiplying.\n//\ninline const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat );\n\n// Linear interpolation between two 3-D vectors\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 );\n\n// Linear interpolation between two 3-D vectors (scalar data contained in vector data type)\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 );\n\n// Spherical linear interpolation between two 3-D vectors\n// NOTE:\n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n//\ninline const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 );\n\n// Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type)\n// NOTE:\n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n//\ninline const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 );\n\n// Conditionally select between two 3-D vectors\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 );\n\n// Conditionally select between two 3-D vectors (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 );\n\n// Store x, y, and z elements of 3-D vector in first three words of a quadword, preserving fourth word\n//\ninline void storeXYZ( const Vector3 &vec, __m128 * quad );\n\n// Load four three-float 3-D vectors, stored in three quadwords\n//\ninline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads );\n\n// Store four 3-D vectors in three quadwords\n//\ninline void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads );\n\n// Store eight 3-D vectors as half-floats\n//\ninline void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D vector\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Vector3 &vec );\n\n// Print a 3-D vector and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Vector3 &vec, const char * name );\n\n#endif\n\n// A 4-D vector in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Vector4 {\n\nprivate:\n\n    __m128 mVec128;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Vector4( ) { };\n\n    // Construct a 4-D vector from x, y, z, and w elements\n    //\n    inline Vector4( float x, float y, float z, float w );\n\n    // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type)\n    //\n    inline Vector4( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar\n    //\n    inline Vector4( const Vector3 &xyz, float w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type)\n    //\n    inline Vector4( const Vector3 &xyz, const floatInVec &w );\n\n    // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n    //\n    explicit inline Vector4( const Vector3 &vec );\n\n    // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n    //\n    explicit inline Vector4( const Point3 &pnt );\n\n    // Copy elements from a quaternion into a 4-D vector\n    //\n    explicit inline Vector4( const Quat &quat );\n\n    // Set all elements of a 4-D vector to the same scalar value\n    //\n    explicit inline Vector4( float scalar );\n\n    // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Vector4( const floatInVec &scalar );\n\n    // Set vector float data in a 4-D vector\n    //\n    explicit inline Vector4( __m128 vf4 );\n\n    // Get vector float data from a 4-D vector\n    //\n    inline __m128 get128( ) const;\n\n    // Assign one 4-D vector to another\n    //\n    inline Vector4 & operator =( const Vector4 &vec );\n\n    // Set the x, y, and z elements of a 4-D vector\n    // NOTE:\n    // This function does not change the w element.\n    //\n    inline Vector4 & setXYZ( const Vector3 &vec );\n\n    // Get the x, y, and z elements of a 4-D vector\n    //\n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a 4-D vector\n    //\n    inline Vector4 & setX( float x );\n\n    // Set the y element of a 4-D vector\n    //\n    inline Vector4 & setY( float y );\n\n    // Set the z element of a 4-D vector\n    //\n    inline Vector4 & setZ( float z );\n\n    // Set the w element of a 4-D vector\n    //\n    inline Vector4 & setW( float w );\n\n    // Set the x element of a 4-D vector (scalar data contained in vector data type)\n    //\n    inline Vector4 & setX( const floatInVec &x );\n\n    // Set the y element of a 4-D vector (scalar data contained in vector data type)\n    //\n    inline Vector4 & setY( const floatInVec &y );\n\n    // Set the z element of a 4-D vector (scalar data contained in vector data type)\n    //\n    inline Vector4 & setZ( const floatInVec &z );\n\n    // Set the w element of a 4-D vector (scalar data contained in vector data type)\n    //\n    inline Vector4 & setW( const floatInVec &w );\n\n    // Get the x element of a 4-D vector\n    //\n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a 4-D vector\n    //\n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a 4-D vector\n    //\n    inline const floatInVec getZ( ) const;\n\n    // Get the w element of a 4-D vector\n    //\n    inline const floatInVec getW( ) const;\n\n    // Set an x, y, z, or w element of a 4-D vector by index\n    //\n    inline Vector4 & setElem( int idx, float value );\n\n    // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type)\n    //\n    inline Vector4 & setElem( int idx, const floatInVec &value );\n\n    // Get an x, y, z, or w element of a 4-D vector by index\n    //\n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    //\n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    //\n    inline const floatInVec operator []( int idx ) const;\n\n    // Add two 4-D vectors\n    //\n    inline const Vector4 operator +( const Vector4 &vec ) const;\n\n    // Subtract a 4-D vector from another 4-D vector\n    //\n    inline const Vector4 operator -( const Vector4 &vec ) const;\n\n    // Multiply a 4-D vector by a scalar\n    //\n    inline const Vector4 operator *( float scalar ) const;\n\n    // Divide a 4-D vector by a scalar\n    //\n    inline const Vector4 operator /( float scalar ) const;\n\n    // Multiply a 4-D vector by a scalar (scalar data contained in vector data type)\n    //\n    inline const Vector4 operator *( const floatInVec &scalar ) const;\n\n    // Divide a 4-D vector by a scalar (scalar data contained in vector data type)\n    //\n    inline const Vector4 operator /( const floatInVec &scalar ) const;\n\n    // Perform compound assignment and addition with a 4-D vector\n    //\n    inline Vector4 & operator +=( const Vector4 &vec );\n\n    // Perform compound assignment and subtraction by a 4-D vector\n    //\n    inline Vector4 & operator -=( const Vector4 &vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    //\n    inline Vector4 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    //\n    inline Vector4 & operator /=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    //\n    inline Vector4 & operator *=( const floatInVec &scalar );\n\n    // Perform compound assignment and division by a scalar (scalar data contained in vector data type)\n    //\n    inline Vector4 & operator /=( const floatInVec &scalar );\n\n    // Negate all elements of a 4-D vector\n    //\n    inline const Vector4 operator -( ) const;\n\n    // Construct x axis\n    //\n    static inline const Vector4 xAxis( );\n\n    // Construct y axis\n    //\n    static inline const Vector4 yAxis( );\n\n    // Construct z axis\n    //\n    static inline const Vector4 zAxis( );\n\n    // Construct w axis\n    //\n    static inline const Vector4 wAxis( );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Multiply a 4-D vector by a scalar\n//\ninline const Vector4 operator *( float scalar, const Vector4 &vec );\n\n// Multiply a 4-D vector by a scalar (scalar data contained in vector data type)\n//\ninline const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec );\n\n// Multiply two 4-D vectors per element\n//\ninline const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Divide two 4-D vectors per element\n// NOTE:\n// Floating-point behavior matches standard library function divf4.\n//\ninline const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Compute the reciprocal of a 4-D vector per element\n// NOTE:\n// Floating-point behavior matches standard library function recipf4.\n//\ninline const Vector4 recipPerElem( const Vector4 &vec );\n\n// Compute the absolute value of a 4-D vector per element\n//\ninline const Vector4 absPerElem( const Vector4 &vec );\n\n// Copy sign from one 4-D vector to another, per element\n//\ninline const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Maximum of two 4-D vectors per element\n//\ninline const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Minimum of two 4-D vectors per element\n//\ninline const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Maximum element of a 4-D vector\n//\ninline const floatInVec maxElem( const Vector4 &vec );\n\n// Minimum element of a 4-D vector\n//\ninline const floatInVec minElem( const Vector4 &vec );\n\n// Compute the sum of all elements of a 4-D vector\n//\ninline const floatInVec sum( const Vector4 &vec );\n\n// Compute the dot product of two 4-D vectors\n//\ninline const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Compute the square of the length of a 4-D vector\n//\ninline const floatInVec lengthSqr( const Vector4 &vec );\n\n// Compute the length of a 4-D vector\n//\ninline const floatInVec length( const Vector4 &vec );\n\n// Normalize a 4-D vector\n// NOTE:\n// The result is unpredictable when all elements of vec are at or near zero.\n//\ninline const Vector4 normalize( const Vector4 &vec );\n\n// Outer product of two 4-D vectors\n//\ninline const Matrix4 outer( const Vector4 &vec0, const Vector4 &vec1 );\n\n// Linear interpolation between two 4-D vectors\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 );\n\n// Linear interpolation between two 4-D vectors (scalar data contained in vector data type)\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 );\n\n// Spherical linear interpolation between two 4-D vectors\n// NOTE:\n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n//\ninline const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 );\n\n// Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type)\n// NOTE:\n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n//\ninline const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 );\n\n// Conditionally select between two 4-D vectors\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 );\n\n// Conditionally select between two 4-D vectors (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 );\n\n// Store four 4-D vectors as half-floats\n//\ninline void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4-D vector\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Vector4 &vec );\n\n// Print a 4-D vector and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Vector4 &vec, const char * name );\n\n#endif\n\n// A 3-D point in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Point3 {\n\nprivate:\n\n    __m128 mVec128;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Point3( ) { };\n\n    // Construct a 3-D point from x, y, and z elements\n    //\n    inline Point3( float x, float y, float z );\n\n    // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type)\n    //\n    inline Point3( const floatInVec &x, const floatInVec &y, const floatInVec &z );\n\n    // Copy elements from a 3-D vector into a 3-D point\n    //\n    explicit inline Point3( const Vector3 &vec );\n\n    // Set all elements of a 3-D point to the same scalar value\n    //\n    explicit inline Point3( float scalar );\n\n    // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Point3( const floatInVec &scalar );\n\n    // Set vector float data in a 3-D point\n    //\n    explicit inline Point3( __m128 vf4 );\n\n    // Get vector float data from a 3-D point\n    //\n    inline __m128 get128( ) const;\n\n    // Assign one 3-D point to another\n    //\n    inline Point3 & operator =( const Point3 &pnt );\n\n    // Set the x element of a 3-D point\n    //\n    inline Point3 & setX( float x );\n\n    // Set the y element of a 3-D point\n    //\n    inline Point3 & setY( float y );\n\n    // Set the z element of a 3-D point\n    //\n    inline Point3 & setZ( float z );\n\n    // Set the x element of a 3-D point (scalar data contained in vector data type)\n    //\n    inline Point3 & setX( const floatInVec &x );\n\n    // Set the y element of a 3-D point (scalar data contained in vector data type)\n    //\n    inline Point3 & setY( const floatInVec &y );\n\n    // Set the z element of a 3-D point (scalar data contained in vector data type)\n    //\n    inline Point3 & setZ( const floatInVec &z );\n\n    // Get the x element of a 3-D point\n    //\n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a 3-D point\n    //\n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a 3-D point\n    //\n    inline const floatInVec getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D point by index\n    //\n    inline Point3 & setElem( int idx, float value );\n\n    // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type)\n    //\n    inline Point3 & setElem( int idx, const floatInVec &value );\n\n    // Get an x, y, or z element of a 3-D point by index\n    //\n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    //\n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    //\n    inline const floatInVec operator []( int idx ) const;\n\n    // Subtract a 3-D point from another 3-D point\n    //\n    inline const Vector3 operator -( const Point3 &pnt ) const;\n\n    // Add a 3-D point to a 3-D vector\n    //\n    inline const Point3 operator +( const Vector3 &vec ) const;\n\n    // Subtract a 3-D vector from a 3-D point\n    //\n    inline const Point3 operator -( const Vector3 &vec ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    //\n    inline Point3 & operator +=( const Vector3 &vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    //\n    inline Point3 & operator -=( const Vector3 &vec );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Multiply two 3-D points per element\n//\ninline const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Divide two 3-D points per element\n// NOTE:\n// Floating-point behavior matches standard library function divf4.\n//\ninline const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Compute the reciprocal of a 3-D point per element\n// NOTE:\n// Floating-point behavior matches standard library function recipf4.\n//\ninline const Point3 recipPerElem( const Point3 &pnt );\n\n// Compute the absolute value of a 3-D point per element\n//\ninline const Point3 absPerElem( const Point3 &pnt );\n\n// Copy sign from one 3-D point to another, per element\n//\ninline const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Maximum of two 3-D points per element\n//\ninline const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Minimum of two 3-D points per element\n//\ninline const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Maximum element of a 3-D point\n//\ninline const floatInVec maxElem( const Point3 &pnt );\n\n// Minimum element of a 3-D point\n//\ninline const floatInVec minElem( const Point3 &pnt );\n\n// Compute the sum of all elements of a 3-D point\n//\ninline const floatInVec sum( const Point3 &pnt );\n\n// Apply uniform scale to a 3-D point\n//\ninline const Point3 scale( const Point3 &pnt, float scaleVal );\n\n// Apply uniform scale to a 3-D point (scalar data contained in vector data type)\n//\ninline const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal );\n\n// Apply non-uniform scale to a 3-D point\n//\ninline const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec );\n\n// Scalar projection of a 3-D point on a unit-length 3-D vector\n//\ninline const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec );\n\n// Compute the square of the distance of a 3-D point from the coordinate-system origin\n//\ninline const floatInVec distSqrFromOrigin( const Point3 &pnt );\n\n// Compute the distance of a 3-D point from the coordinate-system origin\n//\ninline const floatInVec distFromOrigin( const Point3 &pnt );\n\n// Compute the square of the distance between two 3-D points\n//\ninline const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Compute the distance between two 3-D points\n//\ninline const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 );\n\n// Linear interpolation between two 3-D points\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 );\n\n// Linear interpolation between two 3-D points (scalar data contained in vector data type)\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 );\n\n// Conditionally select between two 3-D points\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 );\n\n// Conditionally select between two 3-D points (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 );\n\n// Store x, y, and z elements of 3-D point in first three words of a quadword, preserving fourth word\n//\ninline void storeXYZ( const Point3 &pnt, __m128 * quad );\n\n// Load four three-float 3-D points, stored in three quadwords\n//\ninline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads );\n\n// Store four 3-D points in three quadwords\n//\ninline void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads );\n\n// Store eight 3-D points as half-floats\n//\ninline void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D point\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Point3 &pnt );\n\n// Print a 3-D point and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Point3 &pnt, const char * name );\n\n#endif\n\n// A quaternion in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Quat {\n\nprivate:\n\n    __m128 mVec128;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Quat( ) { };\n\n    // Construct a quaternion from x, y, z, and w elements\n    //\n    inline Quat( float x, float y, float z, float w );\n\n    // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type)\n    //\n    inline Quat( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w );\n\n    // Construct a quaternion from a 3-D vector and a scalar\n    //\n    inline Quat( const Vector3 &xyz, float w );\n\n    // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type)\n    //\n    inline Quat( const Vector3 &xyz, const floatInVec &w );\n\n    // Copy elements from a 4-D vector into a quaternion\n    //\n    explicit inline Quat( const Vector4 &vec );\n\n    // Convert a rotation matrix to a unit-length quaternion\n    //\n    explicit inline Quat( const Matrix3 & rotMat );\n\n    // Set all elements of a quaternion to the same scalar value\n    //\n    explicit inline Quat( float scalar );\n\n    // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Quat( const floatInVec &scalar );\n\n    // Set vector float data in a quaternion\n    //\n    explicit inline Quat( __m128 vf4 );\n\n    // Get vector float data from a quaternion\n    //\n    inline __m128 get128( ) const;\n\n    // Assign one quaternion to another\n    //\n    inline Quat & operator =( const Quat &quat );\n\n    // Set the x, y, and z elements of a quaternion\n    // NOTE:\n    // This function does not change the w element.\n    //\n    inline Quat & setXYZ( const Vector3 &vec );\n\n    // Get the x, y, and z elements of a quaternion\n    //\n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a quaternion\n    //\n    inline Quat & setX( float x );\n\n    // Set the y element of a quaternion\n    //\n    inline Quat & setY( float y );\n\n    // Set the z element of a quaternion\n    //\n    inline Quat & setZ( float z );\n\n    // Set the w element of a quaternion\n    //\n    inline Quat & setW( float w );\n\n    // Set the x element of a quaternion (scalar data contained in vector data type)\n    //\n    inline Quat & setX( const floatInVec &x );\n\n    // Set the y element of a quaternion (scalar data contained in vector data type)\n    //\n    inline Quat & setY( const floatInVec &y );\n\n    // Set the z element of a quaternion (scalar data contained in vector data type)\n    //\n    inline Quat & setZ( const floatInVec &z );\n\n    // Set the w element of a quaternion (scalar data contained in vector data type)\n    //\n    inline Quat & setW( const floatInVec &w );\n\n    // Get the x element of a quaternion\n    //\n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a quaternion\n    //\n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a quaternion\n    //\n    inline const floatInVec getZ( ) const;\n\n    // Get the w element of a quaternion\n    //\n    inline const floatInVec getW( ) const;\n\n    // Set an x, y, z, or w element of a quaternion by index\n    //\n    inline Quat & setElem( int idx, float value );\n\n    // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type)\n    //\n    inline Quat & setElem( int idx, const floatInVec &value );\n\n    // Get an x, y, z, or w element of a quaternion by index\n    //\n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    //\n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    //\n    inline const floatInVec operator []( int idx ) const;\n\n    // Add two quaternions\n    //\n    inline const Quat operator +( const Quat &quat ) const;\n\n    // Subtract a quaternion from another quaternion\n    //\n    inline const Quat operator -( const Quat &quat ) const;\n\n    // Multiply two quaternions\n    //\n    inline const Quat operator *( const Quat &quat ) const;\n\n    // Multiply a quaternion by a scalar\n    //\n    inline const Quat operator *( float scalar ) const;\n\n    // Divide a quaternion by a scalar\n    //\n    inline const Quat operator /( float scalar ) const;\n\n    // Multiply a quaternion by a scalar (scalar data contained in vector data type)\n    //\n    inline const Quat operator *( const floatInVec &scalar ) const;\n\n    // Divide a quaternion by a scalar (scalar data contained in vector data type)\n    //\n    inline const Quat operator /( const floatInVec &scalar ) const;\n\n    // Perform compound assignment and addition with a quaternion\n    //\n    inline Quat & operator +=( const Quat &quat );\n\n    // Perform compound assignment and subtraction by a quaternion\n    //\n    inline Quat & operator -=( const Quat &quat );\n\n    // Perform compound assignment and multiplication by a quaternion\n    //\n    inline Quat & operator *=( const Quat &quat );\n\n    // Perform compound assignment and multiplication by a scalar\n    //\n    inline Quat & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    //\n    inline Quat & operator /=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    //\n    inline Quat & operator *=( const floatInVec &scalar );\n\n    // Perform compound assignment and division by a scalar (scalar data contained in vector data type)\n    //\n    inline Quat & operator /=( const floatInVec &scalar );\n\n    // Negate all elements of a quaternion\n    //\n    inline const Quat operator -( ) const;\n\n    // Construct an identity quaternion\n    //\n    static inline const Quat identity( );\n\n    // Construct a quaternion to rotate between two unit-length 3-D vectors\n    // NOTE:\n    // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n    //\n    static inline const Quat rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector\n    //\n    static inline const Quat rotation( float radians, const Vector3 &unitVec );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    //\n    static inline const Quat rotation( const floatInVec &radians, const Vector3 &unitVec );\n\n    // Construct a quaternion to rotate around the x axis\n    //\n    static inline const Quat rotationX( float radians );\n\n    // Construct a quaternion to rotate around the y axis\n    //\n    static inline const Quat rotationY( float radians );\n\n    // Construct a quaternion to rotate around the z axis\n    //\n    static inline const Quat rotationZ( float radians );\n\n    // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type)\n    //\n    static inline const Quat rotationX( const floatInVec &radians );\n\n    // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type)\n    //\n    static inline const Quat rotationY( const floatInVec &radians );\n\n    // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type)\n    //\n    static inline const Quat rotationZ( const floatInVec &radians );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Multiply a quaternion by a scalar\n//\ninline const Quat operator *( float scalar, const Quat &quat );\n\n// Multiply a quaternion by a scalar (scalar data contained in vector data type)\n//\ninline const Quat operator *( const floatInVec &scalar, const Quat &quat );\n\n// Compute the conjugate of a quaternion\n//\ninline const Quat conj( const Quat &quat );\n\n// Use a unit-length quaternion to rotate a 3-D vector\n//\ninline const Vector3 rotate( const Quat &unitQuat, const Vector3 &vec );\n\n// Compute the dot product of two quaternions\n//\ninline const floatInVec dot( const Quat &quat0, const Quat &quat1 );\n\n// Compute the norm of a quaternion\n//\ninline const floatInVec norm( const Quat &quat );\n\n// Compute the length of a quaternion\n//\ninline const floatInVec length( const Quat &quat );\n\n// Normalize a quaternion\n// NOTE:\n// The result is unpredictable when all elements of quat are at or near zero.\n//\ninline const Quat normalize( const Quat &quat );\n\n// Linear interpolation between two quaternions\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Quat lerp( float t, const Quat &quat0, const Quat &quat1 );\n\n// Linear interpolation between two quaternions (scalar data contained in vector data type)\n// NOTE:\n// Does not clamp t between 0 and 1.\n//\ninline const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 );\n\n// Spherical linear interpolation between two quaternions\n// NOTE:\n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n//\ninline const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 );\n\n// Spherical linear interpolation between two quaternions (scalar data contained in vector data type)\n// NOTE:\n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n//\ninline const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 );\n\n// Spherical quadrangle interpolation\n//\ninline const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 );\n\n// Spherical quadrangle interpolation (scalar data contained in vector data type)\n//\ninline const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 );\n\n// Conditionally select between two quaternions\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Quat select( const Quat &quat0, const Quat &quat1, bool select1 );\n\n// Conditionally select between two quaternions (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a quaternion\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Quat &quat );\n\n// Print a quaternion and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Quat &quat, const char * name );\n\n#endif\n\n// A 3x3 matrix in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Matrix3 {\n\nprivate:\n\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Matrix3( ) { };\n\n    // Copy a 3x3 matrix\n    //\n    inline Matrix3( const Matrix3 & mat );\n\n    // Construct a 3x3 matrix containing the specified columns\n    //\n    inline Matrix3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2 );\n\n    // Construct a 3x3 rotation matrix from a unit-length quaternion\n    //\n    explicit inline Matrix3( const Quat &unitQuat );\n\n    // Set all elements of a 3x3 matrix to the same scalar value\n    //\n    explicit inline Matrix3( float scalar );\n\n    // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Matrix3( const floatInVec &scalar );\n\n    // Assign one 3x3 matrix to another\n    //\n    inline Matrix3 & operator =( const Matrix3 & mat );\n\n    // Set column 0 of a 3x3 matrix\n    //\n    inline Matrix3 & setCol0( const Vector3 &col0 );\n\n    // Set column 1 of a 3x3 matrix\n    //\n    inline Matrix3 & setCol1( const Vector3 &col1 );\n\n    // Set column 2 of a 3x3 matrix\n    //\n    inline Matrix3 & setCol2( const Vector3 &col2 );\n\n    // Get column 0 of a 3x3 matrix\n    //\n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x3 matrix\n    //\n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x3 matrix\n    //\n    inline const Vector3 getCol2( ) const;\n\n    // Set the column of a 3x3 matrix referred to by the specified index\n    //\n    inline Matrix3 & setCol( int col, const Vector3 &vec );\n\n    // Set the row of a 3x3 matrix referred to by the specified index\n    //\n    inline Matrix3 & setRow( int row, const Vector3 &vec );\n\n    // Get the column of a 3x3 matrix referred to by the specified index\n    //\n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x3 matrix referred to by the specified index\n    //\n    inline const Vector3 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    //\n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    //\n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x3 matrix referred to by column and row indices\n    //\n    inline Matrix3 & setElem( int col, int row, float val );\n\n    // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type)\n    //\n    inline Matrix3 & setElem( int col, int row, const floatInVec &val );\n\n    // Get the element of a 3x3 matrix referred to by column and row indices\n    //\n    inline const floatInVec getElem( int col, int row ) const;\n\n    // Add two 3x3 matrices\n    //\n    inline const Matrix3 operator +( const Matrix3 & mat ) const;\n\n    // Subtract a 3x3 matrix from another 3x3 matrix\n    //\n    inline const Matrix3 operator -( const Matrix3 & mat ) const;\n\n    // Negate all elements of a 3x3 matrix\n    //\n    inline const Matrix3 operator -( ) const;\n\n    // Multiply a 3x3 matrix by a scalar\n    //\n    inline const Matrix3 operator *( float scalar ) const;\n\n    // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type)\n    //\n    inline const Matrix3 operator *( const floatInVec &scalar ) const;\n\n    // Multiply a 3x3 matrix by a 3-D vector\n    //\n    inline const Vector3 operator *( const Vector3 &vec ) const;\n\n    // Multiply two 3x3 matrices\n    //\n    inline const Matrix3 operator *( const Matrix3 & mat ) const;\n\n    // Perform compound assignment and addition with a 3x3 matrix\n    //\n    inline Matrix3 & operator +=( const Matrix3 & mat );\n\n    // Perform compound assignment and subtraction by a 3x3 matrix\n    //\n    inline Matrix3 & operator -=( const Matrix3 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    //\n    inline Matrix3 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    //\n    inline Matrix3 & operator *=( const floatInVec &scalar );\n\n    // Perform compound assignment and multiplication by a 3x3 matrix\n    //\n    inline Matrix3 & operator *=( const Matrix3 & mat );\n\n    // Construct an identity 3x3 matrix\n    //\n    static inline const Matrix3 identity( );\n\n    // Construct a 3x3 matrix to rotate around the x axis\n    //\n    static inline const Matrix3 rotationX( float radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis\n    //\n    static inline const Matrix3 rotationY( float radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis\n    //\n    static inline const Matrix3 rotationZ( float radians );\n\n    // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type)\n    //\n    static inline const Matrix3 rotationX( const floatInVec &radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type)\n    //\n    static inline const Matrix3 rotationY( const floatInVec &radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type)\n    //\n    static inline const Matrix3 rotationZ( const floatInVec &radians );\n\n    // Construct a 3x3 matrix to rotate around the x, y, and z axes\n    //\n    static inline const Matrix3 rotationZYX( const Vector3 &radiansXYZ );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n    //\n    static inline const Matrix3 rotation( float radians, const Vector3 &unitVec );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    //\n    static inline const Matrix3 rotation( const floatInVec &radians, const Vector3 &unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    //\n    static inline const Matrix3 rotation( const Quat &unitQuat );\n\n    // Construct a 3x3 matrix to perform scaling\n    //\n    static inline const Matrix3 scale( const Vector3 &scaleVec );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Multiply a 3x3 matrix by a scalar\n//\ninline const Matrix3 operator *( float scalar, const Matrix3 & mat );\n\n// Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type)\n//\ninline const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat );\n\n// Append (post-multiply) a scale transformation to a 3x3 matrix\n// NOTE:\n// Faster than creating and multiplying a scale transformation matrix.\n//\ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n// NOTE:\n// Faster than creating and multiplying a scale transformation matrix.\n//\ninline const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat );\n\n// Multiply two 3x3 matrices per element\n//\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );\n\n// Compute the absolute value of a 3x3 matrix per element\n//\ninline const Matrix3 absPerElem( const Matrix3 & mat );\n\n// Transpose of a 3x3 matrix\n//\ninline const Matrix3 transpose( const Matrix3 & mat );\n\n// Compute the inverse of a 3x3 matrix\n// NOTE:\n// Result is unpredictable when the determinant of mat is equal to or near 0.\n//\ninline const Matrix3 inverse( const Matrix3 & mat );\n\n// Determinant of a 3x3 matrix\n//\ninline const floatInVec determinant( const Matrix3 & mat );\n\n// Conditionally select between two 3x3 matrices\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 );\n\n// Conditionally select between two 3x3 matrices (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x3 matrix\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Matrix3 & mat );\n\n// Print a 3x3 matrix and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Matrix3 & mat, const char * name );\n\n#endif\n\n// A 4x4 matrix in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Matrix4 {\n\nprivate:\n\n    Vector4 mCol0;\n    Vector4 mCol1;\n    Vector4 mCol2;\n    Vector4 mCol3;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Matrix4( ) { };\n\n    // Copy a 4x4 matrix\n    //\n    inline Matrix4( const Matrix4 & mat );\n\n    // Construct a 4x4 matrix containing the specified columns\n    //\n    inline Matrix4( const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3 );\n\n    // Construct a 4x4 matrix from a 3x4 transformation matrix\n    //\n    explicit inline Matrix4( const Transform3 & mat );\n\n    // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n    //\n    inline Matrix4( const Matrix3 & mat, const Vector3 &translateVec );\n\n    // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n    //\n    inline Matrix4( const Quat &unitQuat, const Vector3 &translateVec );\n\n    // Set all elements of a 4x4 matrix to the same scalar value\n    //\n    explicit inline Matrix4( float scalar );\n\n    // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Matrix4( const floatInVec &scalar );\n\n    // Assign one 4x4 matrix to another\n    //\n    inline Matrix4 & operator =( const Matrix4 & mat );\n\n    // Set the upper-left 3x3 submatrix\n    // NOTE:\n    // This function does not change the bottom row elements.\n    //\n    inline Matrix4 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 4x4 matrix\n    //\n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // NOTE:\n    // This function does not change the bottom row elements.\n    //\n    inline Matrix4 & setTranslation( const Vector3 &translateVec );\n\n    // Get the translation component of a 4x4 matrix\n    //\n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 4x4 matrix\n    //\n    inline Matrix4 & setCol0( const Vector4 &col0 );\n\n    // Set column 1 of a 4x4 matrix\n    //\n    inline Matrix4 & setCol1( const Vector4 &col1 );\n\n    // Set column 2 of a 4x4 matrix\n    //\n    inline Matrix4 & setCol2( const Vector4 &col2 );\n\n    // Set column 3 of a 4x4 matrix\n    //\n    inline Matrix4 & setCol3( const Vector4 &col3 );\n\n    // Get column 0 of a 4x4 matrix\n    //\n    inline const Vector4 getCol0( ) const;\n\n    // Get column 1 of a 4x4 matrix\n    //\n    inline const Vector4 getCol1( ) const;\n\n    // Get column 2 of a 4x4 matrix\n    //\n    inline const Vector4 getCol2( ) const;\n\n    // Get column 3 of a 4x4 matrix\n    //\n    inline const Vector4 getCol3( ) const;\n\n    // Set the column of a 4x4 matrix referred to by the specified index\n    //\n    inline Matrix4 & setCol( int col, const Vector4 &vec );\n\n    // Set the row of a 4x4 matrix referred to by the specified index\n    //\n    inline Matrix4 & setRow( int row, const Vector4 &vec );\n\n    // Get the column of a 4x4 matrix referred to by the specified index\n    //\n    inline const Vector4 getCol( int col ) const;\n\n    // Get the row of a 4x4 matrix referred to by the specified index\n    //\n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    //\n    inline Vector4 & operator []( int col );\n\n    // Subscripting operator to get a column\n    //\n    inline const Vector4 operator []( int col ) const;\n\n    // Set the element of a 4x4 matrix referred to by column and row indices\n    //\n    inline Matrix4 & setElem( int col, int row, float val );\n\n    // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type)\n    //\n    inline Matrix4 & setElem( int col, int row, const floatInVec &val );\n\n    // Get the element of a 4x4 matrix referred to by column and row indices\n    //\n    inline const floatInVec getElem( int col, int row ) const;\n\n    // Add two 4x4 matrices\n    //\n    inline const Matrix4 operator +( const Matrix4 & mat ) const;\n\n    // Subtract a 4x4 matrix from another 4x4 matrix\n    //\n    inline const Matrix4 operator -( const Matrix4 & mat ) const;\n\n    // Negate all elements of a 4x4 matrix\n    //\n    inline const Matrix4 operator -( ) const;\n\n    // Multiply a 4x4 matrix by a scalar\n    //\n    inline const Matrix4 operator *( float scalar ) const;\n\n    // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type)\n    //\n    inline const Matrix4 operator *( const floatInVec &scalar ) const;\n\n    // Multiply a 4x4 matrix by a 4-D vector\n    //\n    inline const Vector4 operator *( const Vector4 &vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D vector\n    //\n    inline const Vector4 operator *( const Vector3 &vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D point\n    //\n    inline const Vector4 operator *( const Point3 &pnt ) const;\n\n    // Multiply two 4x4 matrices\n    //\n    inline const Matrix4 operator *( const Matrix4 & mat ) const;\n\n    // Multiply a 4x4 matrix by a 3x4 transformation matrix\n    //\n    inline const Matrix4 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and addition with a 4x4 matrix\n    //\n    inline Matrix4 & operator +=( const Matrix4 & mat );\n\n    // Perform compound assignment and subtraction by a 4x4 matrix\n    //\n    inline Matrix4 & operator -=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    //\n    inline Matrix4 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    //\n    inline Matrix4 & operator *=( const floatInVec &scalar );\n\n    // Perform compound assignment and multiplication by a 4x4 matrix\n    //\n    inline Matrix4 & operator *=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    //\n    inline Matrix4 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 4x4 matrix\n    //\n    static inline const Matrix4 identity( );\n\n    // Construct a 4x4 matrix to rotate around the x axis\n    //\n    static inline const Matrix4 rotationX( float radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis\n    //\n    static inline const Matrix4 rotationY( float radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis\n    //\n    static inline const Matrix4 rotationZ( float radians );\n\n    // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type)\n    //\n    static inline const Matrix4 rotationX( const floatInVec &radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type)\n    //\n    static inline const Matrix4 rotationY( const floatInVec &radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type)\n    //\n    static inline const Matrix4 rotationZ( const floatInVec &radians );\n\n    // Construct a 4x4 matrix to rotate around the x, y, and z axes\n    //\n    static inline const Matrix4 rotationZYX( const Vector3 &radiansXYZ );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n    //\n    static inline const Matrix4 rotation( float radians, const Vector3 &unitVec );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    //\n    static inline const Matrix4 rotation( const floatInVec &radians, const Vector3 &unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    //\n    static inline const Matrix4 rotation( const Quat &unitQuat );\n\n    // Construct a 4x4 matrix to perform scaling\n    //\n    static inline const Matrix4 scale( const Vector3 &scaleVec );\n\n    // Construct a 4x4 matrix to perform translation\n    //\n    static inline const Matrix4 translation( const Vector3 &translateVec );\n\n    // Construct viewing matrix based on eye, position looked at, and up direction\n    //\n    static inline const Matrix4 lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec );\n\n    // Construct a perspective projection matrix\n    //\n    static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar );\n\n    // Construct a perspective projection matrix based on frustum\n    //\n    static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar );\n\n    // Construct an orthographic projection matrix\n    //\n    static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Multiply a 4x4 matrix by a scalar\n//\ninline const Matrix4 operator *( float scalar, const Matrix4 & mat );\n\n// Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type)\n//\ninline const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat );\n\n// Append (post-multiply) a scale transformation to a 4x4 matrix\n// NOTE:\n// Faster than creating and multiplying a scale transformation matrix.\n//\ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n// NOTE:\n// Faster than creating and multiplying a scale transformation matrix.\n//\ninline const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat );\n\n// Multiply two 4x4 matrices per element\n//\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );\n\n// Compute the absolute value of a 4x4 matrix per element\n//\ninline const Matrix4 absPerElem( const Matrix4 & mat );\n\n// Transpose of a 4x4 matrix\n//\ninline const Matrix4 transpose( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix\n// NOTE:\n// Result is unpredictable when the determinant of mat is equal to or near 0.\n//\ninline const Matrix4 inverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n// NOTE:\n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n// The result is unpredictable when the determinant of mat is equal to or near 0.\n//\ninline const Matrix4 affineInverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n// NOTE:\n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n//\ninline const Matrix4 orthoInverse( const Matrix4 & mat );\n\n// Determinant of a 4x4 matrix\n//\ninline const floatInVec determinant( const Matrix4 & mat );\n\n// Conditionally select between two 4x4 matrices\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 );\n\n// Conditionally select between two 4x4 matrices (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4x4 matrix\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Matrix4 & mat );\n\n// Print a 4x4 matrix and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Matrix4 & mat, const char * name );\n\n#endif\n\n// A 3x4 transformation matrix in array-of-structures format\n//\n_VECTORMATH_ALIGNED_TYPE_1 class Transform3 {\n\nprivate:\n\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n    Vector3 mCol3;\n\npublic:\n\n    // Default constructor; does no initialization\n    //\n    inline Transform3( ) { };\n\n    // Copy a 3x4 transformation matrix\n    //\n    inline Transform3( const Transform3 & tfrm );\n\n    // Construct a 3x4 transformation matrix containing the specified columns\n    //\n    inline Transform3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3 );\n\n    // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n    //\n    inline Transform3( const Matrix3 & tfrm, const Vector3 &translateVec );\n\n    // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n    //\n    inline Transform3( const Quat &unitQuat, const Vector3 &translateVec );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value\n    //\n    explicit inline Transform3( float scalar );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type)\n    //\n    explicit inline Transform3( const floatInVec &scalar );\n\n    // Assign one 3x4 transformation matrix to another\n    //\n    inline Transform3 & operator =( const Transform3 & tfrm );\n\n    // Set the upper-left 3x3 submatrix\n    //\n    inline Transform3 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n    //\n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    //\n    inline Transform3 & setTranslation( const Vector3 &translateVec );\n\n    // Get the translation component of a 3x4 transformation matrix\n    //\n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 3x4 transformation matrix\n    //\n    inline Transform3 & setCol0( const Vector3 &col0 );\n\n    // Set column 1 of a 3x4 transformation matrix\n    //\n    inline Transform3 & setCol1( const Vector3 &col1 );\n\n    // Set column 2 of a 3x4 transformation matrix\n    //\n    inline Transform3 & setCol2( const Vector3 &col2 );\n\n    // Set column 3 of a 3x4 transformation matrix\n    //\n    inline Transform3 & setCol3( const Vector3 &col3 );\n\n    // Get column 0 of a 3x4 transformation matrix\n    //\n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x4 transformation matrix\n    //\n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x4 transformation matrix\n    //\n    inline const Vector3 getCol2( ) const;\n\n    // Get column 3 of a 3x4 transformation matrix\n    //\n    inline const Vector3 getCol3( ) const;\n\n    // Set the column of a 3x4 transformation matrix referred to by the specified index\n    //\n    inline Transform3 & setCol( int col, const Vector3 &vec );\n\n    // Set the row of a 3x4 transformation matrix referred to by the specified index\n    //\n    inline Transform3 & setRow( int row, const Vector4 &vec );\n\n    // Get the column of a 3x4 transformation matrix referred to by the specified index\n    //\n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x4 transformation matrix referred to by the specified index\n    //\n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    //\n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    //\n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices\n    //\n    inline Transform3 & setElem( int col, int row, float val );\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type)\n    //\n    inline Transform3 & setElem( int col, int row, const floatInVec &val );\n\n    // Get the element of a 3x4 transformation matrix referred to by column and row indices\n    //\n    inline const floatInVec getElem( int col, int row ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D vector\n    //\n    inline const Vector3 operator *( const Vector3 &vec ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D point\n    //\n    inline const Point3 operator *( const Point3 &pnt ) const;\n\n    // Multiply two 3x4 transformation matrices\n    //\n    inline const Transform3 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    //\n    inline Transform3 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 3x4 transformation matrix\n    //\n    static inline const Transform3 identity( );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis\n    //\n    static inline const Transform3 rotationX( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis\n    //\n    static inline const Transform3 rotationY( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis\n    //\n    static inline const Transform3 rotationZ( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type)\n    //\n    static inline const Transform3 rotationX( const floatInVec &radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type)\n    //\n    static inline const Transform3 rotationY( const floatInVec &radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type)\n    //\n    static inline const Transform3 rotationZ( const floatInVec &radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n    //\n    static inline const Transform3 rotationZYX( const Vector3 &radiansXYZ );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n    //\n    static inline const Transform3 rotation( float radians, const Vector3 &unitVec );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    //\n    static inline const Transform3 rotation( const floatInVec &radians, const Vector3 &unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    //\n    static inline const Transform3 rotation( const Quat &unitQuat );\n\n    // Construct a 3x4 transformation matrix to perform scaling\n    //\n    static inline const Transform3 scale( const Vector3 &scaleVec );\n\n    // Construct a 3x4 transformation matrix to perform translation\n    //\n    static inline const Transform3 translation( const Vector3 &translateVec );\n\n} _VECTORMATH_ALIGNED_TYPE_2 ;\n\n// Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE:\n// Faster than creating and multiplying a scale transformation matrix.\n//\ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE:\n// Faster than creating and multiplying a scale transformation matrix.\n//\ninline const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm );\n\n// Multiply two 3x4 transformation matrices per element\n//\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );\n\n// Compute the absolute value of a 3x4 transformation matrix per element\n//\ninline const Transform3 absPerElem( const Transform3 & tfrm );\n\n// Inverse of a 3x4 transformation matrix\n// NOTE:\n// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n//\ninline const Transform3 inverse( const Transform3 & tfrm );\n\n// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n// NOTE:\n// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n//\ninline const Transform3 orthoInverse( const Transform3 & tfrm );\n\n// Conditionally select between two 3x4 transformation matrices\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n//\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 );\n\n// Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type)\n// NOTE:\n// This function uses a conditional select instruction to avoid a branch.\n//\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x4 transformation matrix\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Transform3 & tfrm );\n\n// Print a 3x4 transformation matrix and an associated string identifier\n// NOTE:\n// Function is only defined when _VECTORMATH_DEBUG is defined.\n//\ninline void print( const Transform3 & tfrm, const char * name );\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/c/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_H\n#define _VECTORMATH_AOS_C_H\n\n#if defined(__SPU__)\n\t#include \"../spu/c/vectormath_aos.h\"\n\t#define VMATH_SPU 1\n#elif defined(__ALTIVEC__)\n\t#include \"../ppu/c/vectormath_aos.h\"\n\t#define VMATH_ALTIVEC 1\n#else\n\t#include \"../scalar/c/vectormath_aos.h\"\n\t#define VMATH_SCALAR 1\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/c/vectormath_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_V_H\n#define _VECTORMATH_AOS_C_V_H\n\n#if defined(__SPU__)\n\t#include \"../spu/c/vectormath_aos_v.h\"\n\t#define VMATH_SPU 1\n#elif defined(__ALTIVEC__)\n\t#include \"../ppu/c/vectormath_aos_v.h\"\n\t#define VMATH_ALTIVEC 1\n#else\n\t#include \"../scalar/c/vectormath_aos_v.h\"\n\t#define VMATH_SCALAR 1\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/c/vectormath_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_C_H\n#define _VECTORMATH_SOA_C_H\n\n#if defined(__SPU__)\n\t#include \"../spu/c/vectormath_soa.h\"\n\t#define VMATH_SPU 1\n#elif defined(__ALTIVEC__)\n\t#include \"../ppu/c/vectormath_soa.h\"\n\t#define VMATH_ALTIVEC 1\n#else\n\t#error \"Vectormath library not implemented!\"\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/c/vectormath_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_C_V_H\n#define _VECTORMATH_SOA_C_V_H\n\n#if defined(__SPU__)\n\t#include \"../spu/c/vectormath_soa_v.h\"\n\t#define VMATH_SPU 1\n#elif defined(__ALTIVEC__)\n\t#include \"../ppu/c/vectormath_soa_v.h\"\n\t#define VMATH_ALTIVEC 1\n#else\n\t#error \"Vectormath library not implemented!\"\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/cpp/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_CPP_H\n#define _VECTORMATH_AOS_CPP_H\n\n#if defined(__SPU__)\n\t#include \"../spu/cpp/vectormath_aos.h\"\n\t#define VMATH_SPU 1\n#elif defined(__ALTIVEC__)\n\t#include \"../ppu/cpp/vectormath_aos.h\"\n\t#define VMATH_ALTIVEC 1\n#elif defined(__SSE__)\n\t#include \"../SSE/cpp/vectormath_aos.h\"\n\t#define VMATH_SSE 1\n#else\n\t#include \"../scalar/cpp/vectormath_aos.h\"\n\t#define VMATH_SCALAR 1\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/cpp/vectormath_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_CPP_H\n#define _VECTORMATH_SOA_CPP_H\n\n#if defined(__SPU__)\n\t#include \"../spu/cpp/vectormath_soa.h\"\n\t#define VMATH_SPU 1\n#elif defined(__ALTIVEC__)\n\t#include \"../ppu/cpp/vectormath_soa.h\"\n\t#define VMATH_ALTIVEC 1\n#else\n\t#error \"Vectormath library not implemented!\"\n#endif\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_C_H\n#define _VECTORMATH_MAT_AOS_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X })     \n#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z })\n#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y })\n#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( &result->col0, &mat->col0 );\n    vmathV3Copy( &result->col1, &mat->col1 );\n    vmathV3Copy( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar )\n{\n    vmathV3MakeFromScalar( &result->col0, scalar );\n    vmathV3MakeFromScalar( &result->col1, scalar );\n    vmathV3MakeFromScalar( &result->col2, scalar );\n}\n\nstatic inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat )\n{\n    vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    vec_uint4 select_x = _VECTORMATH_MASK_0xF000;\n    vec_uint4 select_z = _VECTORMATH_MASK_0x00F0;\n    xyzw_2 = vec_add( unitQuat->vec128, unitQuat->vec128 );\n    wwww = vec_splat( unitQuat->vec128, 3 );\n    yzxw = vec_perm( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_PERM_YZXW );\n    zxyw = vec_perm( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_PERM_ZXYW );\n    yzxw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_YZXW );\n    zxyw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_ZXYW );\n    tmp0 = vec_madd( yzxw_2, wwww, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_nmsub( yzxw, yzxw_2, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    tmp2 = vec_madd( yzxw, xyzw_2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp0 = vec_madd( zxyw, xyzw_2, tmp0 );\n    tmp1 = vec_nmsub( zxyw, zxyw_2, tmp1 );\n    tmp2 = vec_nmsub( zxyw_2, wwww, tmp2 );\n    tmp3 = vec_sel( tmp0, tmp1, select_x );\n    tmp4 = vec_sel( tmp1, tmp2, select_x );\n    tmp5 = vec_sel( tmp2, tmp0, select_x );\n    result->col0.vec128 = vec_sel( tmp3, tmp2, select_z );\n    result->col1.vec128 = vec_sel( tmp4, tmp0, select_z );\n    result->col2.vec128 = vec_sel( tmp5, tmp1, select_z );\n}\n\nstatic inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n    vmathV3Copy( &result->col1, _col1 );\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *_col0 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *_col1 )\n{\n    vmathV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec )\n{\n    vmathV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec )\n{\n    vmathV3SetElem( &result->col0, row, vmathV3GetElem( vec, 0 ) );\n    vmathV3SetElem( &result->col1, row, vmathV3GetElem( vec, 1 ) );\n    vmathV3SetElem( &result->col2, row, vmathV3GetElem( vec, 2 ) );\n}\n\nstatic inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val )\n{\n    VmathVector3 tmpV3_0;\n    vmathM3GetCol( &tmpV3_0, result, col );\n    vmathV3SetElem( &tmpV3_0, row, val );\n    vmathM3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row )\n{\n    VmathVector3 tmpV3_0;\n    vmathM3GetCol( &tmpV3_0, mat, col );\n    return vmathV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col )\n{\n    vmathV3Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row )\n{\n    vmathV3MakeFromElems( result, vmathV3GetElem( &mat->col0, row ), vmathV3GetElem( &mat->col1, row ), vmathV3GetElem( &mat->col2, row ) );\n}\n\nstatic inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vec_float4 tmp0, tmp1, res0, res1, res2;\n    tmp0 = vec_mergeh( mat->col0.vec128, mat->col2.vec128 );\n    tmp1 = vec_mergel( mat->col0.vec128, mat->col2.vec128 );\n    res0 = vec_mergeh( tmp0, mat->col1.vec128 );\n    res1 = vec_perm( tmp0, mat->col1.vec128, _VECTORMATH_PERM_ZBWX );\n    res2 = vec_perm( tmp1, mat->col1.vec128, _VECTORMATH_PERM_XCYX );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    tmp2 = _vmathVfCross( mat->col0.vec128, mat->col1.vec128 );\n    tmp0 = _vmathVfCross( mat->col1.vec128, mat->col2.vec128 );\n    tmp1 = _vmathVfCross( mat->col2.vec128, mat->col0.vec128 );\n    dot = _vmathVfDot3( tmp2, mat->col2.vec128 );\n    dot = vec_splat( dot, 0 );\n    invdet = recipf4( dot );\n    tmp3 = vec_mergeh( tmp0, tmp2 );\n    tmp4 = vec_mergel( tmp0, tmp2 );\n    inv0 = vec_mergeh( tmp3, tmp1 );\n    inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX );\n    inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX );\n    inv0 = vec_madd( inv0, invdet, zero );\n    inv1 = vec_madd( inv1, invdet, zero );\n    inv2 = vec_madd( inv2, invdet, zero );\n    result->col0.vec128 = inv0;\n    result->col1.vec128 = inv1;\n    result->col2.vec128 = inv2;\n}\n\nstatic inline float vmathM3Determinant( const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3Cross( &tmpV3_0, &mat->col0, &mat->col1 );\n    return vmathV3Dot( &mat->col2, &tmpV3_0 );\n}\n\nstatic inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3Add( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3Sub( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Neg( &result->col0, &mat->col0 );\n    vmathV3Neg( &result->col1, &mat->col1 );\n    vmathV3Neg( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3AbsPerElem( &result->col0, &mat->col0 );\n    vmathV3AbsPerElem( &result->col1, &mat->col1 );\n    vmathV3AbsPerElem( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar )\n{\n    vmathV3ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathV3ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathV3ScalarMul( &result->col2, &mat->col2, scalar );\n}\n\nstatic inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec )\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec->vec128, 0 );\n    yyyy = vec_splat( vec->vec128, 1 );\n    zzzz = vec_splat( vec->vec128, 2 );\n    res = vec_madd( mat->col0.vec128, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( mat->col1.vec128, yyyy, res );\n    res = vec_madd( mat->col2.vec128, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    VmathMatrix3 tmpResult;\n    vmathM3MulV3( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathM3MulV3( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathM3MulV3( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3MakeIdentity( VmathMatrix3 *result )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    vmathV3MakeXAxis( &result->col0 );\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    result->col0.vec128 = res0;\n    vmathV3MakeYAxis( &result->col1 );\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    vmathV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ )\n{\n    VmathVector4 tmpV4_0;\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    vmathV4MakeFromV3Scalar( &tmpV4_0, radiansXYZ, 0.0f );\n    angles = tmpV4_0.vec128;\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n    Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F );\n    Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX );\n    Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_madd( Z0, Y1, zero );\n    result->col0.vec128 = vec_madd( Z0, Y0, zero );\n    result->col1.vec128 = vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) );\n    result->col2.vec128 = vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) );\n}\n\nstatic inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    axis = unitVec->vec128;\n    sincosf4( (vec_float4){radians,radians,radians,radians}, &s, &c );\n    xxxx = vec_splat( axis, 0 );\n    yyyy = vec_splat( axis, 1 );\n    zzzz = vec_splat( axis, 2 );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    axisS = vec_madd( axis, s, zero );\n    negAxisS = negatef4( axisS );\n    tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX );\n    tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX );\n    tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX );\n    tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 );\n    tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 );\n    tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 );\n    result->col0.vec128 = vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 );\n    result->col1.vec128 = vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 );\n    result->col2.vec128 = vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 );\n}\n\nstatic inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat )\n{\n    vmathM3MakeFromQ( result, unitQuat );\n}\n\nstatic inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec )\n{\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    result->col0.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0xF000 );\n    result->col1.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x0F00 );\n    result->col2.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x00F0 );\n}\n\nstatic inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec )\n{\n    vmathV3ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) );\n    vmathV3ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) );\n    vmathV3ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) );\n}\n\nstatic inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat )\n{\n    vmathV3MulPerElem( &result->col0, &mat->col0, scaleVec );\n    vmathV3MulPerElem( &result->col1, &mat->col1, scaleVec );\n    vmathV3MulPerElem( &result->col2, &mat->col2, scaleVec );\n}\n\nstatic inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 )\n{\n    vmathV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM3Print( const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathM3GetRow( &tmpV3_0, mat, 0 );\n    vmathV3Print( &tmpV3_0 );\n    vmathM3GetRow( &tmpV3_1, mat, 1 );\n    vmathV3Print( &tmpV3_1 );\n    vmathM3GetRow( &tmpV3_2, mat, 2 );\n    vmathV3Print( &tmpV3_2 );\n}\n\nstatic inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathM3Print( mat );\n}\n\n#endif\n\nstatic inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( &result->col0, &mat->col0 );\n    vmathV4Copy( &result->col1, &mat->col1 );\n    vmathV4Copy( &result->col2, &mat->col2 );\n    vmathV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar )\n{\n    vmathV4MakeFromScalar( &result->col0, scalar );\n    vmathV4MakeFromScalar( &result->col1, scalar );\n    vmathV4MakeFromScalar( &result->col2, scalar );\n    vmathV4MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat )\n{\n    vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, &mat->col3, 1.0f );\n}\n\nstatic inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *_col0, const VmathVector4 *_col1, const VmathVector4 *_col2, const VmathVector4 *_col3 )\n{\n    vmathV4Copy( &result->col0, _col0 );\n    vmathV4Copy( &result->col1, _col1 );\n    vmathV4Copy( &result->col2, _col2 );\n    vmathV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec )\n{\n    vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec )\n{\n    VmathMatrix3 mat;\n    vmathM3MakeFromQ( &mat, unitQuat );\n    vmathV4MakeFromV3Scalar( &result->col0, &mat.col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat.col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat.col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *_col0 )\n{\n    vmathV4Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *_col1 )\n{\n    vmathV4Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *_col2 )\n{\n    vmathV4Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *_col3 )\n{\n    vmathV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec )\n{\n    vmathV4Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec )\n{\n    vmathV4SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) );\n    vmathV4SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) );\n    vmathV4SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) );\n    vmathV4SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val )\n{\n    VmathVector4 tmpV3_0;\n    vmathM4GetCol( &tmpV3_0, result, col );\n    vmathV4SetElem( &tmpV3_0, row, val );\n    vmathM4SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row )\n{\n    VmathVector4 tmpV4_0;\n    vmathM4GetCol( &tmpV4_0, mat, col );\n    return vmathV4GetElem( &tmpV4_0, row );\n}\n\nstatic inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col3 );\n}\n\nstatic inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col )\n{\n    vmathV4Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row )\n{\n    vmathV4MakeFromElems( result, vmathV4GetElem( &mat->col0, row ), vmathV4GetElem( &mat->col1, row ), vmathV4GetElem( &mat->col2, row ), vmathV4GetElem( &mat->col3, row ) );\n}\n\nstatic inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3;\n    tmp0 = vec_mergeh( mat->col0.vec128, mat->col2.vec128 );\n    tmp1 = vec_mergeh( mat->col1.vec128, mat->col3.vec128 );\n    tmp2 = vec_mergel( mat->col0.vec128, mat->col2.vec128 );\n    tmp3 = vec_mergel( mat->col1.vec128, mat->col3.vec128 );\n    res0 = vec_mergeh( tmp0, tmp1 );\n    res1 = vec_mergel( tmp0, tmp1 );\n    res2 = vec_mergeh( tmp2, tmp3 );\n    res3 = vec_mergel( tmp2, tmp3 );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n    result->col3.vec128 = res3;\n}\n\nstatic inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vector float in0, in1, in2, in3;\n    vector float tmp0, tmp1, tmp2, tmp3;\n    vector float cof0, cof1, cof2, cof3;\n    vector float t0, t1, t2, t3;\n    vector float t01, t02, t03, t12, t23;\n    vector float t1r, t2r;\n    vector float t01r, t02r, t03r, t12r, t23r;\n    vector float t1r3, t1r3r;\n    vector float det, det0, det1, det2, det3, invdet;\n    vector float vzero = (vector float){0.0};\n    in0 = mat->col0.vec128;\n    in1 = mat->col1.vec128;\n    in2 = mat->col2.vec128;\n    in3 = mat->col3.vec128;\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC);\t/* A E C G */\n    tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC);\t/* I M K O */\n    tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD);\t/* B F D H */\n    tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD);\t/* J N L P */\n    t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB);\t/* A E I M */\n    t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB);\t/* J N B F */\n    t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD);\t/* C G K O */\n    t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD);\t/* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = vec_madd(t2, t3, vzero);\t\t/* CL GP KD OH */\n    t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ);\t/* GP CL OH KD */\n    cof0 = vec_nmsub(t1, t23, vzero);\t\t/* -(JGP NCL FOH BKD) */\n    cof1 = vec_nmsub(t0, t23, vzero);\t\t/* -(AGP ECL IOH MKD) */\n    t23r = vec_sld(t23, t23, 8);\t\t\t/* OH KD GP CL */\n    cof0 = vec_madd(t1, t23r, cof0);\t\t/* JOH NKD BGP FCL + cof0 */\n    cof1 = vec_madd(t0, t23r, cof1);\t\t/* AOH EKD IGP MCL + cof1 */\n    cof1 = vec_sld(cof1, cof1, 8);\t\t/* IGP MCL AOH EKD - IOH MKD AGP ECL */\n    t12 = vec_madd(t1, t2, vzero);\t\t/* JC NG BK FO */\n    t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ);\t/* NG JC FO BK */\n    cof0 = vec_madd(t3, t12, cof0);\t\t/* LNG PJC DFO HBK + cof0 */\n    cof3 = vec_madd(t0, t12, vzero);\t\t/* ANG EJC IFO MBK */\n    t12r = vec_sld(t12, t12, 8);\t\t\t/* FO BK NG JC */\n    cof0 = vec_nmsub(t3, t12r, cof0);\t\t/* cof0 - LFO PBK DNG HJC */\n    cof3 = vec_nmsub(t0, t12r, cof3);\t\t/* cof3 - AFO EBK ING MJC */\n    cof3 = vec_sld(cof3, cof3, 8);\t\t/* ING MJC AFO EBK - IFO MBK ANG EJC */\n    t1r = vec_sld(t1, t1, 8);\t\t\t/* B F J N */\n    t2r = vec_sld(t2, t2, 8);\t\t\t/* K O C G */\n    t1r3 = vec_madd(t1r, t3, vzero);\t\t/* BL FP JD NH */\n    t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ);\t/* FP BL NH JD */\n    cof0 = vec_madd(t2r, t1r3, cof0);\t\t/* KFP OBL CNH GJD + cof0 */\n    cof2 = vec_madd(t0, t1r3, vzero);\t\t/* AFP EBL INH MJD */\n    t1r3r = vec_sld(t1r3, t1r3, 8);\t\t/* NH JD FP BL */\n    cof0 = vec_nmsub(t2r, t1r3r, cof0);\t\t/* cof0 - KNH OJD CFP GBL */\n    cof2 = vec_nmsub(t0, t1r3r, cof2);\t\t/* cof2 - ANH EJD IFP MBL */\n    cof2 = vec_sld(cof2, cof2, 8);\t\t/* IFP MBL ANH EJD - INH MJD AFP EBL */\n    t01 = vec_madd(t0, t1, vzero);\t\t/* AJ EN IB MF */\n    t01 = vec_perm(t01, t01, _VECTORMATH_PERM_YXWZ);\t/* EN AJ MF IB */\n    cof2 = vec_nmsub(t3, t01, cof2);\t\t/* cof2 - LEN PAJ DMF HIB */\n    cof3 = vec_madd(t2r, t01, cof3);\t\t/* KEN OAJ CMF GIB + cof3 */ \n    t01r = vec_sld(t01, t01, 8);\t\t\t/* MF IB EN AJ */\n    cof2 = vec_madd(t3, t01r, cof2);\t\t/* LMF PIB DEN HAJ + cof2 */\n    cof3 = vec_nmsub(t2r, t01r, cof3);\t\t/* cof3 - KMF OIB CEN GAJ */\n    t03 = vec_madd(t0, t3, vzero);\t\t/* AL EP ID MH */\n    t03 = vec_perm(t03, t03, _VECTORMATH_PERM_YXWZ);\t/* EP AL MH ID */\n    cof1 = vec_nmsub(t2r, t03, cof1);\t\t/* cof1 - KEP OAL CMH GID */\n    cof2 = vec_madd(t1, t03, cof2);\t\t/* JEP NAL BMH FID + cof2 */\n    t03r = vec_sld(t03, t03, 8);\t\t\t/* MH ID EP AL */\n    cof1 = vec_madd(t2r, t03r, cof1);\t\t/* KMH OID CEP GAL + cof1 */\n    cof2 = vec_nmsub(t1, t03r, cof2);\t\t/* cof2 - JMH NID BEP FAL */ \n    t02 = vec_madd(t0, t2r, vzero);\t\t/* AK EO IC MG */\n    t02 = vec_perm(t02, t02, _VECTORMATH_PERM_YXWZ);\t/* E0 AK MG IC */\n    cof1 = vec_madd(t3, t02, cof1);\t\t/* LEO PAK DMG HIC + cof1 */\n    cof3 = vec_nmsub(t1, t02, cof3);\t\t/* cof3 - JEO NAK BMG FIC */\n    t02r = vec_sld(t02, t02, 8);\t\t\t/* MG IC EO AK */\n    cof1 = vec_nmsub(t3, t02r, cof1);\t\t/* cof1 - LMG PIC DEO HAK */\n    cof3 = vec_madd(t1, t02r, cof3);\t\t/* JMG NIC BEO FAK + cof3 */\n    /* Compute the determinant of the matrix \n     *\n     * det = sum_across(t0 * cof0);\n     *\n     * We perform a sum across the entire vector so that \n     * we don't have to splat the result when multiplying the\n     * cofactors by the inverse of the determinant.\n     */\n    det  = vec_madd(t0, cof0, vzero);\n    det0 = vec_splat(det, 0);\n    det1 = vec_splat(det, 1);\n    det2 = vec_splat(det, 2);\n    det3 = vec_splat(det, 3);\n    det  = vec_add(det0, det1);\n    det2 = vec_add(det2, det3);\n    det  = vec_add(det, det2);\n    /* Compute the reciprocal of the determinant.\n     */\n    invdet = recipf4(det);\n    /* Multiply the cofactors by the reciprocal of the determinant.\n     */ \n    result->col0.vec128 = vec_madd(cof0, invdet, vzero);\n    result->col1.vec128 = vec_madd(cof1, invdet, vzero);\n    result->col2.vec128 = vec_madd(cof2, invdet, vzero);\n    result->col3.vec128 = vec_madd(cof3, invdet, vzero);\n}\n\nstatic inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathTransform3 affineMat, tmpT3_0;\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathT3Inverse( &tmpT3_0, &affineMat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathTransform3 affineMat, tmpT3_0;\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathT3OrthoInverse( &tmpT3_0, &affineMat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline float vmathM4Determinant( const VmathMatrix4 *mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vector float in0, in1, in2, in3;\n    vector float tmp0, tmp1, tmp2, tmp3;\n    vector float cof0;\n    vector float t0, t1, t2, t3;\n    vector float t12, t23;\n    vector float t1r, t2r;\n    vector float t12r, t23r;\n    vector float t1r3, t1r3r;\n    vector float vzero = (vector float){0.0};\n    union { vec_float4 v; float s[4]; } tmp;\n    in0 = mat->col0.vec128;\n    in1 = mat->col1.vec128;\n    in2 = mat->col2.vec128;\n    in3 = mat->col3.vec128;\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC);\t/* A E C G */\n    tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC);\t/* I M K O */\n    tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD);\t/* B F D H */\n    tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD);\t/* J N L P */\n    t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB);\t/* A E I M */\n    t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB);\t/* J N B F */\n    t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD);\t/* C G K O */\n    t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD);\t/* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = vec_madd(t2, t3, vzero);\t\t/* CL GP KD OH */\n    t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ);\t/* GP CL OH KD */\n    cof0 = vec_nmsub(t1, t23, vzero);\t\t/* -(JGP NCL FOH BKD) */\n    t23r = vec_sld(t23, t23, 8);\t\t\t/* OH KD GP CL */\n    cof0 = vec_madd(t1, t23r, cof0);\t\t/* JOH NKD BGP FCL + cof0 */\n    t12 = vec_madd(t1, t2, vzero);\t\t/* JC NG BK FO */\n    t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ);\t/* NG JC FO BK */\n    cof0 = vec_madd(t3, t12, cof0);\t\t/* LNG PJC DFO HBK + cof0 */\n    t12r = vec_sld(t12, t12, 8);\t\t\t/* FO BK NG JC */\n    cof0 = vec_nmsub(t3, t12r, cof0);\t\t/* cof0 - LFO PBK DNG HJC */\n    t1r = vec_sld(t1, t1, 8);\t\t\t/* B F J N */\n    t2r = vec_sld(t2, t2, 8);\t\t\t/* K O C G */\n    t1r3 = vec_madd(t1r, t3, vzero);\t\t/* BL FP JD NH */\n    t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ);\t/* FP BL NH JD */\n    cof0 = vec_madd(t2r, t1r3, cof0);\t\t/* KFP OBL CNH GJD + cof0 */\n    t1r3r = vec_sld(t1r3, t1r3, 8);\t\t/* NH JD FP BL */\n    cof0 = vec_nmsub(t2r, t1r3r, cof0);\t\t/* cof0 - KNH OJD CFP GBL */\n    tmp.v = _vmathVfDot4(t0,cof0);\n    return tmp.s[0];\n}\n\nstatic inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4Add( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4Add( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4Sub( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4Sub( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Neg( &result->col0, &mat->col0 );\n    vmathV4Neg( &result->col1, &mat->col1 );\n    vmathV4Neg( &result->col2, &mat->col2 );\n    vmathV4Neg( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4AbsPerElem( &result->col0, &mat->col0 );\n    vmathV4AbsPerElem( &result->col1, &mat->col1 );\n    vmathV4AbsPerElem( &result->col2, &mat->col2 );\n    vmathV4AbsPerElem( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar )\n{\n    vmathV4ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathV4ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathV4ScalarMul( &result->col2, &mat->col2, scalar );\n    vmathV4ScalarMul( &result->col3, &mat->col3, scalar );\n}\n\nstatic inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec )\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz, wwww;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    xxxx = vec_splat( vec->vec128, 0 );\n    yyyy = vec_splat( vec->vec128, 1 );\n    zzzz = vec_splat( vec->vec128, 2 );\n    wwww = vec_splat( vec->vec128, 3 );\n    tmp0 = vec_madd( mat->col0.vec128, xxxx, zero );\n    tmp1 = vec_madd( mat->col1.vec128, yyyy, zero );\n    tmp0 = vec_madd( mat->col2.vec128, zzzz, tmp0 );\n    tmp1 = vec_madd( mat->col3.vec128, wwww, tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec )\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec->vec128, 0 );\n    yyyy = vec_splat( vec->vec128, 1 );\n    zzzz = vec_splat( vec->vec128, 2 );\n    res = vec_madd( mat->col0.vec128, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( mat->col1.vec128, yyyy, res );\n    res = vec_madd( mat->col2.vec128, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt )\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    xxxx = vec_splat( pnt->vec128, 0 );\n    yyyy = vec_splat( pnt->vec128, 1 );\n    zzzz = vec_splat( pnt->vec128, 2 );\n    tmp0 = vec_madd( mat->col0.vec128, xxxx, zero );\n    tmp1 = vec_madd( mat->col1.vec128, yyyy, zero );\n    tmp0 = vec_madd( mat->col2.vec128, zzzz, tmp0 );\n    tmp1 = vec_add( mat->col3.vec128, tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    VmathMatrix4 tmpResult;\n    vmathM4MulV4( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathM4MulV4( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathM4MulV4( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathM4MulV4( &tmpResult.col3, mat0, &mat1->col3 );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm1 )\n{\n    VmathMatrix4 tmpResult;\n    VmathPoint3 tmpP3_0;\n    vmathM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 );\n    vmathM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 );\n    vmathM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 );\n    vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathM4MulP3( &tmpResult.col3, mat, &tmpP3_0 );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4MakeIdentity( VmathMatrix4 *result )\n{\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 )\n{\n    vmathV4SetXYZ( &result->col0, &mat3->col0 );\n    vmathV4SetXYZ( &result->col1, &mat3->col1 );\n    vmathV4SetXYZ( &result->col2, &mat3->col2 );\n}\n\nstatic inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat )\n{\n    vmathV4GetXYZ( &result->col0, &mat->col0 );\n    vmathV4GetXYZ( &result->col1, &mat->col1 );\n    vmathV4GetXYZ( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec )\n{\n    vmathV4SetXYZ( &result->col3, translateVec );\n}\n\nstatic inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat )\n{\n    vmathV4GetXYZ( result, &mat->col3 );\n}\n\nstatic inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    vmathV4MakeXAxis( &result->col0 );\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    result->col0.vec128 = res0;\n    vmathV4MakeYAxis( &result->col1 );\n    result->col2.vec128 = res2;\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ )\n{\n    VmathVector4 tmpV4_0;\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    vmathV4MakeFromV3Scalar( &tmpV4_0, radiansXYZ, 0.0f );\n    angles = tmpV4_0.vec128;\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n    Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F );\n    Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX );\n    Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_madd( Z0, Y1, zero );\n    result->col0.vec128 = vec_madd( Z0, Y0, zero );\n    result->col1.vec128 = vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) );\n    result->col2.vec128 = vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    axis = unitVec->vec128;\n    sincosf4( (vec_float4){radians,radians,radians,radians}, &s, &c );\n    xxxx = vec_splat( axis, 0 );\n    yyyy = vec_splat( axis, 1 );\n    zzzz = vec_splat( axis, 2 );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    axisS = vec_madd( axis, s, zero );\n    negAxisS = negatef4( axisS );\n    tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX );\n    tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX );\n    tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX );\n    tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 );\n    tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 );\n    tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 );\n    zeroW = (vec_float4)_VECTORMATH_MASK_0x000F;\n    axis = vec_andc( axis, zeroW );\n    tmp0 = vec_andc( tmp0, zeroW );\n    tmp1 = vec_andc( tmp1, zeroW );\n    tmp2 = vec_andc( tmp2, zeroW );\n    result->col0.vec128 = vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 );\n    result->col1.vec128 = vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 );\n    result->col2.vec128 = vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat )\n{\n    VmathTransform3 tmpT3_0;\n    vmathT3MakeRotationQ( &tmpT3_0, unitQuat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec )\n{\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    result->col0.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0xF000 );\n    result->col1.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x0F00 );\n    result->col2.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x00F0 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec )\n{\n    vmathV4ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) );\n    vmathV4ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) );\n    vmathV4ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) );\n    vmathV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat )\n{\n    VmathVector4 scale4;\n    vmathV4MakeFromV3Scalar( &scale4, scaleVec, 1.0f );\n    vmathV4MulPerElem( &result->col0, &mat->col0, &scale4 );\n    vmathV4MulPerElem( &result->col1, &mat->col1, &scale4 );\n    vmathV4MulPerElem( &result->col2, &mat->col2, &scale4 );\n    vmathV4MulPerElem( &result->col3, &mat->col3, &scale4 );\n}\n\nstatic inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec )\n{\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec )\n{\n    VmathMatrix4 m4EyeFrame;\n    VmathVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1;\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathV3Normalize( &v3Y, upVec );\n    vmathP3Sub( &tmpV3_0, eyePos, lookAtPos );\n    vmathV3Normalize( &v3Z, &tmpV3_0 );\n    vmathV3Cross( &tmpV3_1, &v3Y, &v3Z );\n    vmathV3Normalize( &v3X, &tmpV3_1 );\n    vmathV3Cross( &v3Y, &v3Z, &v3X );\n    vmathV4MakeFromV3( &tmpV4_0, &v3X );\n    vmathV4MakeFromV3( &tmpV4_1, &v3Y );\n    vmathV4MakeFromV3( &tmpV4_2, &v3Z );\n    vmathV4MakeFromP3( &tmpV4_3, eyePos );\n    vmathM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 );\n    vmathM4OrthoInverse( result, &m4EyeFrame );\n}\n\nstatic inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    vec_float4 zero, col0, col1, col2, col3;\n    union { vec_float4 v; float s[4]; } tmp;\n    f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f );\n    rangeInv = 1.0f / ( zNear - zFar );\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    tmp.v = zero;\n    tmp.s[0] = f / aspect;\n    col0 = tmp.v;\n    tmp.v = zero;\n    tmp.s[1] = f;\n    col1 = tmp.v;\n    tmp.v = zero;\n    tmp.s[2] = ( zNear + zFar ) * rangeInv;\n    tmp.s[3] = -1.0f;\n    col2 = tmp.v;\n    tmp.v = zero;\n    tmp.s[2] = zNear * zFar * rangeInv * 2.0f;\n    col3 = tmp.v;\n    result->col0.vec128 = col0;\n    result->col1.vec128 = col1;\n    result->col2.vec128 = col2;\n    result->col3.vec128 = col3;\n}\n\nstatic inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff;\n    vec_float4 diagonal, column, near2;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    union { vec_float4 v; float s[4]; } l, f, r, n, b, t;\n    l.s[0] = left;\n    f.s[0] = zFar;\n    r.s[0] = right;\n    n.s[0] = zNear;\n    b.s[0] = bottom;\n    t.s[0] = top;\n    lbf = vec_mergeh( l.v, f.v );\n    rtn = vec_mergeh( r.v, n.v );\n    lbf = vec_mergeh( lbf, b.v );\n    rtn = vec_mergeh( rtn, t.v );\n    diff = vec_sub( rtn, lbf );\n    sum  = vec_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    near2 = vec_splat( n.v, 0 );\n    near2 = vec_add( near2, near2 );\n    diagonal = vec_madd( near2, inv_diff, zero );\n    column = vec_madd( sum, inv_diff, zero );\n    result->col0.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 );\n    result->col1.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 );\n    result->col2.vec128 = vec_sel( column, ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}), _VECTORMATH_MASK_0x000F );\n    result->col3.vec128 = vec_sel( zero, vec_madd( diagonal, vec_splat( f.v, 0 ), zero ), _VECTORMATH_MASK_0x00F0 );\n}\n\nstatic inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff, neg_inv_diff;\n    vec_float4 diagonal, column;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    union { vec_float4 v; float s[4]; } l, f, r, n, b, t;\n    l.s[0] = left;\n    f.s[0] = zFar;\n    r.s[0] = right;\n    n.s[0] = zNear;\n    b.s[0] = bottom;\n    t.s[0] = top;\n    lbf = vec_mergeh( l.v, f.v );\n    rtn = vec_mergeh( r.v, n.v );\n    lbf = vec_mergeh( lbf, b.v );\n    rtn = vec_mergeh( rtn, t.v );\n    diff = vec_sub( rtn, lbf );\n    sum  = vec_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    neg_inv_diff = negatef4( inv_diff );\n    diagonal = vec_add( inv_diff, inv_diff );\n    column = vec_madd( sum, vec_sel( neg_inv_diff, inv_diff, _VECTORMATH_MASK_0x00F0 ), zero );\n    result->col0.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 );\n    result->col1.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 );\n    result->col2.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0x00F0 );\n    result->col3.vec128 = vec_sel( column, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), _VECTORMATH_MASK_0x000F );\n}\n\nstatic inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 )\n{\n    vmathV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n    vmathV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM4Print( const VmathMatrix4 *mat )\n{\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathM4GetRow( &tmpV4_0, mat, 0 );\n    vmathV4Print( &tmpV4_0 );\n    vmathM4GetRow( &tmpV4_1, mat, 1 );\n    vmathV4Print( &tmpV4_1 );\n    vmathM4GetRow( &tmpV4_2, mat, 2 );\n    vmathV4Print( &tmpV4_2 );\n    vmathM4GetRow( &tmpV4_3, mat, 3 );\n    vmathV4Print( &tmpV4_3 );\n}\n\nstatic inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathM4Print( mat );\n}\n\n#endif\n\nstatic inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( &result->col0, &tfrm->col0 );\n    vmathV3Copy( &result->col1, &tfrm->col1 );\n    vmathV3Copy( &result->col2, &tfrm->col2 );\n    vmathV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar )\n{\n    vmathV3MakeFromScalar( &result->col0, scalar );\n    vmathV3MakeFromScalar( &result->col1, scalar );\n    vmathV3MakeFromScalar( &result->col2, scalar );\n    vmathV3MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2, const VmathVector3 *_col3 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n    vmathV3Copy( &result->col1, _col1 );\n    vmathV3Copy( &result->col2, _col2 );\n    vmathV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec )\n{\n    vmathT3SetUpper3x3( result, tfrm );\n    vmathT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec )\n{\n    VmathMatrix3 tmpM3_0;\n    vmathM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathT3SetUpper3x3( result, &tmpM3_0 );\n    vmathT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *_col0 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *_col1 )\n{\n    vmathV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *_col3 )\n{\n    vmathV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec )\n{\n    vmathV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec )\n{\n    vmathV3SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) );\n    vmathV3SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) );\n    vmathV3SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) );\n    vmathV3SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val )\n{\n    VmathVector3 tmpV3_0;\n    vmathT3GetCol( &tmpV3_0, result, col );\n    vmathV3SetElem( &tmpV3_0, row, val );\n    vmathT3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row )\n{\n    VmathVector3 tmpV3_0;\n    vmathT3GetCol( &tmpV3_0, tfrm, col );\n    return vmathV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col0 );\n}\n\nstatic inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col1 );\n}\n\nstatic inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col2 );\n}\n\nstatic inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col )\n{\n    vmathV3Copy( result, (&tfrm->col0 + col) );\n}\n\nstatic inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row )\n{\n    vmathV4MakeFromElems( result, vmathV3GetElem( &tfrm->col0, row ), vmathV3GetElem( &tfrm->col1, row ), vmathV3GetElem( &tfrm->col2, row ), vmathV3GetElem( &tfrm->col3, row ) );\n}\n\nstatic inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    tmp2 = _vmathVfCross( tfrm->col0.vec128, tfrm->col1.vec128 );\n    tmp0 = _vmathVfCross( tfrm->col1.vec128, tfrm->col2.vec128 );\n    tmp1 = _vmathVfCross( tfrm->col2.vec128, tfrm->col0.vec128 );\n    inv3 = negatef4( tfrm->col3.vec128 );\n    dot = _vmathVfDot3( tmp2, tfrm->col2.vec128 );\n    dot = vec_splat( dot, 0 );\n    invdet = recipf4( dot );\n    tmp3 = vec_mergeh( tmp0, tmp2 );\n    tmp4 = vec_mergel( tmp0, tmp2 );\n    inv0 = vec_mergeh( tmp3, tmp1 );\n    xxxx = vec_splat( inv3, 0 );\n    inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX );\n    inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX );\n    yyyy = vec_splat( inv3, 1 );\n    zzzz = vec_splat( inv3, 2 );\n    inv3 = vec_madd( inv0, xxxx, zero );\n    inv3 = vec_madd( inv1, yyyy, inv3 );\n    inv3 = vec_madd( inv2, zzzz, inv3 );\n    inv0 = vec_madd( inv0, invdet, zero );\n    inv1 = vec_madd( inv1, invdet, zero );\n    inv2 = vec_madd( inv2, invdet, zero );\n    inv3 = vec_madd( inv3, invdet, zero );\n    result->col0.vec128 = inv0;\n    result->col1.vec128 = inv1;\n    result->col2.vec128 = inv2;\n    result->col3.vec128 = inv3;\n}\n\nstatic inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1;\n    vec_float4 xxxx, yyyy, zzzz;\n    tmp0 = vec_mergeh( tfrm->col0.vec128, tfrm->col2.vec128 );\n    tmp1 = vec_mergel( tfrm->col0.vec128, tfrm->col2.vec128 );\n    inv3 = negatef4( tfrm->col3.vec128 );\n    inv0 = vec_mergeh( tmp0, tfrm->col1.vec128 );\n    xxxx = vec_splat( inv3, 0 );\n    inv1 = vec_perm( tmp0, tfrm->col1.vec128, _VECTORMATH_PERM_ZBWX );\n    inv2 = vec_perm( tmp1, tfrm->col1.vec128, _VECTORMATH_PERM_XCYX );\n    yyyy = vec_splat( inv3, 1 );\n    zzzz = vec_splat( inv3, 2 );\n    inv3 = vec_madd( inv0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    inv3 = vec_madd( inv1, yyyy, inv3 );\n    inv3 = vec_madd( inv2, zzzz, inv3 );\n    result->col0.vec128 = inv0;\n    result->col1.vec128 = inv1;\n    result->col2.vec128 = inv2;\n    result->col3.vec128 = inv3;\n}\n\nstatic inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3AbsPerElem( &result->col0, &tfrm->col0 );\n    vmathV3AbsPerElem( &result->col1, &tfrm->col1 );\n    vmathV3AbsPerElem( &result->col2, &tfrm->col2 );\n    vmathV3AbsPerElem( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec )\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec->vec128, 0 );\n    yyyy = vec_splat( vec->vec128, 1 );\n    zzzz = vec_splat( vec->vec128, 2 );\n    res = vec_madd( tfrm->col0.vec128, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( tfrm->col1.vec128, yyyy, res );\n    res = vec_madd( tfrm->col2.vec128, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt )\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    xxxx = vec_splat( pnt->vec128, 0 );\n    yyyy = vec_splat( pnt->vec128, 1 );\n    zzzz = vec_splat( pnt->vec128, 2 );\n    tmp0 = vec_madd( tfrm->col0.vec128, xxxx, zero );\n    tmp1 = vec_madd( tfrm->col1.vec128, yyyy, zero );\n    tmp0 = vec_madd( tfrm->col2.vec128, zzzz, tmp0 );\n    tmp1 = vec_add( tfrm->col3.vec128, tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    result->vec128 = res;\n}\n\nstatic inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 )\n{\n    VmathTransform3 tmpResult;\n    VmathPoint3 tmpP3_0, tmpP3_1;\n    vmathT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 );\n    vmathT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 );\n    vmathT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 );\n    vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 );\n    vmathV3MakeFromP3( &tmpResult.col3, &tmpP3_1 );\n    vmathT3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 )\n{\n    vmathV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 );\n    vmathV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 );\n    vmathV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 );\n    vmathV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 );\n}\n\nstatic inline void vmathT3MakeIdentity( VmathTransform3 *result )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *tfrm )\n{\n    vmathV3Copy( &result->col0, &tfrm->col0 );\n    vmathV3Copy( &result->col1, &tfrm->col1 );\n    vmathV3Copy( &result->col2, &tfrm->col2 );\n}\n\nstatic inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm )\n{\n    vmathM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 );\n}\n\nstatic inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec )\n{\n    vmathV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    vmathV3MakeXAxis( &result->col0 );\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    result->col0.vec128 = res0;\n    vmathV3MakeYAxis( &result->col1 );\n    result->col2.vec128 = res2;\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( _vmathVfSplatScalar(radians), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ )\n{\n    VmathVector4 tmpV4_0;\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    vmathV4MakeFromV3Scalar( &tmpV4_0, radiansXYZ, 0.0f );\n    angles = tmpV4_0.vec128;\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n    Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F );\n    Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX );\n    Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_madd( Z0, Y1, zero );\n    result->col0.vec128 = vec_madd( Z0, Y0, zero );\n    result->col1.vec128 = vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) );\n    result->col2.vec128 = vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec )\n{\n    VmathMatrix3 tmpM3_0;\n    VmathVector3 tmpV3_0;\n    vmathM3MakeRotationAxis( &tmpM3_0, radians, unitVec );\n    vmathV3MakeFromScalar( &tmpV3_0, 0.0f );\n    vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat )\n{\n    VmathMatrix3 tmpM3_0;\n    VmathVector3 tmpV3_0;\n    vmathM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathV3MakeFromScalar( &tmpV3_0, 0.0f );\n    vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec )\n{\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    result->col0.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0xF000 );\n    result->col1.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x0F00 );\n    result->col2.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x00F0 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec )\n{\n    vmathV3ScalarMul( &result->col0, &tfrm->col0, vmathV3GetX( scaleVec ) );\n    vmathV3ScalarMul( &result->col1, &tfrm->col1, vmathV3GetY( scaleVec ) );\n    vmathV3ScalarMul( &result->col2, &tfrm->col2, vmathV3GetZ( scaleVec ) );\n    vmathV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm )\n{\n    vmathV3MulPerElem( &result->col0, &tfrm->col0, scaleVec );\n    vmathV3MulPerElem( &result->col1, &tfrm->col1, scaleVec );\n    vmathV3MulPerElem( &result->col2, &tfrm->col2, scaleVec );\n    vmathV3MulPerElem( &result->col3, &tfrm->col3, scaleVec );\n}\n\nstatic inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 )\n{\n    vmathV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 );\n    vmathV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 );\n    vmathV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 );\n    vmathV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathT3Print( const VmathTransform3 *tfrm )\n{\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2;\n    vmathT3GetRow( &tmpV4_0, tfrm, 0 );\n    vmathV4Print( &tmpV4_0 );\n    vmathT3GetRow( &tmpV4_1, tfrm, 1 );\n    vmathV4Print( &tmpV4_1 );\n    vmathT3GetRow( &tmpV4_2, tfrm, 2 );\n    vmathV4Print( &tmpV4_2 );\n}\n\nstatic inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathT3Print( tfrm );\n}\n\n#endif\n\nstatic inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *tfrm )\n{\n    vec_float4 res;\n    vec_float4 col0, col1, col2;\n    vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff;\n    vec_float4 zy_xz_yx, yz_zx_xy, sum, diff;\n    vec_float4 radicand, invSqrt, scale;\n    vec_float4 res0, res1, res2, res3;\n    vec_float4 xx, yy, zz;\n    vec_uint4 select_x = _VECTORMATH_MASK_0xF000;\n    vec_uint4 select_y = _VECTORMATH_MASK_0x0F00;\n    vec_uint4 select_z = _VECTORMATH_MASK_0x00F0;\n    vec_uint4 select_w = _VECTORMATH_MASK_0x000F;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n\n    col0 = tfrm->col0.vec128;\n    col1 = tfrm->col1.vec128;\n    col2 = tfrm->col2.vec128;\n\n    /* four cases: */\n    /* trace > 0 */\n    /* else */\n    /*    xx largest diagonal element */\n    /*    yy largest diagonal element */\n    /*    zz largest diagonal element */\n\n    /* compute quaternion for each case */\n\n    xx_yy = vec_sel( col0, col1, select_y );\n    xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX );\n    yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY );\n    zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC );\n\n    diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    invSqrt = rsqrtf4( radicand );\n\n    zy_xz_yx = vec_sel( col0, col1, select_z );\n    zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX );\n    yz_zx_xy = vec_sel( col0, col1, select_x );\n    yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX );\n\n    sum = vec_add( zy_xz_yx, yz_zx_xy );\n    diff = vec_sub( zy_xz_yx, yz_zx_xy );\n\n    scale = vec_madd( invSqrt, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), zero );\n    res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA );\n    res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB );\n    res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC );\n    res3 = diff;\n    res0 = vec_sel( res0, radicand, select_x );\n    res1 = vec_sel( res1, radicand, select_y );\n    res2 = vec_sel( res2, radicand, select_z );\n    res3 = vec_sel( res3, radicand, select_w );\n    res0 = vec_madd( res0, vec_splat( scale, 0 ), zero );\n    res1 = vec_madd( res1, vec_splat( scale, 1 ), zero );\n    res2 = vec_madd( res2, vec_splat( scale, 2 ), zero );\n    res3 = vec_madd( res3, vec_splat( scale, 3 ), zero );\n\n    /* determine case and select answer */\n\n    xx = vec_splat( col0, 0 );\n    yy = vec_splat( col1, 1 );\n    zz = vec_splat( col2, 2 );\n    res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) );\n    res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) );\n    res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), zero ) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *tfrm0, const VmathVector3 *tfrm1 )\n{\n    vmathV3ScalarMul( &result->col0, tfrm0, vmathV3GetX( tfrm1 ) );\n    vmathV3ScalarMul( &result->col1, tfrm0, vmathV3GetY( tfrm1 ) );\n    vmathV3ScalarMul( &result->col2, tfrm0, vmathV3GetZ( tfrm1 ) );\n}\n\nstatic inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *tfrm0, const VmathVector4 *tfrm1 )\n{\n    vmathV4ScalarMul( &result->col0, tfrm0, vmathV4GetX( tfrm1 ) );\n    vmathV4ScalarMul( &result->col1, tfrm0, vmathV4GetY( tfrm1 ) );\n    vmathV4ScalarMul( &result->col2, tfrm0, vmathV4GetZ( tfrm1 ) );\n    vmathV4ScalarMul( &result->col3, tfrm0, vmathV4GetW( tfrm1 ) );\n}\n\nstatic inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat )\n{\n    vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    tmp0 = vec_mergeh( mat->col0.vec128, mat->col2.vec128 );\n    tmp1 = vec_mergel( mat->col0.vec128, mat->col2.vec128 );\n    xxxx = vec_splat( vec->vec128, 0 );\n    mcol0 = vec_mergeh( tmp0, mat->col1.vec128 );\n    mcol1 = vec_perm( tmp0, mat->col1.vec128, _VECTORMATH_PERM_ZBWX );\n    mcol2 = vec_perm( tmp1, mat->col1.vec128, _VECTORMATH_PERM_XCYX );\n    yyyy = vec_splat( vec->vec128, 1 );\n    res = vec_madd( mcol0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    zzzz = vec_splat( vec->vec128, 2 );\n    res = vec_madd( mcol1, yyyy, res );\n    res = vec_madd( mcol2, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec )\n{\n    vec_float4 neg, res0, res1, res2;\n    neg = negatef4( vec->vec128 );\n    res0 = vec_perm( vec->vec128, neg, _VECTORMATH_PERM_XZBX );\n    res1 = vec_perm( vec->vec128, neg, _VECTORMATH_PERM_CXXX );\n    res2 = vec_perm( vec->vec128, neg, _VECTORMATH_PERM_YAXX );\n    res0 = vec_andc( res0, (vec_float4)_VECTORMATH_MASK_0xF000 );\n    res1 = vec_andc( res1, (vec_float4)_VECTORMATH_MASK_0x0F00 );\n    res2 = vec_andc( res2, (vec_float4)_VECTORMATH_MASK_0x00F0 );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathV3Cross( &tmpV3_0, vec, &mat->col0 );\n    vmathV3Cross( &tmpV3_1, vec, &mat->col1 );\n    vmathV3Cross( &tmpV3_2, vec, &mat->col2 );\n    vmathM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 );\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/mat_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_V_C_H\n#define _VECTORMATH_MAT_AOS_V_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X })     \n#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z })\n#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y })\n#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2 )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromCols(&result, &_col0, &_col1, &_col2);\n    return result;\n}\n\nstatic inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 _col0 )\n{\n    vmathM3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 _col1 )\n{\n    vmathM3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 _col2 )\n{\n    vmathM3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec )\n{\n    vmathM3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec )\n{\n    vmathM3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val )\n{\n    vmathM3SetElem(result, col, row, val);\n}\n\nstatic inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row )\n{\n    return vmathM3GetElem(&mat, col, row);\n}\n\nstatic inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col )\n{\n    VmathVector3 result;\n    vmathM3GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row )\n{\n    VmathVector3 result;\n    vmathM3GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline float vmathM3Determinant_V( VmathMatrix3 mat )\n{\n    return vmathM3Determinant(&mat);\n}\n\nstatic inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar )\n{\n    VmathMatrix3 result;\n    vmathM3ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathM3MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeIdentity_V( )\n{\n    VmathMatrix3 result;\n    vmathM3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationX_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationY_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathMatrix3 result;\n    vmathM3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec )\n{\n    VmathMatrix3 result;\n    vmathM3AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 )\n{\n    VmathMatrix3 result;\n    vmathM3Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM3Print_V( VmathMatrix3 mat )\n{\n    vmathM3Print(&mat);\n}\n\nstatic inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name )\n{\n    vmathM3Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromT3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 _col0, VmathVector4 _col1, VmathVector4 _col2, VmathVector4 _col3 )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromM3V3(&result, &mat, &translateVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 _col0 )\n{\n    vmathM4SetCol0(result, &_col0);\n}\n\nstatic inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 _col1 )\n{\n    vmathM4SetCol1(result, &_col1);\n}\n\nstatic inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 _col2 )\n{\n    vmathM4SetCol2(result, &_col2);\n}\n\nstatic inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 _col3 )\n{\n    vmathM4SetCol3(result, &_col3);\n}\n\nstatic inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec )\n{\n    vmathM4SetCol(result, col, &vec);\n}\n\nstatic inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec )\n{\n    vmathM4SetRow(result, row, &vec);\n}\n\nstatic inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val )\n{\n    vmathM4SetElem(result, col, row, val);\n}\n\nstatic inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row )\n{\n    return vmathM4GetElem(&mat, col, row);\n}\n\nstatic inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col )\n{\n    VmathVector4 result;\n    vmathM4GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row )\n{\n    VmathVector4 result;\n    vmathM4GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4AffineInverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4OrthoInverse(&result, &mat);\n    return result;\n}\n\nstatic inline float vmathM4Determinant_V( VmathMatrix4 mat )\n{\n    return vmathM4Determinant(&mat);\n}\n\nstatic inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar )\n{\n    VmathMatrix4 result;\n    vmathM4ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathM4MulV4(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec )\n{\n    VmathVector4 result;\n    vmathM4MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt )\n{\n    VmathVector4 result;\n    vmathM4MulP3(&result, &mat, &pnt);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm1 )\n{\n    VmathMatrix4 result;\n    vmathM4MulT3(&result, &mat, &tfrm1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeIdentity_V( )\n{\n    VmathMatrix4 result;\n    vmathM4MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 )\n{\n    vmathM4SetUpper3x3(result, &mat3);\n}\n\nstatic inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat )\n{\n    VmathMatrix3 result;\n    vmathM4GetUpper3x3(&result, &mat);\n    return result;\n}\n\nstatic inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec )\n{\n    vmathM4SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat )\n{\n    VmathVector3 result;\n    vmathM4GetTranslation(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationX_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationY_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec )\n{\n    VmathMatrix4 result;\n    vmathM4AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 )\n{\n    VmathMatrix4 result;\n    vmathM4Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM4Print_V( VmathMatrix4 mat )\n{\n    vmathM4Print(&mat);\n}\n\nstatic inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name )\n{\n    vmathM4Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2, VmathVector3 _col3 )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromM3V3(&result, &tfrm, &translateVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 _col0 )\n{\n    vmathT3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 _col1 )\n{\n    vmathT3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 _col2 )\n{\n    vmathT3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 _col3 )\n{\n    vmathT3SetCol3(result, &_col3);\n}\n\nstatic inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec )\n{\n    vmathT3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec )\n{\n    vmathT3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val )\n{\n    vmathT3SetElem(result, col, row, val);\n}\n\nstatic inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row )\n{\n    return vmathT3GetElem(&tfrm, col, row);\n}\n\nstatic inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol0(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol1(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol2(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col )\n{\n    VmathVector3 result;\n    vmathT3GetCol(&result, &tfrm, col);\n    return result;\n}\n\nstatic inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row )\n{\n    VmathVector4 result;\n    vmathT3GetRow(&result, &tfrm, row);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3Inverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3OrthoInverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3AbsPerElem(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathT3MulV3(&result, &tfrm, &vec);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathT3MulP3(&result, &tfrm, &pnt);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 )\n{\n    VmathTransform3 result;\n    vmathT3Mul(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 )\n{\n    VmathTransform3 result;\n    vmathT3MulPerElem(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeIdentity_V( )\n{\n    VmathTransform3 result;\n    vmathT3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 tfrm )\n{\n    vmathT3SetUpper3x3(result, &tfrm);\n}\n\nstatic inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm )\n{\n    VmathMatrix3 result;\n    vmathT3GetUpper3x3(&result, &tfrm);\n    return result;\n}\n\nstatic inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec )\n{\n    vmathT3SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetTranslation(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationX_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationY_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationZ_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec )\n{\n    VmathTransform3 result;\n    vmathT3AppendScale(&result, &tfrm, &scaleVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3PrependScale(&result, &scaleVec, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 )\n{\n    VmathTransform3 result;\n    vmathT3Select(&result, &tfrm0, &tfrm1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathT3Print_V( VmathTransform3 tfrm )\n{\n    vmathT3Print(&tfrm);\n}\n\nstatic inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name )\n{\n    vmathT3Prints(&tfrm, name);\n}\n\n#endif\n\nstatic inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 tfrm )\n{\n    VmathQuat result;\n    vmathQMakeFromM3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3Outer_V( VmathVector3 tfrm0, VmathVector3 tfrm1 )\n{\n    VmathMatrix3 result;\n    vmathV3Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathV4Outer_V( VmathVector4 tfrm0, VmathVector4 tfrm1 )\n{\n    VmathMatrix4 result;\n    vmathV4Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathV3RowMul(&result, &vec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec )\n{\n    VmathMatrix3 result;\n    vmathV3CrossMatrix(&result, &vec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathV3CrossMatrixMul(&result, &vec, &mat);\n    return result;\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/mat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_SOA_C_H\n#define _VECTORMATH_MAT_SOA_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( &result->col0, &mat->col0 );\n    vmathSoaV3Copy( &result->col1, &mat->col1 );\n    vmathSoaV3Copy( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar )\n{\n    vmathSoaV3MakeFromScalar( &result->col0, scalar );\n    vmathSoaV3MakeFromScalar( &result->col1, scalar );\n    vmathSoaV3MakeFromScalar( &result->col2, scalar );\n}\n\nstatic inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat )\n{\n    vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2;\n    qx = unitQuat->x;\n    qy = unitQuat->y;\n    qz = unitQuat->z;\n    qw = unitQuat->w;\n    qx2 = vec_add( qx, qx );\n    qy2 = vec_add( qy, qy );\n    qz2 = vec_add( qz, qz );\n    qxqx2 = vec_madd( qx, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qxqy2 = vec_madd( qx, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qxqz2 = vec_madd( qx, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qxqw2 = vec_madd( qw, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qyqy2 = vec_madd( qy, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qyqz2 = vec_madd( qy, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qyqw2 = vec_madd( qw, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qzqz2 = vec_madd( qz, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qzqw2 = vec_madd( qw, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col0, vec_sub( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), qyqy2 ), qzqz2 ), vec_add( qxqy2, qzqw2 ), vec_sub( qxqz2, qyqw2 ) );\n    vmathSoaV3MakeFromElems( &result->col1, vec_sub( qxqy2, qzqw2 ), vec_sub( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), qxqx2 ), qzqz2 ), vec_add( qyqz2, qxqw2 ) );\n    vmathSoaV3MakeFromElems( &result->col2, vec_add( qxqz2, qyqw2 ), vec_sub( qyqz2, qxqw2 ), vec_sub( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), qxqx2 ), qyqy2 ) );\n}\n\nstatic inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n    vmathSoaV3Copy( &result->col1, _col1 );\n    vmathSoaV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathSoaV3MakeFromAos( &result->col0, &mat->col0 );\n    vmathSoaV3MakeFromAos( &result->col1, &mat->col1 );\n    vmathSoaV3MakeFromAos( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 )\n{\n    vmathSoaV3MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 );\n    vmathSoaV3MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 );\n    vmathSoaV3MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 );\n}\n\nstatic inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 )\n{\n    vmathSoaV3Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 );\n    vmathSoaV3Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 );\n    vmathSoaV3Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 );\n}\n\nstatic inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col1 )\n{\n    vmathSoaV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col2 )\n{\n    vmathSoaV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3SetElem( &result->col0, row, vmathSoaV3GetElem( vec, 0 ) );\n    vmathSoaV3SetElem( &result->col1, row, vmathSoaV3GetElem( vec, 1 ) );\n    vmathSoaV3SetElem( &result->col2, row, vmathSoaV3GetElem( vec, 2 ) );\n}\n\nstatic inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3GetCol( &tmpV3_0, result, col );\n    vmathSoaV3SetElem( &tmpV3_0, row, val );\n    vmathSoaM3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3GetCol( &tmpV3_0, mat, col );\n    return vmathSoaV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col )\n{\n    vmathSoaV3Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row )\n{\n    vmathSoaV3MakeFromElems( result, vmathSoaV3GetElem( &mat->col0, row ), vmathSoaV3GetElem( &mat->col1, row ), vmathSoaV3GetElem( &mat->col2, row ) );\n}\n\nstatic inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    VmathSoaMatrix3 tmpResult;\n    vmathSoaV3MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x );\n    vmathSoaV3MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y );\n    vmathSoaV3MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z );\n    vmathSoaM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    VmathSoaVector3 tmp0, tmp1, tmp2;\n    vec_float4 detinv;\n    vmathSoaV3Cross( &tmp0, &mat->col1, &mat->col2 );\n    vmathSoaV3Cross( &tmp1, &mat->col2, &mat->col0 );\n    vmathSoaV3Cross( &tmp2, &mat->col0, &mat->col1 );\n    detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vmathSoaV3Dot( &mat->col2, &tmp2 ) );\n    vmathSoaV3MakeFromElems( &result->col0, vec_madd( tmp0.x, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.x, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.x, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( &result->col1, vec_madd( tmp0.y, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.y, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.y, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( &result->col2, vec_madd( tmp0.z, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.z, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.z, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaV3Cross( &tmpV3_0, &mat->col0, &mat->col1 );\n    return vmathSoaV3Dot( &mat->col2, &tmpV3_0 );\n}\n\nstatic inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    vmathSoaV3Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV3Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV3Add( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    vmathSoaV3Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV3Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV3Sub( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Neg( &result->col0, &mat->col0 );\n    vmathSoaV3Neg( &result->col1, &mat->col1 );\n    vmathSoaV3Neg( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3AbsPerElem( &result->col0, &mat->col0 );\n    vmathSoaV3AbsPerElem( &result->col1, &mat->col1 );\n    vmathSoaV3AbsPerElem( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar )\n{\n    vmathSoaV3ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathSoaV3ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathSoaV3ScalarMul( &result->col2, &mat->col2, scalar );\n}\n\nstatic inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = vec_add( vec_add( vec_madd( mat->col0.x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.x, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.x, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_add( vec_add( vec_madd( mat->col0.y, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.y, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_add( vec_add( vec_madd( mat->col0.z, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.z, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    VmathSoaMatrix3 tmpResult;\n    vmathSoaM3MulV3( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathSoaM3MulV3( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathSoaM3MulV3( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathSoaM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    vmathSoaV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result )\n{\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s );\n    vmathSoaV3MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c );\n}\n\nstatic inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeFromElems( &result->col2, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );\n}\n\nstatic inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ->x, &sX, &cX );\n    sincosf4( radiansXYZ->y, &sY, &cY );\n    sincosf4( radiansXYZ->z, &sZ, &cZ );\n    tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col0, vec_madd( cZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), negatef4( sY ) );\n    vmathSoaV3MakeFromElems( &result->col1, vec_sub( vec_madd( tmp0, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( tmp1, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( &result->col2, vec_add( vec_madd( tmp0, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( tmp1, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec->x;\n    y = unitVec->y;\n    z = unitVec->z;\n    xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    vmathSoaV3MakeFromElems( &result->col0, vec_add( vec_madd( vec_madd( x, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    vmathSoaV3MakeFromElems( &result->col1, vec_sub( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( y, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    vmathSoaV3MakeFromElems( &result->col2, vec_add( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( z, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ) );\n}\n\nstatic inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat )\n{\n    vmathSoaM3MakeFromQ( result, unitQuat );\n}\n\nstatic inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3MakeFromElems( &result->col0, scaleVec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec->z );\n}\n\nstatic inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) );\n}\n\nstatic inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3MulPerElem( &result->col0, &mat->col0, scaleVec );\n    vmathSoaV3MulPerElem( &result->col1, &mat->col1, scaleVec );\n    vmathSoaV3MulPerElem( &result->col2, &mat->col2, scaleVec );\n}\n\nstatic inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 )\n{\n    vmathSoaV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathSoaV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathSoaV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat )\n{\n    VmathMatrix3 mat0, mat1, mat2, mat3;\n    vmathSoaM3Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 );\n    printf(\"slot 0:\\n\");\n    vmathM3Print( &mat0 );\n    printf(\"slot 1:\\n\");\n    vmathM3Print( &mat1 );\n    printf(\"slot 2:\\n\");\n    vmathM3Print( &mat2 );\n    printf(\"slot 3:\\n\");\n    vmathM3Print( &mat3 );\n}\n\nstatic inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathSoaM3Print( mat );\n}\n\n#endif\n\nstatic inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( &result->col0, &mat->col0 );\n    vmathSoaV4Copy( &result->col1, &mat->col1 );\n    vmathSoaV4Copy( &result->col2, &mat->col2 );\n    vmathSoaV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar )\n{\n    vmathSoaV4MakeFromScalar( &result->col0, scalar );\n    vmathSoaV4MakeFromScalar( &result->col1, scalar );\n    vmathSoaV4MakeFromScalar( &result->col2, scalar );\n    vmathSoaV4MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat )\n{\n    vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, &mat->col3, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0, const VmathSoaVector4 *_col1, const VmathSoaVector4 *_col2, const VmathSoaVector4 *_col3 )\n{\n    vmathSoaV4Copy( &result->col0, _col0 );\n    vmathSoaV4Copy( &result->col1, _col1 );\n    vmathSoaV4Copy( &result->col2, _col2 );\n    vmathSoaV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec )\n{\n    VmathSoaMatrix3 mat;\n    vmathSoaM3MakeFromQ( &mat, unitQuat );\n    vmathSoaV4MakeFromV3Scalar( &result->col0, &mat.col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col1, &mat.col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col2, &mat.col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathSoaV4MakeFromAos( &result->col0, &mat->col0 );\n    vmathSoaV4MakeFromAos( &result->col1, &mat->col1 );\n    vmathSoaV4MakeFromAos( &result->col2, &mat->col2 );\n    vmathSoaV4MakeFromAos( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 )\n{\n    vmathSoaV4MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 );\n    vmathSoaV4MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 );\n    vmathSoaV4MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 );\n    vmathSoaV4MakeFrom4Aos( &result->col3, &mat0->col3, &mat1->col3, &mat2->col3, &mat3->col3 );\n}\n\nstatic inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 )\n{\n    vmathSoaV4Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 );\n    vmathSoaV4Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 );\n    vmathSoaV4Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 );\n    vmathSoaV4Get4Aos( &mat->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 );\n}\n\nstatic inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0 )\n{\n    vmathSoaV4Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col1 )\n{\n    vmathSoaV4Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col2 )\n{\n    vmathSoaV4Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col3 )\n{\n    vmathSoaV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec )\n{\n    vmathSoaV4Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec )\n{\n    vmathSoaV4SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) );\n    vmathSoaV4SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) );\n    vmathSoaV4SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) );\n    vmathSoaV4SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val )\n{\n    VmathSoaVector4 tmpV3_0;\n    vmathSoaM4GetCol( &tmpV3_0, result, col );\n    vmathSoaV4SetElem( &tmpV3_0, row, val );\n    vmathSoaM4SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row )\n{\n    VmathSoaVector4 tmpV4_0;\n    vmathSoaM4GetCol( &tmpV4_0, mat, col );\n    return vmathSoaV4GetElem( &tmpV4_0, row );\n}\n\nstatic inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col )\n{\n    vmathSoaV4Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row )\n{\n    vmathSoaV4MakeFromElems( result, vmathSoaV4GetElem( &mat->col0, row ), vmathSoaV4GetElem( &mat->col1, row ), vmathSoaV4GetElem( &mat->col2, row ), vmathSoaV4GetElem( &mat->col3, row ) );\n}\n\nstatic inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaMatrix4 tmpResult;\n    vmathSoaV4MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x, mat->col3.x );\n    vmathSoaV4MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y, mat->col3.y );\n    vmathSoaV4MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z, mat->col3.z );\n    vmathSoaV4MakeFromElems( &tmpResult.col3, mat->col0.w, mat->col1.w, mat->col2.w, mat->col3.w );\n    vmathSoaM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaVector4 res0, res1, res2, res3;\n    vec_float4 mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv;\n    mA = mat->col0.x;\n    mB = mat->col0.y;\n    mC = mat->col0.z;\n    mD = mat->col0.w;\n    mE = mat->col1.x;\n    mF = mat->col1.y;\n    mG = mat->col1.z;\n    mH = mat->col1.w;\n    mI = mat->col2.x;\n    mJ = mat->col2.y;\n    mK = mat->col2.z;\n    mL = mat->col2.w;\n    mM = mat->col3.x;\n    mN = mat->col3.y;\n    mO = mat->col3.z;\n    mP = mat->col3.w;\n    tmp0 = vec_sub( vec_madd( mK, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp1 = vec_sub( vec_madd( mO, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp2 = vec_sub( vec_madd( mB, mK, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mJ, mC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp3 = vec_sub( vec_madd( mF, mO, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mN, mG, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp4 = vec_sub( vec_madd( mJ, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mB, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp5 = vec_sub( vec_madd( mN, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mF, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetX( &res0, vec_sub( vec_sub( vec_madd( mJ, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mL, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mK, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    vmathSoaV4SetY( &res0, vec_sub( vec_sub( vec_madd( mN, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mP, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mO, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    vmathSoaV4SetZ( &res0, vec_sub( vec_add( vec_madd( mD, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mB, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    vmathSoaV4SetW( &res0, vec_sub( vec_add( vec_madd( mH, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mF, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    detInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_add( vec_add( vec_add( vec_madd( mA, res0.x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, res0.y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mI, res0.z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mM, res0.w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    vmathSoaV4SetX( &res1, vec_madd( mI, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetY( &res1, vec_madd( mM, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetZ( &res1, vec_madd( mA, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetW( &res1, vec_madd( mE, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetX( &res3, vec_madd( mI, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetY( &res3, vec_madd( mM, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetZ( &res3, vec_madd( mA, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetW( &res3, vec_madd( mE, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetX( &res2, vec_madd( mI, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetY( &res2, vec_madd( mM, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetZ( &res2, vec_madd( mA, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetW( &res2, vec_madd( mE, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp0 = vec_sub( vec_madd( mI, mB, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mA, mJ, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp1 = vec_sub( vec_madd( mM, mF, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, mN, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp2 = vec_sub( vec_madd( mI, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mA, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp3 = vec_sub( vec_madd( mM, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp4 = vec_sub( vec_madd( mI, mC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mA, mK, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp5 = vec_sub( vec_madd( mM, mG, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, mO, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4SetX( &res2, vec_add( vec_sub( vec_madd( mL, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mJ, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.x ) );\n    vmathSoaV4SetY( &res2, vec_add( vec_sub( vec_madd( mP, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mN, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.y ) );\n    vmathSoaV4SetZ( &res2, vec_sub( vec_sub( vec_madd( mB, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mD, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.z ) );\n    vmathSoaV4SetW( &res2, vec_sub( vec_sub( vec_madd( mF, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mH, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.w ) );\n    vmathSoaV4SetX( &res3, vec_add( vec_sub( vec_madd( mJ, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mK, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.x ) );\n    vmathSoaV4SetY( &res3, vec_add( vec_sub( vec_madd( mN, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mO, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.y ) );\n    vmathSoaV4SetZ( &res3, vec_sub( vec_sub( vec_madd( mC, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mB, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.z ) );\n    vmathSoaV4SetW( &res3, vec_sub( vec_sub( vec_madd( mG, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mF, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.w ) );\n    vmathSoaV4SetX( &res1, vec_sub( vec_sub( vec_madd( mK, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mL, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.x ) );\n    vmathSoaV4SetY( &res1, vec_sub( vec_sub( vec_madd( mO, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mP, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.y ) );\n    vmathSoaV4SetZ( &res1, vec_add( vec_sub( vec_madd( mD, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.z ) );\n    vmathSoaV4SetW( &res1, vec_add( vec_sub( vec_madd( mH, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.w ) );\n    vmathSoaV4ScalarMul( &result->col0, &res0, detInv );\n    vmathSoaV4ScalarMul( &result->col1, &res1, detInv );\n    vmathSoaV4ScalarMul( &result->col2, &res2, detInv );\n    vmathSoaV4ScalarMul( &result->col3, &res3, detInv );\n}\n\nstatic inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaTransform3 affineMat, tmpT3_0;\n    VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathSoaT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathSoaT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathSoaT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathSoaT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathSoaT3Inverse( &tmpT3_0, &affineMat );\n    vmathSoaM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaTransform3 affineMat, tmpT3_0;\n    VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathSoaT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathSoaT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathSoaT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathSoaT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathSoaT3OrthoInverse( &tmpT3_0, &affineMat );\n    vmathSoaM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat )\n{\n    vec_float4 dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    mA = mat->col0.x;\n    mB = mat->col0.y;\n    mC = mat->col0.z;\n    mD = mat->col0.w;\n    mE = mat->col1.x;\n    mF = mat->col1.y;\n    mG = mat->col1.z;\n    mH = mat->col1.w;\n    mI = mat->col2.x;\n    mJ = mat->col2.y;\n    mK = mat->col2.z;\n    mL = mat->col2.w;\n    mM = mat->col3.x;\n    mN = mat->col3.y;\n    mO = mat->col3.z;\n    mP = mat->col3.w;\n    tmp0 = vec_sub( vec_madd( mK, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp1 = vec_sub( vec_madd( mO, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp2 = vec_sub( vec_madd( mB, mK, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mJ, mC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp3 = vec_sub( vec_madd( mF, mO, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mN, mG, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp4 = vec_sub( vec_madd( mJ, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mB, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp5 = vec_sub( vec_madd( mN, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mF, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dx = vec_sub( vec_sub( vec_madd( mJ, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mL, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mK, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dy = vec_sub( vec_sub( vec_madd( mN, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mP, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mO, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dz = vec_sub( vec_add( vec_madd( mD, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mB, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dw = vec_sub( vec_add( vec_madd( mH, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mF, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return vec_add( vec_add( vec_add( vec_madd( mA, dx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, dy, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mI, dz, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mM, dw, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    vmathSoaV4Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV4Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV4Add( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathSoaV4Add( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    vmathSoaV4Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV4Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV4Sub( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathSoaV4Sub( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Neg( &result->col0, &mat->col0 );\n    vmathSoaV4Neg( &result->col1, &mat->col1 );\n    vmathSoaV4Neg( &result->col2, &mat->col2 );\n    vmathSoaV4Neg( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4AbsPerElem( &result->col0, &mat->col0 );\n    vmathSoaV4AbsPerElem( &result->col1, &mat->col1 );\n    vmathSoaV4AbsPerElem( &result->col2, &mat->col2 );\n    vmathSoaV4AbsPerElem( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar )\n{\n    vmathSoaV4ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathSoaV4ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathSoaV4ScalarMul( &result->col2, &mat->col2, scalar );\n    vmathSoaV4ScalarMul( &result->col3, &mat->col3, scalar );\n}\n\nstatic inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = vec_add( vec_add( vec_add( vec_madd( mat->col0.x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.x, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.x, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col3.x, vec->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_add( vec_add( vec_add( vec_madd( mat->col0.y, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.y, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col3.y, vec->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_add( vec_add( vec_add( vec_madd( mat->col0.z, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.z, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col3.z, vec->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpW = vec_add( vec_add( vec_add( vec_madd( mat->col0.w, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.w, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.w, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col3.w, vec->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV4MakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );\n}\n\nstatic inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec )\n{\n    result->x = vec_add( vec_add( vec_madd( mat->col0.x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.x, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.x, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result->y = vec_add( vec_add( vec_madd( mat->col0.y, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.y, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result->z = vec_add( vec_add( vec_madd( mat->col0.z, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.z, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result->w = vec_add( vec_add( vec_madd( mat->col0.w, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.w, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.w, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt )\n{\n    result->x = vec_add( vec_add( vec_add( vec_madd( mat->col0.x, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.x, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.x, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mat->col3.x );\n    result->y = vec_add( vec_add( vec_add( vec_madd( mat->col0.y, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.y, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.y, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mat->col3.y );\n    result->z = vec_add( vec_add( vec_add( vec_madd( mat->col0.z, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.z, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.z, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mat->col3.z );\n    result->w = vec_add( vec_add( vec_add( vec_madd( mat->col0.w, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mat->col1.w, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mat->col2.w, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mat->col3.w );\n}\n\nstatic inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    VmathSoaMatrix4 tmpResult;\n    vmathSoaM4MulV4( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathSoaM4MulV4( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathSoaM4MulV4( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathSoaM4MulV4( &tmpResult.col3, mat0, &mat1->col3 );\n    vmathSoaM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm1 )\n{\n    VmathSoaMatrix4 tmpResult;\n    VmathSoaPoint3 tmpP3_0;\n    vmathSoaM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 );\n    vmathSoaM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 );\n    vmathSoaM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 );\n    vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathSoaM4MulP3( &tmpResult.col3, mat, &tmpP3_0 );\n    vmathSoaM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    vmathSoaV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathSoaV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result )\n{\n    vmathSoaV4MakeXAxis( &result->col0 );\n    vmathSoaV4MakeYAxis( &result->col1 );\n    vmathSoaV4MakeZAxis( &result->col2 );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 )\n{\n    vmathSoaV4SetXYZ( &result->col0, &mat3->col0 );\n    vmathSoaV4SetXYZ( &result->col1, &mat3->col1 );\n    vmathSoaV4SetXYZ( &result->col2, &mat3->col2 );\n}\n\nstatic inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4GetXYZ( &result->col0, &mat->col0 );\n    vmathSoaV4GetXYZ( &result->col1, &mat->col1 );\n    vmathSoaV4GetXYZ( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV4SetXYZ( &result->col3, translateVec );\n}\n\nstatic inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4GetXYZ( result, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV4MakeXAxis( &result->col0 );\n    vmathSoaV4MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV4MakeFromElems( &result->col0, c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeYAxis( &result->col1 );\n    vmathSoaV4MakeFromElems( &result->col2, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV4MakeFromElems( &result->col0, c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeZAxis( &result->col2 );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ->x, &sX, &cX );\n    sincosf4( radiansXYZ->y, &sY, &cY );\n    sincosf4( radiansXYZ->z, &sZ, &cZ );\n    tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col0, vec_madd( cZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), negatef4( sY ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, vec_sub( vec_madd( tmp0, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( tmp1, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, vec_add( vec_madd( tmp0, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( tmp1, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec->x;\n    y = unitVec->y;\n    z = unitVec->z;\n    xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    vmathSoaV4MakeFromElems( &result->col0, vec_add( vec_madd( vec_madd( x, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, vec_sub( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( y, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, vec_add( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( z, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat )\n{\n    VmathSoaTransform3 tmpT3_0;\n    vmathSoaT3MakeRotationQ( &tmpT3_0, unitQuat );\n    vmathSoaM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV4MakeFromElems( &result->col0, scaleVec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV4ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) );\n    vmathSoaV4ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) );\n    vmathSoaV4ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) );\n    vmathSoaV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaVector4 scale4;\n    vmathSoaV4MakeFromV3Scalar( &scale4, scaleVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    vmathSoaV4MulPerElem( &result->col0, &mat->col0, &scale4 );\n    vmathSoaV4MulPerElem( &result->col1, &mat->col1, &scale4 );\n    vmathSoaV4MulPerElem( &result->col2, &mat->col2, &scale4 );\n    vmathSoaV4MulPerElem( &result->col3, &mat->col3, &scale4 );\n}\n\nstatic inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV4MakeXAxis( &result->col0 );\n    vmathSoaV4MakeYAxis( &result->col1 );\n    vmathSoaV4MakeZAxis( &result->col2 );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec )\n{\n    VmathSoaMatrix4 m4EyeFrame;\n    VmathSoaVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1;\n    VmathSoaVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathSoaV3Normalize( &v3Y, upVec );\n    vmathSoaP3Sub( &tmpV3_0, eyePos, lookAtPos );\n    vmathSoaV3Normalize( &v3Z, &tmpV3_0 );\n    vmathSoaV3Cross( &tmpV3_1, &v3Y, &v3Z );\n    vmathSoaV3Normalize( &v3X, &tmpV3_1 );\n    vmathSoaV3Cross( &v3Y, &v3Z, &v3X );\n    vmathSoaV4MakeFromV3( &tmpV4_0, &v3X );\n    vmathSoaV4MakeFromV3( &tmpV4_1, &v3Y );\n    vmathSoaV4MakeFromV3( &tmpV4_2, &v3Z );\n    vmathSoaV4MakeFromP3( &tmpV4_3, eyePos );\n    vmathSoaM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 );\n    vmathSoaM4OrthoInverse( result, &m4EyeFrame );\n}\n\nstatic inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 f, rangeInv;\n    f = tanf4( vec_sub( ((vec_float4){_VECTORMATH_PI_OVER_2,_VECTORMATH_PI_OVER_2,_VECTORMATH_PI_OVER_2,_VECTORMATH_PI_OVER_2}), vec_madd( ((vec_float4){0.5f,0.5f,0.5f,0.5f}), fovyRadians, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    rangeInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) );\n    vmathSoaV4MakeFromElems( &result->col0, divf4( f, aspect ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), f, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( vec_add( zNear, zFar ), rangeInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}) );\n    vmathSoaV4MakeFromElems( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( vec_madd( vec_madd( zNear, zFar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), rangeInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){2.0f,2.0f,2.0f,2.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2;\n    sum_rl = vec_add( right, left );\n    sum_tb = vec_add( top, bottom );\n    sum_nf = vec_add( zNear, zFar );\n    inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) );\n    inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) );\n    inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) );\n    n2 = vec_add( zNear, zNear );\n    vmathSoaV4MakeFromElems( &result->col0, vec_madd( n2, inv_rl, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( n2, inv_tb, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, vec_madd( sum_rl, inv_rl, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sum_tb, inv_tb, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sum_nf, inv_nf, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}) );\n    vmathSoaV4MakeFromElems( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( vec_madd( n2, inv_nf, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), zFar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf;\n    sum_rl = vec_add( right, left );\n    sum_tb = vec_add( top, bottom );\n    sum_nf = vec_add( zNear, zFar );\n    inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) );\n    inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) );\n    inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) );\n    vmathSoaV4MakeFromElems( &result->col0, vec_add( inv_rl, inv_rl ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_add( inv_tb, inv_tb ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_add( inv_nf, inv_nf ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV4MakeFromElems( &result->col3, vec_madd( negatef4( sum_rl ), inv_rl, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( negatef4( sum_tb ), inv_tb, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sum_nf, inv_nf, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 )\n{\n    vmathSoaV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathSoaV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathSoaV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n    vmathSoaV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat )\n{\n    VmathMatrix4 mat0, mat1, mat2, mat3;\n    vmathSoaM4Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 );\n    printf(\"slot 0:\\n\");\n    vmathM4Print( &mat0 );\n    printf(\"slot 1:\\n\");\n    vmathM4Print( &mat1 );\n    printf(\"slot 2:\\n\");\n    vmathM4Print( &mat2 );\n    printf(\"slot 3:\\n\");\n    vmathM4Print( &mat3 );\n}\n\nstatic inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathSoaM4Print( mat );\n}\n\n#endif\n\nstatic inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( &result->col0, &tfrm->col0 );\n    vmathSoaV3Copy( &result->col1, &tfrm->col1 );\n    vmathSoaV3Copy( &result->col2, &tfrm->col2 );\n    vmathSoaV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar )\n{\n    vmathSoaV3MakeFromScalar( &result->col0, scalar );\n    vmathSoaV3MakeFromScalar( &result->col1, scalar );\n    vmathSoaV3MakeFromScalar( &result->col2, scalar );\n    vmathSoaV3MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2, const VmathSoaVector3 *_col3 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n    vmathSoaV3Copy( &result->col1, _col1 );\n    vmathSoaV3Copy( &result->col2, _col2 );\n    vmathSoaV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaT3SetUpper3x3( result, tfrm );\n    vmathSoaT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec )\n{\n    VmathSoaMatrix3 tmpM3_0;\n    vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathSoaT3SetUpper3x3( result, &tmpM3_0 );\n    vmathSoaT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathSoaV3MakeFromAos( &result->col0, &tfrm->col0 );\n    vmathSoaV3MakeFromAos( &result->col1, &tfrm->col1 );\n    vmathSoaV3MakeFromAos( &result->col2, &tfrm->col2 );\n    vmathSoaV3MakeFromAos( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 )\n{\n    vmathSoaV3MakeFrom4Aos( &result->col0, &tfrm0->col0, &tfrm1->col0, &tfrm2->col0, &tfrm3->col0 );\n    vmathSoaV3MakeFrom4Aos( &result->col1, &tfrm0->col1, &tfrm1->col1, &tfrm2->col1, &tfrm3->col1 );\n    vmathSoaV3MakeFrom4Aos( &result->col2, &tfrm0->col2, &tfrm1->col2, &tfrm2->col2, &tfrm3->col2 );\n    vmathSoaV3MakeFrom4Aos( &result->col3, &tfrm0->col3, &tfrm1->col3, &tfrm2->col3, &tfrm3->col3 );\n}\n\nstatic inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 )\n{\n    vmathSoaV3Get4Aos( &tfrm->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 );\n    vmathSoaV3Get4Aos( &tfrm->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 );\n    vmathSoaV3Get4Aos( &tfrm->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 );\n    vmathSoaV3Get4Aos( &tfrm->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 );\n}\n\nstatic inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *_col1 )\n{\n    vmathSoaV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *_col2 )\n{\n    vmathSoaV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *_col3 )\n{\n    vmathSoaV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec )\n{\n    vmathSoaV3SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) );\n    vmathSoaV3SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) );\n    vmathSoaV3SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) );\n    vmathSoaV3SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaT3GetCol( &tmpV3_0, result, col );\n    vmathSoaV3SetElem( &tmpV3_0, row, val );\n    vmathSoaT3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaT3GetCol( &tmpV3_0, tfrm, col );\n    return vmathSoaV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col0 );\n}\n\nstatic inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col1 );\n}\n\nstatic inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col2 );\n}\n\nstatic inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col )\n{\n    vmathSoaV3Copy( result, (&tfrm->col0 + col) );\n}\n\nstatic inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row )\n{\n    vmathSoaV4MakeFromElems( result, vmathSoaV3GetElem( &tfrm->col0, row ), vmathSoaV3GetElem( &tfrm->col1, row ), vmathSoaV3GetElem( &tfrm->col2, row ), vmathSoaV3GetElem( &tfrm->col3, row ) );\n}\n\nstatic inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    VmathSoaVector3 tmp0, tmp1, tmp2, inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5;\n    vec_float4 detinv;\n    vmathSoaV3Cross( &tmp0, &tfrm->col1, &tfrm->col2 );\n    vmathSoaV3Cross( &tmp1, &tfrm->col2, &tfrm->col0 );\n    vmathSoaV3Cross( &tmp2, &tfrm->col0, &tfrm->col1 );\n    detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vmathSoaV3Dot( &tfrm->col2, &tmp2 ) );\n    vmathSoaV3MakeFromElems( &inv0, vec_madd( tmp0.x, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.x, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.x, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( &inv1, vec_madd( tmp0.y, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.y, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.y, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( &inv2, vec_madd( tmp0.z, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.z, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.z, detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3Copy( &result->col0, &inv0 );\n    vmathSoaV3Copy( &result->col1, &inv1 );\n    vmathSoaV3Copy( &result->col2, &inv2 );\n    vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x );\n    vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y );\n    vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z );\n    vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 );\n    vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 );\n    vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 );\n    vmathSoaV3Copy( &result->col3, &tmpV3_5 );\n}\n\nstatic inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    VmathSoaVector3 inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5;\n    vmathSoaV3MakeFromElems( &inv0, tfrm->col0.x, tfrm->col1.x, tfrm->col2.x );\n    vmathSoaV3MakeFromElems( &inv1, tfrm->col0.y, tfrm->col1.y, tfrm->col2.y );\n    vmathSoaV3MakeFromElems( &inv2, tfrm->col0.z, tfrm->col1.z, tfrm->col2.z );\n    vmathSoaV3Copy( &result->col0, &inv0 );\n    vmathSoaV3Copy( &result->col1, &inv1 );\n    vmathSoaV3Copy( &result->col2, &inv2 );\n    vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x );\n    vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y );\n    vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z );\n    vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 );\n    vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 );\n    vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 );\n    vmathSoaV3Copy( &result->col3, &tmpV3_5 );\n}\n\nstatic inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3AbsPerElem( &result->col0, &tfrm->col0 );\n    vmathSoaV3AbsPerElem( &result->col1, &tfrm->col1 );\n    vmathSoaV3AbsPerElem( &result->col2, &tfrm->col2 );\n    vmathSoaV3AbsPerElem( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = vec_add( vec_add( vec_madd( tfrm->col0.x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tfrm->col1.x, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tfrm->col2.x, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_add( vec_add( vec_madd( tfrm->col0.y, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tfrm->col1.y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tfrm->col2.y, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_add( vec_add( vec_madd( tfrm->col0.z, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tfrm->col1.z, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tfrm->col2.z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = vec_add( vec_add( vec_add( vec_madd( tfrm->col0.x, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tfrm->col1.x, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tfrm->col2.x, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), tfrm->col3.x );\n    tmpY = vec_add( vec_add( vec_add( vec_madd( tfrm->col0.y, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tfrm->col1.y, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tfrm->col2.y, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), tfrm->col3.y );\n    tmpZ = vec_add( vec_add( vec_add( vec_madd( tfrm->col0.z, pnt->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tfrm->col1.z, pnt->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tfrm->col2.z, pnt->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), tfrm->col3.z );\n    vmathSoaP3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 )\n{\n    VmathSoaTransform3 tmpResult;\n    VmathSoaPoint3 tmpP3_0, tmpP3_1;\n    vmathSoaT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 );\n    vmathSoaT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 );\n    vmathSoaT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 );\n    vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathSoaT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 );\n    vmathSoaV3MakeFromP3( &tmpResult.col3, &tmpP3_1 );\n    vmathSoaT3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 )\n{\n    vmathSoaV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 );\n    vmathSoaV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 );\n    vmathSoaV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 );\n    vmathSoaV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 );\n}\n\nstatic inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result )\n{\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeZAxis( &result->col2 );\n    vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm )\n{\n    vmathSoaV3Copy( &result->col0, &tfrm->col0 );\n    vmathSoaV3Copy( &result->col1, &tfrm->col1 );\n    vmathSoaV3Copy( &result->col2, &tfrm->col2 );\n}\n\nstatic inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 );\n}\n\nstatic inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s );\n    vmathSoaV3MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c );\n    vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeFromElems( &result->col2, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );\n    vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeZAxis( &result->col2 );\n    vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ->x, &sX, &cX );\n    sincosf4( radiansXYZ->y, &sY, &cY );\n    sincosf4( radiansXYZ->z, &sZ, &cZ );\n    tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col0, vec_madd( cZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), negatef4( sY ) );\n    vmathSoaV3MakeFromElems( &result->col1, vec_sub( vec_madd( tmp0, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( tmp1, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( &result->col2, vec_add( vec_madd( tmp0, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( tmp1, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    VmathSoaMatrix3 tmpM3_0;\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3MakeRotationAxis( &tmpM3_0, radians, unitVec );\n    vmathSoaV3MakeFromScalar( &tmpV3_0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat )\n{\n    VmathSoaMatrix3 tmpM3_0;\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathSoaV3MakeFromScalar( &tmpV3_0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3MakeFromElems( &result->col0, scaleVec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathSoaV3MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec->z );\n    vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3ScalarMul( &result->col0, &tfrm->col0, vmathSoaV3GetX( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col1, &tfrm->col1, vmathSoaV3GetY( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col2, &tfrm->col2, vmathSoaV3GetZ( scaleVec ) );\n    vmathSoaV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3MulPerElem( &result->col0, &tfrm->col0, scaleVec );\n    vmathSoaV3MulPerElem( &result->col1, &tfrm->col1, scaleVec );\n    vmathSoaV3MulPerElem( &result->col2, &tfrm->col2, scaleVec );\n    vmathSoaV3MulPerElem( &result->col3, &tfrm->col3, scaleVec );\n}\n\nstatic inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeZAxis( &result->col2 );\n    vmathSoaV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 )\n{\n    vmathSoaV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 );\n    vmathSoaV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 );\n    vmathSoaV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 );\n    vmathSoaV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm )\n{\n    VmathTransform3 mat0, mat1, mat2, mat3;\n    vmathSoaT3Get4Aos( tfrm, &mat0, &mat1, &mat2, &mat3 );\n    printf(\"slot 0:\\n\");\n    vmathT3Print( &mat0 );\n    printf(\"slot 1:\\n\");\n    vmathT3Print( &mat1 );\n    printf(\"slot 2:\\n\");\n    vmathT3Print( &mat2 );\n    printf(\"slot 3:\\n\");\n    vmathT3Print( &mat3 );\n}\n\nstatic inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathSoaT3Print( tfrm );\n}\n\n#endif\n\nstatic inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *tfrm )\n{\n    vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw;\n    vec_uint4 negTrace, ZgtX, ZgtY, YgtX;\n    vec_uint4 largestXorY, largestYorZ, largestZorX;\n\n    xx = tfrm->col0.x;\n    yx = tfrm->col0.y;\n    zx = tfrm->col0.z;\n    xy = tfrm->col1.x;\n    yy = tfrm->col1.y;\n    zy = tfrm->col1.z;\n    xz = tfrm->col2.x;\n    yz = tfrm->col2.y;\n    zz = tfrm->col2.z;\n\n    trace = vec_add( vec_add( xx, yy ), zz );\n\n    negTrace = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), trace );\n    ZgtX = (vec_uint4)vec_cmpgt( zz, xx );\n    ZgtY = (vec_uint4)vec_cmpgt( zz, yy );\n    YgtX = (vec_uint4)vec_cmpgt( yy, xx );\n    largestXorY = vec_andc( negTrace, vec_and( ZgtX, ZgtY ) );\n    largestYorZ = vec_and( negTrace, vec_or( YgtX, ZgtX ) );\n    largestZorX = vec_andc( negTrace, vec_andc( YgtX, ZgtY ) );\n    \n    zz = vec_sel( zz, negatef4(zz), largestXorY );\n    xy = vec_sel( xy, negatef4(xy), largestXorY );\n    xx = vec_sel( xx, negatef4(xx), largestYorZ );\n    yz = vec_sel( yz, negatef4(yz), largestYorZ );\n    yy = vec_sel( yy, negatef4(yy), largestZorX );\n    zx = vec_sel( zx, negatef4(zx), largestZorX );\n\n    radicand = vec_add( vec_add( vec_add( xx, yy ), zz ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    scale = vec_madd( ((vec_float4){0.5f,0.5f,0.5f,0.5f}), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( radicand ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n\n    tmpx = vec_madd( vec_sub( zy, yz ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmpy = vec_madd( vec_sub( xz, zx ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmpz = vec_madd( vec_sub( yx, xy ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmpw = vec_madd( radicand, scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qx = tmpx;\n    qy = tmpy;\n    qz = tmpz;\n    qw = tmpw;\n\n    qx = vec_sel( qx, tmpw, largestXorY );\n    qy = vec_sel( qy, tmpz, largestXorY );\n    qz = vec_sel( qz, tmpy, largestXorY );\n    qw = vec_sel( qw, tmpx, largestXorY );\n    tmpx = qx;\n    tmpz = qz;\n    qx = vec_sel( qx, qy, largestYorZ );\n    qy = vec_sel( qy, tmpx, largestYorZ );\n    qz = vec_sel( qz, qw, largestYorZ );\n    qw = vec_sel( qw, tmpz, largestYorZ );\n\n    result->x = qx;\n    result->y = qy;\n    result->z = qz;\n    result->w = qw;\n}\n\nstatic inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *tfrm0, const VmathSoaVector3 *tfrm1 )\n{\n    vmathSoaV3ScalarMul( &result->col0, tfrm0, vmathSoaV3GetX( tfrm1 ) );\n    vmathSoaV3ScalarMul( &result->col1, tfrm0, vmathSoaV3GetY( tfrm1 ) );\n    vmathSoaV3ScalarMul( &result->col2, tfrm0, vmathSoaV3GetZ( tfrm1 ) );\n}\n\nstatic inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *tfrm0, const VmathSoaVector4 *tfrm1 )\n{\n    vmathSoaV4ScalarMul( &result->col0, tfrm0, vmathSoaV4GetX( tfrm1 ) );\n    vmathSoaV4ScalarMul( &result->col1, tfrm0, vmathSoaV4GetY( tfrm1 ) );\n    vmathSoaV4ScalarMul( &result->col2, tfrm0, vmathSoaV4GetZ( tfrm1 ) );\n    vmathSoaV4ScalarMul( &result->col3, tfrm0, vmathSoaV4GetW( tfrm1 ) );\n}\n\nstatic inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = vec_add( vec_add( vec_madd( vec->x, mat->col0.x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec->y, mat->col0.y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( vec->z, mat->col0.z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_add( vec_add( vec_madd( vec->x, mat->col1.x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec->y, mat->col1.y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( vec->z, mat->col1.z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_add( vec_add( vec_madd( vec->x, mat->col2.x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec->y, mat->col2.y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( vec->z, mat->col2.z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3MakeFromElems( &result->col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec->z, negatef4( vec->y ) );\n    vmathSoaV3MakeFromElems( &result->col1, negatef4( vec->z ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec->x );\n    vmathSoaV3MakeFromElems( &result->col2, vec->y, negatef4( vec->x ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathSoaV3Cross( &tmpV3_0, vec, &mat->col0 );\n    vmathSoaV3Cross( &tmpV3_1, vec, &mat->col1 );\n    vmathSoaV3Cross( &tmpV3_2, vec, &mat->col2 );\n    vmathSoaM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 );\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/mat_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_SOA_V_C_H\n#define _VECTORMATH_MAT_SOA_V_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromCols(&result, &_col0, &_col1, &_col2);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromAos(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3);\n    return result;\n}\n\nstatic inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 )\n{\n    vmathSoaM3Get4Aos(&mat, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col0 )\n{\n    vmathSoaM3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col1 )\n{\n    vmathSoaM3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col2 )\n{\n    vmathSoaM3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec )\n{\n    vmathSoaM3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec )\n{\n    vmathSoaM3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val )\n{\n    vmathSoaM3SetElem(result, col, row, val);\n}\n\nstatic inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row )\n{\n    return vmathSoaM3GetElem(&mat, col, row);\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat )\n{\n    return vmathSoaM3Determinant(&mat);\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat )\n{\n    vmathSoaM3Print(&mat);\n}\n\nstatic inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name )\n{\n    vmathSoaM3Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromT3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 _col0, VmathSoaVector4 _col1, VmathSoaVector4 _col2, VmathSoaVector4 _col3 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromM3V3(&result, &mat, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromAos(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3);\n    return result;\n}\n\nstatic inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 )\n{\n    vmathSoaM4Get4Aos(&mat, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col0 )\n{\n    vmathSoaM4SetCol0(result, &_col0);\n}\n\nstatic inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col1 )\n{\n    vmathSoaM4SetCol1(result, &_col1);\n}\n\nstatic inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col2 )\n{\n    vmathSoaM4SetCol2(result, &_col2);\n}\n\nstatic inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col3 )\n{\n    vmathSoaM4SetCol3(result, &_col3);\n}\n\nstatic inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec )\n{\n    vmathSoaM4SetCol(result, col, &vec);\n}\n\nstatic inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec )\n{\n    vmathSoaM4SetRow(result, row, &vec);\n}\n\nstatic inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val )\n{\n    vmathSoaM4SetElem(result, col, row, val);\n}\n\nstatic inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row )\n{\n    return vmathSoaM4GetElem(&mat, col, row);\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4AffineInverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4OrthoInverse(&result, &mat);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat )\n{\n    return vmathSoaM4Determinant(&mat);\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4MulV4(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4MulP3(&result, &mat, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MulT3(&result, &mat, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 )\n{\n    vmathSoaM4SetUpper3x3(result, &mat3);\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM4GetUpper3x3(&result, &mat);\n    return result;\n}\n\nstatic inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec )\n{\n    vmathSoaM4SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM4GetTranslation(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat )\n{\n    vmathSoaM4Print(&mat);\n}\n\nstatic inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name )\n{\n    vmathSoaM4Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2, VmathSoaVector3 _col3 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromM3V3(&result, &tfrm, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromAos(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFrom4Aos(&result, &tfrm0, &tfrm1, &tfrm2, &tfrm3);\n    return result;\n}\n\nstatic inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 )\n{\n    vmathSoaT3Get4Aos(&tfrm, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 _col0 )\n{\n    vmathSoaT3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 _col1 )\n{\n    vmathSoaT3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 _col2 )\n{\n    vmathSoaT3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 _col3 )\n{\n    vmathSoaT3SetCol3(result, &_col3);\n}\n\nstatic inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec )\n{\n    vmathSoaT3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec )\n{\n    vmathSoaT3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val )\n{\n    vmathSoaT3SetElem(result, col, row, val);\n}\n\nstatic inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row )\n{\n    return vmathSoaT3GetElem(&tfrm, col, row);\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol0(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol1(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol2(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol(&result, &tfrm, col);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row )\n{\n    VmathSoaVector4 result;\n    vmathSoaT3GetRow(&result, &tfrm, row);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3Inverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3OrthoInverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3AbsPerElem(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3MulV3(&result, &tfrm, &vec);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaT3MulP3(&result, &tfrm, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3Mul(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MulPerElem(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 tfrm )\n{\n    vmathSoaT3SetUpper3x3(result, &tfrm);\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaT3GetUpper3x3(&result, &tfrm);\n    return result;\n}\n\nstatic inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec )\n{\n    vmathSoaT3SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetTranslation(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3AppendScale(&result, &tfrm, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3PrependScale(&result, &scaleVec, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3Select(&result, &tfrm0, &tfrm1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm )\n{\n    vmathSoaT3Print(&tfrm);\n}\n\nstatic inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name )\n{\n    vmathSoaT3Prints(&tfrm, name);\n}\n\n#endif\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 tfrm )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromM3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 tfrm0, VmathSoaVector3 tfrm1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaV3Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 tfrm0, VmathSoaVector4 tfrm1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaV4Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3RowMul(&result, &vec, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaV3CrossMatrix(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaV3CrossMatrixMul(&result, &vec, &mat);\n    return result;\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_C_H\n#define _VECTORMATH_QUAT_AOS_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat )\n{\n    result->vec128 = quat->vec128;\n}\n\nstatic inline void vmathQMakeFromElems( VmathQuat *result, float _x, float _y, float _z, float _w )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) &\n        __builtin_constant_p(_z) & __builtin_constant_p(_w)) {\n        result->vec128 = (vec_float4){_x, _y, _z, _w};\n    } else {\n        float *pf = (float *)&result->vec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n        pf[3] = _w;\n    }\n}\n\nstatic inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float _w )\n{\n    result->vec128 = xyz->vec128;\n    _vmathVfSetElement(result->vec128, _w, 3);\n}\n\nstatic inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathQMakeFromScalar( VmathQuat *result, float scalar )\n{\n    result->vec128 = _vmathVfSplatScalar(scalar);\n}\n\nstatic inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathQMakeIdentity( VmathQuat *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0001;\n}\n\nstatic inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    VmathQuat tmpQ_0, tmpQ_1;\n    vmathQSub( &tmpQ_0, quat1, quat0 );\n    vmathQScalarMul( &tmpQ_1, &tmpQ_0, t );\n    vmathQAdd( result, quat0, &tmpQ_1 );\n}\n\nstatic inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 )\n{\n    VmathQuat start;\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot4( unitQuat0->vec128, unitQuat1->vec128 );\n    cosAngle = vec_splat( cosAngle, 0 );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), cosAngle );\n    cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start.vec128 = vec_sel( unitQuat0->vec128, negatef4( unitQuat0->vec128 ), selectMask );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = _vmathVfSplatScalar(t);\n    oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sines = sinf4( angles );\n    scales = divf4( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    result->vec128 = vec_madd( start.vec128, scale0, vec_madd( unitQuat1->vec128, scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 )\n{\n    VmathQuat tmp0, tmp1;\n    vmathQSlerp( &tmp0, t, unitQuat0, unitQuat3 );\n    vmathQSlerp( &tmp1, t, unitQuat1, unitQuat2 );\n    vmathQSlerp( result, ( ( 2.0f * t ) * ( 1.0f - t ) ), &tmp0, &tmp1 );\n}\n\nstatic inline vec_float4 vmathQGet128( const VmathQuat *quat )\n{\n    return quat->vec128;\n}\n\nstatic inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec_sel( vec->vec128, result->vec128, _VECTORMATH_MASK_0x000F );\n}\n\nstatic inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat )\n{\n    result->vec128 = quat->vec128;\n}\n\nstatic inline void vmathQSetX( VmathQuat *result, float _x )\n{\n    _vmathVfSetElement(result->vec128, _x, 0);\n}\n\nstatic inline float vmathQGetX( const VmathQuat *quat )\n{\n    return _vmathVfGetElement(quat->vec128, 0);\n}\n\nstatic inline void vmathQSetY( VmathQuat *result, float _y )\n{\n    _vmathVfSetElement(result->vec128, _y, 1);\n}\n\nstatic inline float vmathQGetY( const VmathQuat *quat )\n{\n    return _vmathVfGetElement(quat->vec128, 1);\n}\n\nstatic inline void vmathQSetZ( VmathQuat *result, float _z )\n{\n    _vmathVfSetElement(result->vec128, _z, 2);\n}\n\nstatic inline float vmathQGetZ( const VmathQuat *quat )\n{\n    return _vmathVfGetElement(quat->vec128, 2);\n}\n\nstatic inline void vmathQSetW( VmathQuat *result, float _w )\n{\n    _vmathVfSetElement(result->vec128, _w, 3);\n}\n\nstatic inline float vmathQGetW( const VmathQuat *quat )\n{\n    return _vmathVfGetElement(quat->vec128, 3);\n}\n\nstatic inline void vmathQSetElem( VmathQuat *result, int idx, float value )\n{\n    _vmathVfSetElement(result->vec128, value, idx);\n}\n\nstatic inline float vmathQGetElem( const VmathQuat *quat, int idx )\n{\n    return _vmathVfGetElement(quat->vec128, idx);\n}\n\nstatic inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    result->vec128 = vec_add( quat0->vec128, quat1->vec128 );\n}\n\nstatic inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    result->vec128 = vec_sub( quat0->vec128, quat1->vec128 );\n}\n\nstatic inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar )\n{\n    result->vec128 = vec_madd( quat->vec128, _vmathVfSplatScalar(scalar), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar )\n{\n    result->vec128 = divf4( quat->vec128, _vmathVfSplatScalar(scalar) );\n}\n\nstatic inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat )\n{\n    result->vec128 = negatef4( quat->vec128 );\n}\n\nstatic inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    vec_float4 result = _vmathVfDot4( quat0->vec128, quat1->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathQNorm( const VmathQuat *quat )\n{\n    vec_float4 result = _vmathVfDot4( quat->vec128, quat->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathQLength( const VmathQuat *quat )\n{\n    return sqrtf( vmathQNorm( quat ) );\n}\n\nstatic inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat )\n{\n    vec_float4 dot = _vmathVfDot4( quat->vec128, quat->vec128 );\n    result->vec128 = vec_madd( quat->vec128, rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 )\n{\n    VmathVector3 crossVec, tmpV3_0;\n    vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res;\n    cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 );\n    cosAngle = vec_splat( cosAngle, 0 );\n    cosAngleX2Plus2 = vec_madd( cosAngle, ((vec_float4){2.0f,2.0f,2.0f,2.0f}), ((vec_float4){2.0f,2.0f,2.0f,2.0f}) );\n    recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 );\n    cosHalfAngleX2 = vec_madd( recipCosHalfAngleX2, cosAngleX2Plus2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    vmathV3Cross( &tmpV3_0, unitVec0, unitVec1 );\n    crossVec = tmpV3_0;\n    res = vec_madd( crossVec.vec128, recipCosHalfAngleX2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_sel( res, vec_madd( cosHalfAngleX2, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), _VECTORMATH_MASK_0x000F );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( _vmathVfSplatScalar(radians), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( vec_madd( unitVec->vec128, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c, _VECTORMATH_MASK_0x000F );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationX( VmathQuat *result, float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( _vmathVfSplatScalar(radians), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0xF000 );\n    res = vec_sel( res, c, _VECTORMATH_MASK_0x000F );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationY( VmathQuat *result, float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( _vmathVfSplatScalar(radians), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x0F00 );\n    res = vec_sel( res, c, _VECTORMATH_MASK_0x000F );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationZ( VmathQuat *result, float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( _vmathVfSplatScalar(radians), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x00F0 );\n    res = vec_sel( res, c, _VECTORMATH_MASK_0x000F );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;\n    vec_float4 product, l_wxyz, r_wxyz, xy, qw;\n    ldata = quat0->vec128;\n    rdata = quat1->vec128;\n    tmp0 = vec_perm( ldata, ldata, _VECTORMATH_PERM_YZXW );\n    tmp1 = vec_perm( rdata, rdata, _VECTORMATH_PERM_ZXYW );\n    tmp2 = vec_perm( ldata, ldata, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( rdata, rdata, _VECTORMATH_PERM_YZXW );\n    qv = vec_madd( vec_splat( ldata, 3 ), rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv );\n    qv = vec_madd( tmp0, tmp1, qv );\n    qv = vec_nmsub( tmp2, tmp3, qv );\n    product = vec_madd( ldata, rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    l_wxyz = vec_sld( ldata, ldata, 12 );\n    r_wxyz = vec_sld( rdata, rdata, 12 );\n    qw = vec_nmsub( l_wxyz, r_wxyz, product );\n    xy = vec_madd( l_wxyz, r_wxyz, product );\n    qw = vec_sub( qw, vec_sld( xy, xy, 8 ) );\n    result->vec128 = vec_sel( qv, qw, _VECTORMATH_MASK_0x000F );\n}\n\nstatic inline void vmathQRotate( VmathVector3 *result, const VmathQuat *quat, const VmathVector3 *vec )\n{\n    vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res;\n    qdata = quat->vec128;\n    vdata = vec->vec128;\n    tmp0 = vec_perm( qdata, qdata, _VECTORMATH_PERM_YZXW );\n    tmp1 = vec_perm( vdata, vdata, _VECTORMATH_PERM_ZXYW );\n    tmp2 = vec_perm( qdata, qdata, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( vdata, vdata, _VECTORMATH_PERM_YZXW );\n    wwww = vec_splat( qdata, 3 );\n    qv = vec_madd( wwww, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qv = vec_madd( tmp0, tmp1, qv );\n    qv = vec_nmsub( tmp2, tmp3, qv );\n    product = vec_madd( qdata, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product );\n    qw = vec_add( vec_sld( product, product, 8 ), qw );\n    tmp1 = vec_perm( qv, qv, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( qv, qv, _VECTORMATH_PERM_YZXW );\n    res = vec_madd( vec_splat( qw, 0 ), qdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( wwww, qv, res );\n    res = vec_madd( tmp0, tmp1, res );\n    res = vec_nmsub( tmp2, tmp3, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQConj( VmathQuat *result, const VmathQuat *quat )\n{\n    result->vec128 = vec_xor( quat->vec128, ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) );\n}\n\nstatic inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 )\n{\n    unsigned int tmp;\n    tmp = (unsigned int)-(select1 > 0);\n    result->vec128 = vec_sel( quat0->vec128, quat1->vec128, _vmathVuiSplatScalar(tmp) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathQPrint( const VmathQuat *quat )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat->vec128;\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\nstatic inline void vmathQPrints( const VmathQuat *quat, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat->vec128;\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/quat_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_V_C_H\n#define _VECTORMATH_QUAT_AOS_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathQuat vmathQMakeFromElems_V( float _x, float _y, float _z, float _w )\n{\n    VmathQuat result;\n    vmathQMakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float _w )\n{\n    VmathQuat result;\n    vmathQMakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec )\n{\n    VmathQuat result;\n    vmathQMakeFromV4(&result, &vec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromScalar_V( float scalar )\n{\n    VmathQuat result;\n    vmathQMakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 )\n{\n    VmathQuat result;\n    vmathQMakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeIdentity_V( )\n{\n    VmathQuat result;\n    vmathQMakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQLerp(&result, t, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 )\n{\n    VmathQuat result;\n    vmathQSlerp(&result, t, &unitQuat0, &unitQuat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 )\n{\n    VmathQuat result;\n    vmathQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3);\n    return result;\n}\n\nstatic inline vec_float4 vmathQGet128_V( VmathQuat quat )\n{\n    return vmathQGet128(&quat);\n}\n\nstatic inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec )\n{\n    vmathQSetXYZ(result, &vec);\n}\n\nstatic inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat )\n{\n    VmathVector3 result;\n    vmathQGetXYZ(&result, &quat);\n    return result;\n}\n\nstatic inline void vmathQSetX_V( VmathQuat *result, float _x )\n{\n    vmathQSetX(result, _x);\n}\n\nstatic inline float vmathQGetX_V( VmathQuat quat )\n{\n    return vmathQGetX(&quat);\n}\n\nstatic inline void vmathQSetY_V( VmathQuat *result, float _y )\n{\n    vmathQSetY(result, _y);\n}\n\nstatic inline float vmathQGetY_V( VmathQuat quat )\n{\n    return vmathQGetY(&quat);\n}\n\nstatic inline void vmathQSetZ_V( VmathQuat *result, float _z )\n{\n    vmathQSetZ(result, _z);\n}\n\nstatic inline float vmathQGetZ_V( VmathQuat quat )\n{\n    return vmathQGetZ(&quat);\n}\n\nstatic inline void vmathQSetW_V( VmathQuat *result, float _w )\n{\n    vmathQSetW(result, _w);\n}\n\nstatic inline float vmathQGetW_V( VmathQuat quat )\n{\n    return vmathQGetW(&quat);\n}\n\nstatic inline void vmathQSetElem_V( VmathQuat *result, int idx, float value )\n{\n    vmathQSetElem(result, idx, value);\n}\n\nstatic inline float vmathQGetElem_V( VmathQuat quat, int idx )\n{\n    return vmathQGetElem(&quat, idx);\n}\n\nstatic inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQAdd(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQSub(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar )\n{\n    VmathQuat result;\n    vmathQScalarMul(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar )\n{\n    VmathQuat result;\n    vmathQScalarDiv(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQNeg_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQNeg(&result, &quat);\n    return result;\n}\n\nstatic inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    return vmathQDot(&quat0, &quat1);\n}\n\nstatic inline float vmathQNorm_V( VmathQuat quat )\n{\n    return vmathQNorm(&quat);\n}\n\nstatic inline float vmathQLength_V( VmathQuat quat )\n{\n    return vmathQLength(&quat);\n}\n\nstatic inline VmathQuat vmathQNormalize_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQNormalize(&result, &quat);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 )\n{\n    VmathQuat result;\n    vmathQMakeRotationArc(&result, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathQuat result;\n    vmathQMakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationX_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationY_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationZ_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQMul(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathQRotate_V( VmathQuat quat, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathQRotate(&result, &quat, &vec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQConj_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQConj(&result, &quat);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 )\n{\n    VmathQuat result;\n    vmathQSelect(&result, &quat0, &quat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathQPrint_V( VmathQuat quat )\n{\n    vmathQPrint(&quat);\n}\n\nstatic inline void vmathQPrints_V( VmathQuat quat, const char *name )\n{\n    vmathQPrints(&quat, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/quat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_SOA_C_H\n#define _VECTORMATH_QUAT_SOA_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    result->x = quat->x;\n    result->y = quat->y;\n    result->z = quat->z;\n    result->w = quat->w;\n}\n\nstatic inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n    result->w = _w;\n}\n\nstatic inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 _w )\n{\n    vmathSoaQSetXYZ( result, xyz );\n    vmathSoaQSetW( result, _w );\n}\n\nstatic inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = vec->w;\n}\n\nstatic inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n    result->w = scalar;\n}\n\nstatic inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat )\n{\n    vec_float4 vec128 = quat->vec128;\n    result->x = vec_splat( vec128, 0 );\n    result->y = vec_splat( vec128, 1 );\n    result->z = vec_splat( vec128, 2 );\n    result->w = vec_splat( vec128, 3 );\n}\n\nstatic inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( quat0->vec128, quat2->vec128 );\n    tmp1 = vec_mergeh( quat1->vec128, quat3->vec128 );\n    tmp2 = vec_mergel( quat0->vec128, quat2->vec128 );\n    tmp3 = vec_mergel( quat1->vec128, quat3->vec128 );\n    result->x = vec_mergeh( tmp0, tmp1 );\n    result->y = vec_mergel( tmp0, tmp1 );\n    result->z = vec_mergeh( tmp2, tmp3 );\n    result->w = vec_mergel( tmp2, tmp3 );\n}\n\nstatic inline void vmathSoaQMakeIdentity( VmathSoaQuat *result )\n{\n    vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    VmathSoaQuat tmpQ_0, tmpQ_1;\n    vmathSoaQSub( &tmpQ_0, quat1, quat0 );\n    vmathSoaQScalarMul( &tmpQ_1, &tmpQ_0, t );\n    vmathSoaQAdd( result, quat0, &tmpQ_1 );\n}\n\nstatic inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 )\n{\n    VmathSoaQuat start, tmpQ_0, tmpQ_1;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = vmathSoaQDot( unitQuat0, unitQuat1 );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){0.0f,0.0f,0.0f,0.0f}, cosAngle );\n    cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    vmathSoaQSetX( &start, vec_sel( unitQuat0->x, negatef4( unitQuat0->x ), selectMask ) );\n    vmathSoaQSetY( &start, vec_sel( unitQuat0->y, negatef4( unitQuat0->y ), selectMask ) );\n    vmathSoaQSetZ( &start, vec_sel( unitQuat0->z, negatef4( unitQuat0->z ), selectMask ) );\n    vmathSoaQSetW( &start, vec_sel( unitQuat0->w, negatef4( unitQuat0->w ), selectMask ) );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );\n    scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    vmathSoaQScalarMul( &tmpQ_0, &start, scale0 );\n    vmathSoaQScalarMul( &tmpQ_1, unitQuat1, scale1 );\n    vmathSoaQAdd( result, &tmpQ_0, &tmpQ_1 );\n}\n\nstatic inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 )\n{\n    VmathSoaQuat tmp0, tmp1;\n    vmathSoaQSlerp( &tmp0, t, unitQuat0, unitQuat3 );\n    vmathSoaQSlerp( &tmp1, t, unitQuat1, unitQuat2 );\n    vmathSoaQSlerp( result, vec_madd( vec_madd( ((vec_float4){2.0f,2.0f,2.0f,2.0f}), t, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), &tmp0, &tmp1 );\n}\n\nstatic inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( quat->x, quat->z );\n    tmp1 = vec_mergeh( quat->y, quat->w );\n    tmp2 = vec_mergel( quat->x, quat->z );\n    tmp3 = vec_mergel( quat->y, quat->w );\n    vmathQMakeFrom128( result0, vec_mergeh( tmp0, tmp1 ) );\n    vmathQMakeFrom128( result1, vec_mergel( tmp0, tmp1 ) );\n    vmathQMakeFrom128( result2, vec_mergeh( tmp2, tmp3 ) );\n    vmathQMakeFrom128( result3, vec_mergel( tmp2, tmp3 ) );\n}\n\nstatic inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat )\n{\n    vmathSoaV3MakeFromElems( result, quat->x, quat->y, quat->z );\n}\n\nstatic inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat )\n{\n    return quat->x;\n}\n\nstatic inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat )\n{\n    return quat->y;\n}\n\nstatic inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat )\n{\n    return quat->z;\n}\n\nstatic inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 _w )\n{\n    result->w = _w;\n}\n\nstatic inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat )\n{\n    return quat->w;\n}\n\nstatic inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx )\n{\n    return *(&quat->x + idx);\n}\n\nstatic inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    result->x = vec_add( quat0->x, quat1->x );\n    result->y = vec_add( quat0->y, quat1->y );\n    result->z = vec_add( quat0->z, quat1->z );\n    result->w = vec_add( quat0->w, quat1->w );\n}\n\nstatic inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    result->x = vec_sub( quat0->x, quat1->x );\n    result->y = vec_sub( quat0->y, quat1->y );\n    result->z = vec_sub( quat0->z, quat1->z );\n    result->w = vec_sub( quat0->w, quat1->w );\n}\n\nstatic inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar )\n{\n    result->x = vec_madd( quat->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( quat->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( quat->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->w = vec_madd( quat->w, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar )\n{\n    result->x = divf4( quat->x, scalar );\n    result->y = divf4( quat->y, scalar );\n    result->z = divf4( quat->z, scalar );\n    result->w = divf4( quat->w, scalar );\n}\n\nstatic inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    result->x = negatef4( quat->x );\n    result->y = negatef4( quat->y );\n    result->z = negatef4( quat->z );\n    result->w = negatef4( quat->w );\n}\n\nstatic inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    vec_float4 result;\n    result = vec_madd( quat0->x, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( quat0->y, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat0->z, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat0->w, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat )\n{\n    vec_float4 result;\n    result = vec_madd( quat->x, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( quat->y, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat->z, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat->w, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat )\n{\n    return sqrtf4( vmathSoaQNorm( quat ) );\n}\n\nstatic inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = vmathSoaQNorm( quat );\n    lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );\n    result->x = vec_madd( quat->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( quat->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( quat->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->w = vec_madd( quat->w, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vec_float4 cosHalfAngleX2, recipCosHalfAngleX2;\n    cosHalfAngleX2 = sqrtf4( vec_madd( ((vec_float4){2.0f,2.0f,2.0f,2.0f}), vec_add( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vmathSoaV3Dot( unitVec0, unitVec1 ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    recipCosHalfAngleX2 = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), cosHalfAngleX2 );\n    vmathSoaV3Cross( &tmpV3_0, unitVec0, unitVec1 );\n    vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 );\n    vmathSoaQMakeFromV3Scalar( result, &tmpV3_1, vec_madd( cosHalfAngleX2, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    VmathSoaVector3 tmpV3_0;\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    vmathSoaV3ScalarMul( &tmpV3_0, unitVec, s );\n    vmathSoaQMakeFromV3Scalar( result, &tmpV3_0, c );\n}\n\nstatic inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    vmathSoaQMakeFromElems( result, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );\n}\n\nstatic inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );\n}\n\nstatic inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, c );\n}\n\nstatic inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = vec_sub( vec_add( vec_add( vec_madd( quat0->w, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->x, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->y, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->z, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_sub( vec_add( vec_add( vec_madd( quat0->w, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->y, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->z, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->x, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_sub( vec_add( vec_add( vec_madd( quat0->w, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->z, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->x, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->y, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpW = vec_sub( vec_sub( vec_sub( vec_madd( quat0->w, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->x, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->y, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->z, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );\n}\n\nstatic inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *quat, const VmathSoaVector3 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = vec_sub( vec_add( vec_madd( quat->w, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->y, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->z, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_sub( vec_add( vec_madd( quat->w, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->z, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->x, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_sub( vec_add( vec_madd( quat->w, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->x, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->y, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpW = vec_add( vec_add( vec_madd( quat->x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result->x = vec_add( vec_sub( vec_add( vec_madd( tmpW, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpX, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpY, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpZ, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result->y = vec_add( vec_sub( vec_add( vec_madd( tmpW, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpY, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpZ, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpX, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result->z = vec_add( vec_sub( vec_add( vec_madd( tmpW, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpZ, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpX, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpY, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    vmathSoaQMakeFromElems( result, negatef4( quat->x ), negatef4( quat->y ), negatef4( quat->z ), quat->w );\n}\n\nstatic inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 )\n{\n    result->x = vec_sel( quat0->x, quat1->x, select1 );\n    result->y = vec_sel( quat0->y, quat1->y, select1 );\n    result->z = vec_sel( quat0->z, quat1->z, select1 );\n    result->w = vec_sel( quat0->w, quat1->w, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaQPrint( const VmathSoaQuat *quat )\n{\n    VmathQuat vec0, vec1, vec2, vec3;\n    vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathQPrint( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathQPrint( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathQPrint( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathQPrint( &vec3 );\n}\n\nstatic inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name )\n{\n    VmathQuat vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathQPrint( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathQPrint( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathQPrint( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathQPrint( &vec3 );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/quat_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_SOA_V_C_H\n#define _VECTORMATH_QUAT_SOA_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromV4(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromAos(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFrom4Aos(&result, &quat0, &quat1, &quat2, &quat3);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeIdentity_V( )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQLerp(&result, t, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSlerp(&result, t, &unitQuat0, &unitQuat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3);\n    return result;\n}\n\nstatic inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 )\n{\n    vmathSoaQGet4Aos(&quat, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec )\n{\n    vmathSoaQSetXYZ(result, &vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat )\n{\n    VmathSoaVector3 result;\n    vmathSoaQGetXYZ(&result, &quat);\n    return result;\n}\n\nstatic inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 _x )\n{\n    vmathSoaQSetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetX(&quat);\n}\n\nstatic inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 _y )\n{\n    vmathSoaQSetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetY(&quat);\n}\n\nstatic inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 _z )\n{\n    vmathSoaQSetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetZ(&quat);\n}\n\nstatic inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 _w )\n{\n    vmathSoaQSetW(result, _w);\n}\n\nstatic inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetW(&quat);\n}\n\nstatic inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value )\n{\n    vmathSoaQSetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx )\n{\n    return vmathSoaQGetElem(&quat, idx);\n}\n\nstatic inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQAdd(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSub(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar )\n{\n    VmathSoaQuat result;\n    vmathSoaQScalarMul(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar )\n{\n    VmathSoaQuat result;\n    vmathSoaQScalarDiv(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQNeg(&result, &quat);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    return vmathSoaQDot(&quat0, &quat1);\n}\n\nstatic inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat )\n{\n    return vmathSoaQNorm(&quat);\n}\n\nstatic inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat )\n{\n    return vmathSoaQLength(&quat);\n}\n\nstatic inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQNormalize(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationArc(&result, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQMul(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat quat, VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaQRotate(&result, &quat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQConj(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSelect(&result, &quat0, &quat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaQPrint_V( VmathSoaQuat quat )\n{\n    vmathSoaQPrint(&quat);\n}\n\nstatic inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name )\n{\n    vmathSoaQPrints(&quat, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_C_H\n#define _VECTORMATH_VEC_AOS_C_H\n#include <altivec.h>\n#include <simdmath.h>\n#include <stddef.h>\n#include \"vec_types.h\"\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for permutes words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A }\n#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }\n#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C }\n#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W }\n#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 }\n#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 }\n#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 }\n#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff }\n#define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\nstatic inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} );\n    result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result );\n    return vec_madd( vec_sld( vec0, vec0, 8 ), vec_sld( vec1, vec1, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} );\n    result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result );\n    return vec_add( vec_sld( result, result, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, result;\n    tmp0 = vec_perm( vec0, vec0, _VECTORMATH_PERM_YZXW );\n    tmp1 = vec_perm( vec1, vec1, _VECTORMATH_PERM_ZXYW );\n    tmp2 = vec_perm( vec0, vec0, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( vec1, vec1, _VECTORMATH_PERM_YZXW );\n    result = vec_madd( tmp0, tmp1, (vec_float4){0.0f,0.0f,0.0f,0.0f} );\n    result = vec_nmsub( tmp2, tmp3, result );\n    return result;\n}\n\nstatic inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v)\n{\n    vec_int4 bexp;\n    vec_uint4 mant, sign, hfloat;\n    vec_uint4 notZero, isInf;\n    const vec_uint4 hfloatInf = (vec_uint4){0x00007c00u,0x00007c00u,0x00007c00u,0x00007c00u};\n    const vec_uint4 mergeMant = (vec_uint4){0x000003ffu,0x000003ffu,0x000003ffu,0x000003ffu};\n    const vec_uint4 mergeSign = (vec_uint4){0x00008000u,0x00008000u,0x00008000u,0x00008000u};\n\n    sign = vec_sr((vec_uint4)v, (vec_uint4){16,16,16,16});\n    mant = vec_sr((vec_uint4)v, (vec_uint4){13,13,13,13});\n    bexp = vec_and(vec_sr((vec_int4)v, (vec_uint4){23,23,23,23}), (vec_int4){0xff,0xff,0xff,0xff});\n\n    notZero = (vec_uint4)vec_cmpgt(bexp, (vec_int4){112,112,112,112});\n    isInf = (vec_uint4)vec_cmpgt(bexp, (vec_int4){142,142,142,142});\n\n    bexp = vec_add(bexp, (vec_int4){-112,-112,-112,-112});\n    bexp = vec_sl(bexp, (vec_uint4){10,10,10,10});\n\n    hfloat = vec_sel((vec_uint4)bexp, mant, mergeMant);\n    hfloat = vec_sel((vec_uint4){0,0,0,0}, hfloat, notZero);\n    hfloat = vec_sel(hfloat, hfloatInf, isInf);\n    hfloat = vec_sel(hfloat, sign, mergeSign);\n\n    return hfloat;\n}\n\nstatic inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v)\n{\n    vec_uint4 hfloat_u, hfloat_v;\n    const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31};\n    hfloat_u = _vmathVfToHalfFloatsUnpacked(u);\n    hfloat_v = _vmathVfToHalfFloatsUnpacked(v);\n    return (vec_ushort8)vec_perm(hfloat_u, hfloat_v, pack);\n}\n\n#ifndef __GNUC__\n#define __builtin_constant_p(x) 0\n#endif\n\nstatic inline vec_float4 _vmathVfInsert(vec_float4 dst, vec_float4 src, int slot)\n{\n#ifdef __GNUC__\n    if (__builtin_constant_p(slot)) {\n        dst = vec_sld(dst, dst, slot<<2);\n        dst = vec_sld(dst, src, 4);\n        if (slot != 3) dst = vec_sld(dst, dst, (3-slot)<<2);\n        return dst;\n    } else\n#endif\n    {\n        vec_uchar16 shiftpattern = vec_lvsr( 0, (float *)(size_t)(slot<<2) );\n        vec_uint4 selectmask = (vec_uint4)vec_perm( (vec_uint4){0,0,0,0}, _VECTORMATH_MASK_0xF000, shiftpattern );\n        return vec_sel( dst, src, selectmask );\n    }\n}\n\n#define _vmathVfGetElement(vec, slot) ((float *)&(vec))[slot]\n#ifdef _VECTORMATH_SET_CONSTS_IN_MEM\n#define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar\n#else\n#define _vmathVfSetElement(vec, scalar, slot)                                            \\\n{                                                                                        \\\n    if (__builtin_constant_p(scalar)) {                                                  \\\n        (vec) = _vmathVfInsert(vec, (vec_float4){scalar, scalar, scalar, scalar}, slot); \\\n    } else {                                                                             \\\n        ((float *)&(vec))[slot] = scalar;                                                \\\n    }                                                                                    \\\n}\n#endif\n\nstatic inline vec_float4 _vmathVfSplatScalar(float scalar)\n{\n    vec_float4 result;\n    if (__builtin_constant_p(scalar)) {\n        result = (vec_float4){scalar, scalar, scalar, scalar};\n    } else {\n        result = vec_ld(0, &scalar);\n        result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0);\n    } \n    return result;\n}\n\nstatic inline vec_uint4 _vmathVuiSplatScalar(unsigned int scalar)\n{\n    vec_uint4 result;\n    if (__builtin_constant_p(scalar)) {\n        result = (vec_uint4){scalar, scalar, scalar, scalar};\n    } else {\n        result = vec_ld(0, &scalar);\n        result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0);\n    } \n    return result;\n}\n\n#endif\n\nstatic inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathV3MakeFromElems( VmathVector3 *result, float _x, float _y, float _z )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) {\n        result->vec128 = (vec_float4){_x, _y, _z, 0.0f};\n    } else {\n        float *pf = (float *)&result->vec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n    }\n}\n\nstatic inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = pnt->vec128;\n}\n\nstatic inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar )\n{\n    result->vec128 = _vmathVfSplatScalar(scalar);\n}\n\nstatic inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathV3MakeXAxis( VmathVector3 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_1000;\n}\n\nstatic inline void vmathV3MakeYAxis( VmathVector3 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0100;\n}\n\nstatic inline void vmathV3MakeZAxis( VmathVector3 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0010;\n}\n\nstatic inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    vmathV3Sub( &tmpV3_0, vec1, vec0 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathV3Add( result, vec0, &tmpV3_1 );\n}\n\nstatic inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 );\n    cosAngle = vec_splat( cosAngle, 0 );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = _vmathVfSplatScalar(t);\n    oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sines = sinf4( angles );\n    scales = divf4( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    result->vec128 = vec_madd( unitVec0->vec128, scale0, vec_madd( unitVec1->vec128, scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline vec_float4 vmathV3Get128( const VmathVector3 *vec )\n{\n    return vec->vec128;\n}\n\nstatic inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = _VECTORMATH_MASK_0x000F;\n    dstVec = vec_sel(vec->vec128, dstVec, mask);\n    *quad = dstVec;\n}\n\nstatic inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = vec_sld( xyzx, yzxy, 12 );\n    xyz2 = vec_sld( yzxy, zxyz, 8 );\n    xyz3 = vec_sld( zxyz, zxyz, 4 );\n    vec0->vec128 = xyzx;\n    vec1->vec128 = xyz1;\n    vec2->vec128 = xyz2;\n    vec3->vec128 = xyz3;\n}\n\nstatic inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = vec_perm( vec0->vec128, vec1->vec128, _VECTORMATH_PERM_XYZA );\n    yzxy = vec_perm( vec1->vec128, vec2->vec128, _VECTORMATH_PERM_YZAB );\n    zxyz = vec_perm( vec2->vec128, vec3->vec128, _VECTORMATH_PERM_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathV3StoreHalfFloats( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, const VmathVector3 *vec4, const VmathVector3 *vec5, const VmathVector3 *vec6, const VmathVector3 *vec7, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathV3StoreXYZArray( vec0, vec1, vec2, vec3, xyz0 );\n    vmathV3StoreXYZArray( vec4, vec5, vec6, vec7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathV3SetX( VmathVector3 *result, float _x )\n{\n    _vmathVfSetElement(result->vec128, _x, 0);\n}\n\nstatic inline float vmathV3GetX( const VmathVector3 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 0);\n}\n\nstatic inline void vmathV3SetY( VmathVector3 *result, float _y )\n{\n    _vmathVfSetElement(result->vec128, _y, 1);\n}\n\nstatic inline float vmathV3GetY( const VmathVector3 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 1);\n}\n\nstatic inline void vmathV3SetZ( VmathVector3 *result, float _z )\n{\n    _vmathVfSetElement(result->vec128, _z, 2);\n}\n\nstatic inline float vmathV3GetZ( const VmathVector3 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 2);\n}\n\nstatic inline void vmathV3SetElem( VmathVector3 *result, int idx, float value )\n{\n    _vmathVfSetElement(result->vec128, value, idx);\n}\n\nstatic inline float vmathV3GetElem( const VmathVector3 *vec, int idx )\n{\n    return _vmathVfGetElement(vec->vec128, idx);\n}\n\nstatic inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = vec_add( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = vec_sub( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = vec_add( vec->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar )\n{\n    result->vec128 = vec_madd( vec->vec128, _vmathVfSplatScalar(scalar), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar )\n{\n    result->vec128 = divf4( vec->vec128, _vmathVfSplatScalar(scalar) );\n}\n\nstatic inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = negatef4( vec->vec128 );\n}\n\nstatic inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = vec_madd( vec0->vec128, vec1->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = divf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = recipf4( vec->vec128 );\n}\n\nstatic inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = sqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = rsqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = fabsf4( vec->vec128 );\n}\n\nstatic inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = copysignf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV3MaxElem( const VmathVector3 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec_splat( vec->vec128, 1 ), vec->vec128 );\n    result = fmaxf4( vec_splat( vec->vec128, 2 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = fminf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV3MinElem( const VmathVector3 *vec )\n{\n    vec_float4 result;\n    result = fminf4( vec_splat( vec->vec128, 1 ), vec->vec128 );\n    result = fminf4( vec_splat( vec->vec128, 2 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV3Sum( const VmathVector3 *vec )\n{\n    vec_float4 result;\n    result = vec_add( vec_splat( vec->vec128, 1 ), vec->vec128 );\n    result = vec_add( vec_splat( vec->vec128, 2 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    vec_float4 result = _vmathVfDot3( vec0->vec128, vec1->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV3LengthSqr( const VmathVector3 *vec )\n{\n    vec_float4 result = _vmathVfDot3( vec->vec128, vec->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV3Length( const VmathVector3 *vec )\n{\n    return sqrtf( vmathV3LengthSqr( vec ) );\n}\n\nstatic inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec )\n{\n    vec_float4 dot = _vmathVfDot3( vec->vec128, vec->vec128 );\n    dot = vec_splat( dot, 0 );\n    result->vec128 = vec_madd( vec->vec128, rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = _vmathVfCross( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 )\n{\n    unsigned int tmp;\n    tmp = (unsigned int)-(select1 > 0);\n    result->vec128 = vec_sel( vec0->vec128, vec1->vec128, _vmathVuiSplatScalar(tmp) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV3Print( const VmathVector3 *vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\nstatic inline void vmathV3Prints( const VmathVector3 *vec, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\nstatic inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathV4MakeFromElems( VmathVector4 *result, float _x, float _y, float _z, float _w )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) &\n        __builtin_constant_p(_z) & __builtin_constant_p(_w)) {\n        result->vec128 = (vec_float4){_x, _y, _z, _w};\n    } else {\n        float *pf = (float *)&result->vec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n        pf[3] = _w;\n    }\n}\n\nstatic inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float _w )\n{\n    result->vec128 = xyz->vec128;\n    _vmathVfSetElement(result->vec128, _w, 3);\n}\n\nstatic inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec->vec128;\n    result->vec128 = _vmathVfInsert(result->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), 3);\n}\n\nstatic inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = pnt->vec128;\n    result->vec128 = _vmathVfInsert(result->vec128, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), 3);\n}\n\nstatic inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat )\n{\n    result->vec128 = quat->vec128;\n}\n\nstatic inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar )\n{\n    result->vec128 = _vmathVfSplatScalar(scalar);\n}\n\nstatic inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathV4MakeXAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_1000;\n}\n\nstatic inline void vmathV4MakeYAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0100;\n}\n\nstatic inline void vmathV4MakeZAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0010;\n}\n\nstatic inline void vmathV4MakeWAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0001;\n}\n\nstatic inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    VmathVector4 tmpV4_0, tmpV4_1;\n    vmathV4Sub( &tmpV4_0, vec1, vec0 );\n    vmathV4ScalarMul( &tmpV4_1, &tmpV4_0, t );\n    vmathV4Add( result, vec0, &tmpV4_1 );\n}\n\nstatic inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot4( unitVec0->vec128, unitVec1->vec128 );\n    cosAngle = vec_splat( cosAngle, 0 );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = _vmathVfSplatScalar(t);\n    oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sines = sinf4( angles );\n    scales = divf4( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    result->vec128 = vec_madd( unitVec0->vec128, scale0, vec_madd( unitVec1->vec128, scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\nstatic inline vec_float4 vmathV4Get128( const VmathVector4 *vec )\n{\n    return vec->vec128;\n}\n\nstatic inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads )\n{\n    twoQuads[0] = _vmath2VfToHalfFloats(vec0->vec128, vec1->vec128);\n    twoQuads[1] = _vmath2VfToHalfFloats(vec2->vec128, vec3->vec128);\n}\n\nstatic inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec_sel( vec->vec128, result->vec128, _VECTORMATH_MASK_0x000F );\n}\n\nstatic inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathV4SetX( VmathVector4 *result, float _x )\n{\n    _vmathVfSetElement(result->vec128, _x, 0);\n}\n\nstatic inline float vmathV4GetX( const VmathVector4 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 0);\n}\n\nstatic inline void vmathV4SetY( VmathVector4 *result, float _y )\n{\n    _vmathVfSetElement(result->vec128, _y, 1);\n}\n\nstatic inline float vmathV4GetY( const VmathVector4 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 1);\n}\n\nstatic inline void vmathV4SetZ( VmathVector4 *result, float _z )\n{\n    _vmathVfSetElement(result->vec128, _z, 2);\n}\n\nstatic inline float vmathV4GetZ( const VmathVector4 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 2);\n}\n\nstatic inline void vmathV4SetW( VmathVector4 *result, float _w )\n{\n    _vmathVfSetElement(result->vec128, _w, 3);\n}\n\nstatic inline float vmathV4GetW( const VmathVector4 *vec )\n{\n    return _vmathVfGetElement(vec->vec128, 3);\n}\n\nstatic inline void vmathV4SetElem( VmathVector4 *result, int idx, float value )\n{\n    _vmathVfSetElement(result->vec128, value, idx);\n}\n\nstatic inline float vmathV4GetElem( const VmathVector4 *vec, int idx )\n{\n    return _vmathVfGetElement(vec->vec128, idx);\n}\n\nstatic inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = vec_add( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = vec_sub( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar )\n{\n    result->vec128 = vec_madd( vec->vec128, _vmathVfSplatScalar(scalar), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar )\n{\n    result->vec128 = divf4( vec->vec128, _vmathVfSplatScalar(scalar) );\n}\n\nstatic inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = negatef4( vec->vec128 );\n}\n\nstatic inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = vec_madd( vec0->vec128, vec1->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = divf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = recipf4( vec->vec128 );\n}\n\nstatic inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = sqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = rsqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = fabsf4( vec->vec128 );\n}\n\nstatic inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = copysignf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV4MaxElem( const VmathVector4 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec_splat( vec->vec128, 1 ), vec->vec128 );\n    result = fmaxf4( vec_splat( vec->vec128, 2 ), result );\n    result = fmaxf4( vec_splat( vec->vec128, 3 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = fminf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV4MinElem( const VmathVector4 *vec )\n{\n    vec_float4 result;\n    result = fminf4( vec_splat( vec->vec128, 1 ), vec->vec128 );\n    result = fminf4( vec_splat( vec->vec128, 2 ), result );\n    result = fminf4( vec_splat( vec->vec128, 3 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV4Sum( const VmathVector4 *vec )\n{\n    vec_float4 result;\n    result = vec_add( vec_splat( vec->vec128, 1 ), vec->vec128 );\n    result = vec_add( vec_splat( vec->vec128, 2 ), result );\n    result = vec_add( vec_splat( vec->vec128, 3 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    vec_float4 result = _vmathVfDot4( vec0->vec128, vec1->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV4LengthSqr( const VmathVector4 *vec )\n{\n    vec_float4 result = _vmathVfDot4( vec->vec128, vec->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathV4Length( const VmathVector4 *vec )\n{\n    return sqrtf( vmathV4LengthSqr( vec ) );\n}\n\nstatic inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec )\n{\n    vec_float4 dot = _vmathVfDot4( vec->vec128, vec->vec128 );\n    result->vec128 = vec_madd( vec->vec128, rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 )\n{\n    unsigned int tmp;\n    tmp = (unsigned int)-(select1 > 0);\n    result->vec128 = vec_sel( vec0->vec128, vec1->vec128, _vmathVuiSplatScalar(tmp) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV4Print( const VmathVector4 *vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\nstatic inline void vmathV4Prints( const VmathVector4 *vec, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\nstatic inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = pnt->vec128;\n}\n\nstatic inline void vmathP3MakeFromElems( VmathPoint3 *result, float _x, float _y, float _z )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) {\n        result->vec128 = (vec_float4){_x, _y, _z, 0.0f};\n    } else {\n        float *pf = (float *)&result->vec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n    }\n}\n\nstatic inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar )\n{\n    result->vec128 = _vmathVfSplatScalar(scalar);\n}\n\nstatic inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathP3AddV3( result, pnt0, &tmpV3_1 );\n}\n\nstatic inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt )\n{\n    return pnt->vec128;\n}\n\nstatic inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = _VECTORMATH_MASK_0x000F;\n    dstVec = vec_sel(pnt->vec128, dstVec, mask);\n    *quad = dstVec;\n}\n\nstatic inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = vec_sld( xyzx, yzxy, 12 );\n    xyz2 = vec_sld( yzxy, zxyz, 8 );\n    xyz3 = vec_sld( zxyz, zxyz, 4 );\n    pnt0->vec128 = xyzx;\n    pnt1->vec128 = xyz1;\n    pnt2->vec128 = xyz2;\n    pnt3->vec128 = xyz3;\n}\n\nstatic inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = vec_perm( pnt0->vec128, pnt1->vec128, _VECTORMATH_PERM_XYZA );\n    yzxy = vec_perm( pnt1->vec128, pnt2->vec128, _VECTORMATH_PERM_YZAB );\n    zxyz = vec_perm( pnt2->vec128, pnt3->vec128, _VECTORMATH_PERM_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathP3StoreHalfFloats( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, const VmathPoint3 *pnt4, const VmathPoint3 *pnt5, const VmathPoint3 *pnt6, const VmathPoint3 *pnt7, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathP3StoreXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 );\n    vmathP3StoreXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathP3SetX( VmathPoint3 *result, float _x )\n{\n    _vmathVfSetElement(result->vec128, _x, 0);\n}\n\nstatic inline float vmathP3GetX( const VmathPoint3 *pnt )\n{\n    return _vmathVfGetElement(pnt->vec128, 0);\n}\n\nstatic inline void vmathP3SetY( VmathPoint3 *result, float _y )\n{\n    _vmathVfSetElement(result->vec128, _y, 1);\n}\n\nstatic inline float vmathP3GetY( const VmathPoint3 *pnt )\n{\n    return _vmathVfGetElement(pnt->vec128, 1);\n}\n\nstatic inline void vmathP3SetZ( VmathPoint3 *result, float _z )\n{\n    _vmathVfSetElement(result->vec128, _z, 2);\n}\n\nstatic inline float vmathP3GetZ( const VmathPoint3 *pnt )\n{\n    return _vmathVfGetElement(pnt->vec128, 2);\n}\n\nstatic inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value )\n{\n    _vmathVfSetElement(result->vec128, value, idx);\n}\n\nstatic inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx )\n{\n    return _vmathVfGetElement(pnt->vec128, idx);\n}\n\nstatic inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = vec_sub( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 )\n{\n    result->vec128 = vec_add( pnt->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 )\n{\n    result->vec128 = vec_sub( pnt->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = vec_madd( pnt0->vec128, pnt1->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = divf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = recipf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = sqrtf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = rsqrtf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = fabsf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = copysignf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = fmaxf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline float vmathP3MaxElem( const VmathPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( vec_splat( pnt->vec128, 1 ), pnt->vec128 );\n    result = fmaxf4( vec_splat( pnt->vec128, 2 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = fminf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline float vmathP3MinElem( const VmathPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fminf4( vec_splat( pnt->vec128, 1 ), pnt->vec128 );\n    result = fminf4( vec_splat( pnt->vec128, 2 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathP3Sum( const VmathPoint3 *pnt )\n{\n    vec_float4 result;\n    result = vec_add( vec_splat( pnt->vec128, 1 ), pnt->vec128 );\n    result = vec_add( vec_splat( pnt->vec128, 2 ), result );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal )\n{\n    VmathPoint3 tmpP3_0;\n    vmathP3MakeFromScalar( &tmpP3_0, scaleVal );\n    vmathP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec )\n{\n    VmathPoint3 tmpP3_0;\n    vmathP3MakeFromV3( &tmpP3_0, scaleVec );\n    vmathP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec )\n{\n    vec_float4 result = _vmathVfDot3( pnt->vec128, unitVec->vec128 );\n    return _vmathVfGetElement(result, 0);\n}\n\nstatic inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathV3Length( &tmpV3_0 );\n}\n\nstatic inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathV3Length( &tmpV3_0 );\n}\n\nstatic inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 )\n{\n    unsigned int tmp;\n    tmp = (unsigned int)-(select1 > 0);\n    result->vec128 = vec_sel( pnt0->vec128, pnt1->vec128, _vmathVuiSplatScalar(tmp) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathP3Print( const VmathPoint3 *pnt )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt->vec128;\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\nstatic inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt->vec128;\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vec_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_V_C_H\n#define _VECTORMATH_VEC_AOS_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for permutes words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A }\n#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }\n#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C }\n#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W }\n#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 }\n#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 }\n#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 }\n#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff }\n#define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathVector3 vmathV3MakeFromElems_V( float _x, float _y, float _z )\n{\n    VmathVector3 result;\n    vmathV3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt )\n{\n    VmathVector3 result;\n    vmathV3MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFromScalar_V( float scalar )\n{\n    VmathVector3 result;\n    vmathV3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 )\n{\n    VmathVector3 result;\n    vmathV3MakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeXAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeYAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeZAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 )\n{\n    VmathVector3 result;\n    vmathV3Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathV3Get128_V( VmathVector3 vec )\n{\n    return vmathV3Get128(&vec);\n}\n\nstatic inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad )\n{\n    vmathV3StoreXYZ(&vec, quad);\n}\n\nstatic inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads )\n{\n    vmathV3LoadXYZArray(vec0, vec1, vec2, vec3, threeQuads);\n}\n\nstatic inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads )\n{\n    vmathV3StoreXYZArray(&vec0, &vec1, &vec2, &vec3, threeQuads);\n}\n\nstatic inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads )\n{\n    vmathV3StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, &vec4, &vec5, &vec6, &vec7, threeQuads);\n}\n\nstatic inline void vmathV3SetX_V( VmathVector3 *result, float _x )\n{\n    vmathV3SetX(result, _x);\n}\n\nstatic inline float vmathV3GetX_V( VmathVector3 vec )\n{\n    return vmathV3GetX(&vec);\n}\n\nstatic inline void vmathV3SetY_V( VmathVector3 *result, float _y )\n{\n    vmathV3SetY(result, _y);\n}\n\nstatic inline float vmathV3GetY_V( VmathVector3 vec )\n{\n    return vmathV3GetY(&vec);\n}\n\nstatic inline void vmathV3SetZ_V( VmathVector3 *result, float _z )\n{\n    vmathV3SetZ(result, _z);\n}\n\nstatic inline float vmathV3GetZ_V( VmathVector3 vec )\n{\n    return vmathV3GetZ(&vec);\n}\n\nstatic inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value )\n{\n    vmathV3SetElem(result, idx, value);\n}\n\nstatic inline float vmathV3GetElem_V( VmathVector3 vec, int idx )\n{\n    return vmathV3GetElem(&vec, idx);\n}\n\nstatic inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathV3AddP3(&result, &vec, &pnt1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar )\n{\n    VmathVector3 result;\n    vmathV3ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar )\n{\n    VmathVector3 result;\n    vmathV3ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Neg_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV3MaxElem_V( VmathVector3 vec )\n{\n    return vmathV3MaxElem(&vec);\n}\n\nstatic inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV3MinElem_V( VmathVector3 vec )\n{\n    return vmathV3MinElem(&vec);\n}\n\nstatic inline float vmathV3Sum_V( VmathVector3 vec )\n{\n    return vmathV3Sum(&vec);\n}\n\nstatic inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    return vmathV3Dot(&vec0, &vec1);\n}\n\nstatic inline float vmathV3LengthSqr_V( VmathVector3 vec )\n{\n    return vmathV3LengthSqr(&vec);\n}\n\nstatic inline float vmathV3Length_V( VmathVector3 vec )\n{\n    return vmathV3Length(&vec);\n}\n\nstatic inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Cross(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 )\n{\n    VmathVector3 result;\n    vmathV3Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV3Print_V( VmathVector3 vec )\n{\n    vmathV3Print(&vec);\n}\n\nstatic inline void vmathV3Prints_V( VmathVector3 vec, const char *name )\n{\n    vmathV3Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathVector4 vmathV4MakeFromElems_V( float _x, float _y, float _z, float _w )\n{\n    VmathVector4 result;\n    vmathV4MakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float _w )\n{\n    VmathVector4 result;\n    vmathV4MakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec )\n{\n    VmathVector4 result;\n    vmathV4MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt )\n{\n    VmathVector4 result;\n    vmathV4MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat )\n{\n    VmathVector4 result;\n    vmathV4MakeFromQ(&result, &quat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromScalar_V( float scalar )\n{\n    VmathVector4 result;\n    vmathV4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 )\n{\n    VmathVector4 result;\n    vmathV4MakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeXAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeYAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeZAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeWAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeWAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 )\n{\n    VmathVector4 result;\n    vmathV4Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathV4Get128_V( VmathVector4 vec )\n{\n    return vmathV4Get128(&vec);\n}\n\nstatic inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads )\n{\n    vmathV4StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, twoQuads);\n}\n\nstatic inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec )\n{\n    vmathV4SetXYZ(result, &vec);\n}\n\nstatic inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec )\n{\n    VmathVector3 result;\n    vmathV4GetXYZ(&result, &vec);\n    return result;\n}\n\nstatic inline void vmathV4SetX_V( VmathVector4 *result, float _x )\n{\n    vmathV4SetX(result, _x);\n}\n\nstatic inline float vmathV4GetX_V( VmathVector4 vec )\n{\n    return vmathV4GetX(&vec);\n}\n\nstatic inline void vmathV4SetY_V( VmathVector4 *result, float _y )\n{\n    vmathV4SetY(result, _y);\n}\n\nstatic inline float vmathV4GetY_V( VmathVector4 vec )\n{\n    return vmathV4GetY(&vec);\n}\n\nstatic inline void vmathV4SetZ_V( VmathVector4 *result, float _z )\n{\n    vmathV4SetZ(result, _z);\n}\n\nstatic inline float vmathV4GetZ_V( VmathVector4 vec )\n{\n    return vmathV4GetZ(&vec);\n}\n\nstatic inline void vmathV4SetW_V( VmathVector4 *result, float _w )\n{\n    vmathV4SetW(result, _w);\n}\n\nstatic inline float vmathV4GetW_V( VmathVector4 vec )\n{\n    return vmathV4GetW(&vec);\n}\n\nstatic inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value )\n{\n    vmathV4SetElem(result, idx, value);\n}\n\nstatic inline float vmathV4GetElem_V( VmathVector4 vec, int idx )\n{\n    return vmathV4GetElem(&vec, idx);\n}\n\nstatic inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar )\n{\n    VmathVector4 result;\n    vmathV4ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar )\n{\n    VmathVector4 result;\n    vmathV4ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Neg_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV4MaxElem_V( VmathVector4 vec )\n{\n    return vmathV4MaxElem(&vec);\n}\n\nstatic inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV4MinElem_V( VmathVector4 vec )\n{\n    return vmathV4MinElem(&vec);\n}\n\nstatic inline float vmathV4Sum_V( VmathVector4 vec )\n{\n    return vmathV4Sum(&vec);\n}\n\nstatic inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    return vmathV4Dot(&vec0, &vec1);\n}\n\nstatic inline float vmathV4LengthSqr_V( VmathVector4 vec )\n{\n    return vmathV4LengthSqr(&vec);\n}\n\nstatic inline float vmathV4Length_V( VmathVector4 vec )\n{\n    return vmathV4Length(&vec);\n}\n\nstatic inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 )\n{\n    VmathVector4 result;\n    vmathV4Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV4Print_V( VmathVector4 vec )\n{\n    vmathV4Print(&vec);\n}\n\nstatic inline void vmathV4Prints_V( VmathVector4 vec, const char *name )\n{\n    vmathV4Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathPoint3 vmathP3MakeFromElems_V( float _x, float _y, float _z )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 )\n{\n    VmathPoint3 result;\n    vmathP3MakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3Lerp(&result, t, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt )\n{\n    return vmathP3Get128(&pnt);\n}\n\nstatic inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad )\n{\n    vmathP3StoreXYZ(&pnt, quad);\n}\n\nstatic inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads )\n{\n    vmathP3LoadXYZArray(pnt0, pnt1, pnt2, pnt3, threeQuads);\n}\n\nstatic inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads )\n{\n    vmathP3StoreXYZArray(&pnt0, &pnt1, &pnt2, &pnt3, threeQuads);\n}\n\nstatic inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads )\n{\n    vmathP3StoreHalfFloats(&pnt0, &pnt1, &pnt2, &pnt3, &pnt4, &pnt5, &pnt6, &pnt7, threeQuads);\n}\n\nstatic inline void vmathP3SetX_V( VmathPoint3 *result, float _x )\n{\n    vmathP3SetX(result, _x);\n}\n\nstatic inline float vmathP3GetX_V( VmathPoint3 pnt )\n{\n    return vmathP3GetX(&pnt);\n}\n\nstatic inline void vmathP3SetY_V( VmathPoint3 *result, float _y )\n{\n    vmathP3SetY(result, _y);\n}\n\nstatic inline float vmathP3GetY_V( VmathPoint3 pnt )\n{\n    return vmathP3GetY(&pnt);\n}\n\nstatic inline void vmathP3SetZ_V( VmathPoint3 *result, float _z )\n{\n    vmathP3SetZ(result, _z);\n}\n\nstatic inline float vmathP3GetZ_V( VmathPoint3 pnt )\n{\n    return vmathP3GetZ(&pnt);\n}\n\nstatic inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value )\n{\n    vmathP3SetElem(result, idx, value);\n}\n\nstatic inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx )\n{\n    return vmathP3GetElem(&pnt, idx);\n}\n\nstatic inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathVector3 result;\n    vmathP3Sub(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec1 )\n{\n    VmathPoint3 result;\n    vmathP3AddV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec1 )\n{\n    VmathPoint3 result;\n    vmathP3SubV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MulPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3DivPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3RecipPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3SqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3RsqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3AbsPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3CopySignPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MaxPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline float vmathP3MaxElem_V( VmathPoint3 pnt )\n{\n    return vmathP3MaxElem(&pnt);\n}\n\nstatic inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MinPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline float vmathP3MinElem_V( VmathPoint3 pnt )\n{\n    return vmathP3MinElem(&pnt);\n}\n\nstatic inline float vmathP3Sum_V( VmathPoint3 pnt )\n{\n    return vmathP3Sum(&pnt);\n}\n\nstatic inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal )\n{\n    VmathPoint3 result;\n    vmathP3Scale(&result, &pnt, scaleVal);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec )\n{\n    VmathPoint3 result;\n    vmathP3NonUniformScale(&result, &pnt, &scaleVec);\n    return result;\n}\n\nstatic inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec )\n{\n    return vmathP3Projection(&pnt, &unitVec);\n}\n\nstatic inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt )\n{\n    return vmathP3DistSqrFromOrigin(&pnt);\n}\n\nstatic inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt )\n{\n    return vmathP3DistFromOrigin(&pnt);\n}\n\nstatic inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    return vmathP3DistSqr(&pnt0, &pnt1);\n}\n\nstatic inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    return vmathP3Dist(&pnt0, &pnt1);\n}\n\nstatic inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 )\n{\n    VmathPoint3 result;\n    vmathP3Select(&result, &pnt0, &pnt1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathP3Print_V( VmathPoint3 pnt )\n{\n    vmathP3Print(&pnt);\n}\n\nstatic inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name )\n{\n    vmathP3Prints(&pnt, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vec_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_SOA_C_H\n#define _VECTORMATH_VEC_SOA_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for permutes, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_ZDWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_ZCXA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_XBZD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_WDYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_WCYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B })\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n}\n\nstatic inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n}\n\nstatic inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n}\n\nstatic inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec )\n{\n    vec_float4 vec128 = vec->vec128;\n    result->x = vec_splat( vec128, 0 );\n    result->y = vec_splat( vec128, 1 );\n    result->z = vec_splat( vec128, 2 );\n}\n\nstatic inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( vec0->vec128, vec2->vec128 );\n    tmp1 = vec_mergeh( vec1->vec128, vec3->vec128 );\n    tmp2 = vec_mergel( vec0->vec128, vec2->vec128 );\n    tmp3 = vec_mergel( vec1->vec128, vec3->vec128 );\n    result->x = vec_mergeh( tmp0, tmp1 );\n    result->y = vec_mergel( tmp0, tmp1 );\n    result->z = vec_mergeh( tmp2, tmp3 );\n}\n\nstatic inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result )\n{\n    vmathSoaV3MakeFromElems( result, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result )\n{\n    vmathSoaV3MakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result )\n{\n    vmathSoaV3MakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vmathSoaV3Sub( &tmpV3_0, vec1, vec0 );\n    vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathSoaV3Add( result, vec0, &tmpV3_1 );\n}\n\nstatic inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = vmathSoaV3Dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );\n    scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    vmathSoaV3ScalarMul( &tmpV3_0, unitVec0, scale0 );\n    vmathSoaV3ScalarMul( &tmpV3_1, unitVec1, scale1 );\n    vmathSoaV3Add( result, &tmpV3_0, &tmpV3_1 );\n}\n\nstatic inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 )\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = vec_mergeh( vec->x, vec->z );\n    tmp1 = vec_mergel( vec->x, vec->z );\n    vmathV3MakeFrom128( result0, vec_mergeh( tmp0, vec->y ) );\n    vmathV3MakeFrom128( result1, vec_perm( tmp0, vec->y, _VECTORMATH_PERM_ZBWX ) );\n    vmathV3MakeFrom128( result2, vec_perm( tmp1, vec->y, _VECTORMATH_PERM_XCYX ) );\n    vmathV3MakeFrom128( result3, vec_perm( tmp1, vec->y, _VECTORMATH_PERM_ZDWX ) );\n}\n\nstatic inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = vec_sld( yzxy, xyzx, 8 );\n    zxzx = vec_sld( xyzx, zxyz, 8 );\n    yzyz = vec_sld( zxyz, yzxy, 8 );\n    vmathSoaV3SetX( vec, vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) );\n    vmathSoaV3SetY( vec, vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) );\n    vmathSoaV3SetZ( vec, vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) );\n}\n\nstatic inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = vec_perm( vec->x, vec->y, _VECTORMATH_PERM_ZCXA );\n    zxzx = vec_perm( vec->z, vec->x, _VECTORMATH_PERM_XBZD );\n    yzyz = vec_perm( vec->y, vec->z, _VECTORMATH_PERM_WDYB );\n    xyzx = vec_sld( xyxy, zxzx, 8 );\n    yzxy = vec_sld( yzyz, xyxy, 8 );\n    zxyz = vec_sld( zxzx, yzyz, 8 );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathSoaV3StoreXYZArray( vec0, xyz0 );\n    vmathSoaV3StoreXYZArray( vec1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec )\n{\n    return vec->x;\n}\n\nstatic inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec )\n{\n    return vec->y;\n}\n\nstatic inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec )\n{\n    return vec->z;\n}\n\nstatic inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx )\n{\n    return *(&vec->x + idx);\n}\n\nstatic inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = vec_add( vec0->x, vec1->x );\n    result->y = vec_add( vec0->y, vec1->y );\n    result->z = vec_add( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = vec_sub( vec0->x, vec1->x );\n    result->y = vec_sub( vec0->y, vec1->y );\n    result->z = vec_sub( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = vec_add( vec->x, pnt1->x );\n    result->y = vec_add( vec->y, pnt1->y );\n    result->z = vec_add( vec->z, pnt1->z );\n}\n\nstatic inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar )\n{\n    result->x = vec_madd( vec->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( vec->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( vec->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar )\n{\n    result->x = divf4( vec->x, scalar );\n    result->y = divf4( vec->y, scalar );\n    result->z = divf4( vec->z, scalar );\n}\n\nstatic inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = negatef4( vec->x );\n    result->y = negatef4( vec->y );\n    result->z = negatef4( vec->z );\n}\n\nstatic inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = divf4( vec0->x, vec1->x );\n    result->y = divf4( vec0->y, vec1->y );\n    result->z = divf4( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->x );\n    result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->y );\n    result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->z );\n}\n\nstatic inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = sqrtf4( vec->x );\n    result->y = sqrtf4( vec->y );\n    result->z = sqrtf4( vec->z );\n}\n\nstatic inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->x ) );\n    result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->y ) );\n    result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->z ) );\n}\n\nstatic inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = fabsf4( vec->x );\n    result->y = fabsf4( vec->y );\n    result->z = fabsf4( vec->z );\n}\n\nstatic inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = copysignf4( vec0->x, vec1->x );\n    result->y = copysignf4( vec0->y, vec1->y );\n    result->z = copysignf4( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = fmaxf4( vec0->x, vec1->x );\n    result->y = fmaxf4( vec0->y, vec1->y );\n    result->z = fmaxf4( vec0->z, vec1->z );\n}\n\nstatic inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec->x, vec->y );\n    result = fmaxf4( vec->z, result );\n    return result;\n}\n\nstatic inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = fminf4( vec0->x, vec1->x );\n    result->y = fminf4( vec0->y, vec1->y );\n    result->z = fminf4( vec0->z, vec1->z );\n}\n\nstatic inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = fminf4( vec->x, vec->y );\n    result = fminf4( vec->z, result );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = vec_add( vec->x, vec->y );\n    result = vec_add( result, vec->z );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = vec_madd( vec->x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec->y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec->z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec )\n{\n    return sqrtf4( vmathSoaV3LengthSqr( vec ) );\n}\n\nstatic inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = vmathSoaV3LengthSqr( vec );\n    lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );\n    result->x = vec_madd( vec->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( vec->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( vec->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = vec_sub( vec_madd( vec0->y, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0->z, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_sub( vec_madd( vec0->z, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0->x, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_sub( vec_madd( vec0->x, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0->y, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 )\n{\n    result->x = vec_sel( vec0->x, vec1->x, select1 );\n    result->y = vec_sel( vec0->y, vec1->y, select1 );\n    result->z = vec_sel( vec0->z, vec1->z, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV3Print( const VmathSoaVector3 *vec )\n{\n    VmathVector3 vec0, vec1, vec2, vec3;\n    vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV3Print( &vec3 );\n}\n\nstatic inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name )\n{\n    VmathVector3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV3Print( &vec3 );\n}\n\n#endif\n\nstatic inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = vec->w;\n}\n\nstatic inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n    result->w = _w;\n}\n\nstatic inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 _w )\n{\n    vmathSoaV4SetXYZ( result, xyz );\n    vmathSoaV4SetW( result, _w );\n}\n\nstatic inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n}\n\nstatic inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n    result->w = ((vec_float4){1.0f,1.0f,1.0f,1.0f});\n}\n\nstatic inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat )\n{\n    result->x = quat->x;\n    result->y = quat->y;\n    result->z = quat->z;\n    result->w = quat->w;\n}\n\nstatic inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n    result->w = scalar;\n}\n\nstatic inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec )\n{\n    vec_float4 vec128 = vec->vec128;\n    result->x = vec_splat( vec128, 0 );\n    result->y = vec_splat( vec128, 1 );\n    result->z = vec_splat( vec128, 2 );\n    result->w = vec_splat( vec128, 3 );\n}\n\nstatic inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( vec0->vec128, vec2->vec128 );\n    tmp1 = vec_mergeh( vec1->vec128, vec3->vec128 );\n    tmp2 = vec_mergel( vec0->vec128, vec2->vec128 );\n    tmp3 = vec_mergel( vec1->vec128, vec3->vec128 );\n    result->x = vec_mergeh( tmp0, tmp1 );\n    result->y = vec_mergel( tmp0, tmp1 );\n    result->z = vec_mergeh( tmp2, tmp3 );\n    result->w = vec_mergel( tmp2, tmp3 );\n}\n\nstatic inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\nstatic inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    VmathSoaVector4 tmpV4_0, tmpV4_1;\n    vmathSoaV4Sub( &tmpV4_0, vec1, vec0 );\n    vmathSoaV4ScalarMul( &tmpV4_1, &tmpV4_0, t );\n    vmathSoaV4Add( result, vec0, &tmpV4_1 );\n}\n\nstatic inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 )\n{\n    VmathSoaVector4 tmpV4_0, tmpV4_1;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = vmathSoaV4Dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );\n    scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    vmathSoaV4ScalarMul( &tmpV4_0, unitVec0, scale0 );\n    vmathSoaV4ScalarMul( &tmpV4_1, unitVec1, scale1 );\n    vmathSoaV4Add( result, &tmpV4_0, &tmpV4_1 );\n}\n\nstatic inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( vec->x, vec->z );\n    tmp1 = vec_mergeh( vec->y, vec->w );\n    tmp2 = vec_mergel( vec->x, vec->z );\n    tmp3 = vec_mergel( vec->y, vec->w );\n    vmathV4MakeFrom128( result0, vec_mergeh( tmp0, tmp1 ) );\n    vmathV4MakeFrom128( result1, vec_mergel( tmp0, tmp1 ) );\n    vmathV4MakeFrom128( result2, vec_mergeh( tmp2, tmp3 ) );\n    vmathV4MakeFrom128( result3, vec_mergel( tmp2, tmp3 ) );\n}\n\nstatic inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads )\n{\n    VmathVector4 v0, v1, v2, v3;\n    vmathSoaV4Get4Aos( vec, &v0, &v1, &v2, &v3 );\n    twoQuads[0] = _vmath2VfToHalfFloats(v0.vec128, v1.vec128);\n    twoQuads[1] = _vmath2VfToHalfFloats(v2.vec128, v3.vec128);\n}\n\nstatic inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec )\n{\n    vmathSoaV3MakeFromElems( result, vec->x, vec->y, vec->z );\n}\n\nstatic inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec )\n{\n    return vec->x;\n}\n\nstatic inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec )\n{\n    return vec->y;\n}\n\nstatic inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec )\n{\n    return vec->z;\n}\n\nstatic inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 _w )\n{\n    result->w = _w;\n}\n\nstatic inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec )\n{\n    return vec->w;\n}\n\nstatic inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx )\n{\n    return *(&vec->x + idx);\n}\n\nstatic inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = vec_add( vec0->x, vec1->x );\n    result->y = vec_add( vec0->y, vec1->y );\n    result->z = vec_add( vec0->z, vec1->z );\n    result->w = vec_add( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = vec_sub( vec0->x, vec1->x );\n    result->y = vec_sub( vec0->y, vec1->y );\n    result->z = vec_sub( vec0->z, vec1->z );\n    result->w = vec_sub( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar )\n{\n    result->x = vec_madd( vec->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( vec->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( vec->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->w = vec_madd( vec->w, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar )\n{\n    result->x = divf4( vec->x, scalar );\n    result->y = divf4( vec->y, scalar );\n    result->z = divf4( vec->z, scalar );\n    result->w = divf4( vec->w, scalar );\n}\n\nstatic inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = negatef4( vec->x );\n    result->y = negatef4( vec->y );\n    result->z = negatef4( vec->z );\n    result->w = negatef4( vec->w );\n}\n\nstatic inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->w = vec_madd( vec0->w, vec1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = divf4( vec0->x, vec1->x );\n    result->y = divf4( vec0->y, vec1->y );\n    result->z = divf4( vec0->z, vec1->z );\n    result->w = divf4( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->x );\n    result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->y );\n    result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->z );\n    result->w = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->w );\n}\n\nstatic inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = sqrtf4( vec->x );\n    result->y = sqrtf4( vec->y );\n    result->z = sqrtf4( vec->z );\n    result->w = sqrtf4( vec->w );\n}\n\nstatic inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->x ) );\n    result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->y ) );\n    result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->z ) );\n    result->w = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->w ) );\n}\n\nstatic inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = fabsf4( vec->x );\n    result->y = fabsf4( vec->y );\n    result->z = fabsf4( vec->z );\n    result->w = fabsf4( vec->w );\n}\n\nstatic inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = copysignf4( vec0->x, vec1->x );\n    result->y = copysignf4( vec0->y, vec1->y );\n    result->z = copysignf4( vec0->z, vec1->z );\n    result->w = copysignf4( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = fmaxf4( vec0->x, vec1->x );\n    result->y = fmaxf4( vec0->y, vec1->y );\n    result->z = fmaxf4( vec0->z, vec1->z );\n    result->w = fmaxf4( vec0->w, vec1->w );\n}\n\nstatic inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec->x, vec->y );\n    result = fmaxf4( vec->z, result );\n    result = fmaxf4( vec->w, result );\n    return result;\n}\n\nstatic inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = fminf4( vec0->x, vec1->x );\n    result->y = fminf4( vec0->y, vec1->y );\n    result->z = fminf4( vec0->z, vec1->z );\n    result->w = fminf4( vec0->w, vec1->w );\n}\n\nstatic inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = fminf4( vec->x, vec->y );\n    result = fminf4( vec->z, result );\n    result = fminf4( vec->w, result );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = vec_add( vec->x, vec->y );\n    result = vec_add( result, vec->z );\n    result = vec_add( result, vec->w );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec0->w, vec1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = vec_madd( vec->x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec->y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec->z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec->w, vec->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec )\n{\n    return sqrtf4( vmathSoaV4LengthSqr( vec ) );\n}\n\nstatic inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = vmathSoaV4LengthSqr( vec );\n    lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );\n    result->x = vec_madd( vec->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( vec->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( vec->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->w = vec_madd( vec->w, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 )\n{\n    result->x = vec_sel( vec0->x, vec1->x, select1 );\n    result->y = vec_sel( vec0->y, vec1->y, select1 );\n    result->z = vec_sel( vec0->z, vec1->z, select1 );\n    result->w = vec_sel( vec0->w, vec1->w, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV4Print( const VmathSoaVector4 *vec )\n{\n    VmathVector4 vec0, vec1, vec2, vec3;\n    vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV4Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV4Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV4Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV4Print( &vec3 );\n}\n\nstatic inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name )\n{\n    VmathVector4 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV4Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV4Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV4Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV4Print( &vec3 );\n}\n\n#endif\n\nstatic inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n}\n\nstatic inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n}\n\nstatic inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n}\n\nstatic inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt )\n{\n    vec_float4 vec128 = pnt->vec128;\n    result->x = vec_splat( vec128, 0 );\n    result->y = vec_splat( vec128, 1 );\n    result->z = vec_splat( vec128, 2 );\n}\n\nstatic inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( pnt0->vec128, pnt2->vec128 );\n    tmp1 = vec_mergeh( pnt1->vec128, pnt3->vec128 );\n    tmp2 = vec_mergel( pnt0->vec128, pnt2->vec128 );\n    tmp3 = vec_mergel( pnt1->vec128, pnt3->vec128 );\n    result->x = vec_mergeh( tmp0, tmp1 );\n    result->y = vec_mergel( tmp0, tmp1 );\n    result->z = vec_mergeh( tmp2, tmp3 );\n}\n\nstatic inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 );\n    vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathSoaP3AddV3( result, pnt0, &tmpV3_1 );\n}\n\nstatic inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 )\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = vec_mergeh( pnt->x, pnt->z );\n    tmp1 = vec_mergel( pnt->x, pnt->z );\n    vmathP3MakeFrom128( result0, vec_mergeh( tmp0, pnt->y ) );\n    vmathP3MakeFrom128( result1, vec_perm( tmp0, pnt->y, _VECTORMATH_PERM_ZBWX ) );\n    vmathP3MakeFrom128( result2, vec_perm( tmp1, pnt->y, _VECTORMATH_PERM_XCYX ) );\n    vmathP3MakeFrom128( result3, vec_perm( tmp1, pnt->y, _VECTORMATH_PERM_ZDWX ) );\n}\n\nstatic inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *vec, const vec_float4 *threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = vec_sld( yzxy, xyzx, 8 );\n    zxzx = vec_sld( xyzx, zxyz, 8 );\n    yzyz = vec_sld( zxyz, yzxy, 8 );\n    vmathSoaP3SetX( vec, vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) );\n    vmathSoaP3SetY( vec, vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) );\n    vmathSoaP3SetZ( vec, vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) );\n}\n\nstatic inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *vec, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = vec_perm( vec->x, vec->y, _VECTORMATH_PERM_ZCXA );\n    zxzx = vec_perm( vec->z, vec->x, _VECTORMATH_PERM_XBZD );\n    yzyz = vec_perm( vec->y, vec->z, _VECTORMATH_PERM_WDYB );\n    xyzx = vec_sld( xyxy, zxzx, 8 );\n    yzxy = vec_sld( yzyz, xyxy, 8 );\n    zxyz = vec_sld( zxzx, yzyz, 8 );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathSoaP3StoreXYZArray( pnt0, xyz0 );\n    vmathSoaP3StoreXYZArray( pnt1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt )\n{\n    return pnt->x;\n}\n\nstatic inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt )\n{\n    return pnt->y;\n}\n\nstatic inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt )\n{\n    return pnt->z;\n}\n\nstatic inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx )\n{\n    return *(&pnt->x + idx);\n}\n\nstatic inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = vec_sub( pnt0->x, pnt1->x );\n    result->y = vec_sub( pnt0->y, pnt1->y );\n    result->z = vec_sub( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 )\n{\n    result->x = vec_add( pnt->x, vec1->x );\n    result->y = vec_add( pnt->y, vec1->y );\n    result->z = vec_add( pnt->z, vec1->z );\n}\n\nstatic inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 )\n{\n    result->x = vec_sub( pnt->x, vec1->x );\n    result->y = vec_sub( pnt->y, vec1->y );\n    result->z = vec_sub( pnt->z, vec1->z );\n}\n\nstatic inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = vec_madd( pnt0->x, pnt1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->y = vec_madd( pnt0->y, pnt1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result->z = vec_madd( pnt0->z, pnt1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\nstatic inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = divf4( pnt0->x, pnt1->x );\n    result->y = divf4( pnt0->y, pnt1->y );\n    result->z = divf4( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt->x );\n    result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt->y );\n    result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt->z );\n}\n\nstatic inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = sqrtf4( pnt->x );\n    result->y = sqrtf4( pnt->y );\n    result->z = sqrtf4( pnt->z );\n}\n\nstatic inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt->x ) );\n    result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt->y ) );\n    result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt->z ) );\n}\n\nstatic inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = fabsf4( pnt->x );\n    result->y = fabsf4( pnt->y );\n    result->z = fabsf4( pnt->z );\n}\n\nstatic inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = copysignf4( pnt0->x, pnt1->x );\n    result->y = copysignf4( pnt0->y, pnt1->y );\n    result->z = copysignf4( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = fmaxf4( pnt0->x, pnt1->x );\n    result->y = fmaxf4( pnt0->y, pnt1->y );\n    result->z = fmaxf4( pnt0->z, pnt1->z );\n}\n\nstatic inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( pnt->x, pnt->y );\n    result = fmaxf4( pnt->z, result );\n    return result;\n}\n\nstatic inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = fminf4( pnt0->x, pnt1->x );\n    result->y = fminf4( pnt0->y, pnt1->y );\n    result->z = fminf4( pnt0->z, pnt1->z );\n}\n\nstatic inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fminf4( pnt->x, pnt->y );\n    result = fminf4( pnt->z, result );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt )\n{\n    vec_float4 result;\n    result = vec_add( pnt->x, pnt->y );\n    result = vec_add( result, pnt->z );\n    return result;\n}\n\nstatic inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal )\n{\n    VmathSoaPoint3 tmpP3_0;\n    vmathSoaP3MakeFromScalar( &tmpP3_0, scaleVal );\n    vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec )\n{\n    VmathSoaPoint3 tmpP3_0;\n    vmathSoaP3MakeFromV3( &tmpP3_0, scaleVec );\n    vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec )\n{\n    vec_float4 result;\n    result = vec_madd( pnt->x, unitVec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( pnt->y, unitVec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( pnt->z, unitVec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathSoaV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathSoaV3Length( &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathSoaV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathSoaV3Length( &tmpV3_0 );\n}\n\nstatic inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 )\n{\n    result->x = vec_sel( pnt0->x, pnt1->x, select1 );\n    result->y = vec_sel( pnt0->y, pnt1->y, select1 );\n    result->z = vec_sel( pnt0->z, pnt1->z, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt )\n{\n    VmathPoint3 vec0, vec1, vec2, vec3;\n    vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathP3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathP3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathP3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathP3Print( &vec3 );\n}\n\nstatic inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name )\n{\n    VmathPoint3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathP3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathP3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathP3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathP3Print( &vec3 );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vec_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_SOA_V_C_H\n#define _VECTORMATH_VEC_SOA_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for permutes, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_ZDWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_ZCXA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_XBZD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_WDYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_WCYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B })\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromAos(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 )\n{\n    vmathSoaV3Get4Aos(&vec, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads )\n{\n    vmathSoaV3LoadXYZArray(vec, threeQuads);\n}\n\nstatic inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads )\n{\n    vmathSoaV3StoreXYZArray(&vec, threeQuads);\n}\n\nstatic inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads )\n{\n    vmathSoaV3StoreHalfFloats(&vec0, &vec1, threeQuads);\n}\n\nstatic inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 _x )\n{\n    vmathSoaV3SetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3GetX(&vec);\n}\n\nstatic inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 _y )\n{\n    vmathSoaV3SetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3GetY(&vec);\n}\n\nstatic inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 _z )\n{\n    vmathSoaV3SetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3GetZ(&vec);\n}\n\nstatic inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value )\n{\n    vmathSoaV3SetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx )\n{\n    return vmathSoaV3GetElem(&vec, idx);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaV3AddP3(&result, &vec, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3MaxElem(&vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3MinElem(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3Sum(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    return vmathSoaV3Dot(&vec0, &vec1);\n}\n\nstatic inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3LengthSqr(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3Length(&vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Cross(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV3Print_V( VmathSoaVector3 vec )\n{\n    vmathSoaV3Print(&vec);\n}\n\nstatic inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name )\n{\n    vmathSoaV3Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromQ(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromAos(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeWAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 )\n{\n    vmathSoaV4Get4Aos(&vec, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads )\n{\n    vmathSoaV4StoreHalfFloats(&vec, twoQuads);\n}\n\nstatic inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec )\n{\n    vmathSoaV4SetXYZ(result, &vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV4GetXYZ(&result, &vec);\n    return result;\n}\n\nstatic inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 _x )\n{\n    vmathSoaV4SetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetX(&vec);\n}\n\nstatic inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 _y )\n{\n    vmathSoaV4SetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetY(&vec);\n}\n\nstatic inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 _z )\n{\n    vmathSoaV4SetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetZ(&vec);\n}\n\nstatic inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 _w )\n{\n    vmathSoaV4SetW(result, _w);\n}\n\nstatic inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetW(&vec);\n}\n\nstatic inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value )\n{\n    vmathSoaV4SetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx )\n{\n    return vmathSoaV4GetElem(&vec, idx);\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4MaxElem(&vec);\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4MinElem(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4Sum(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    return vmathSoaV4Dot(&vec0, &vec1);\n}\n\nstatic inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4LengthSqr(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4Length(&vec);\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV4Print_V( VmathSoaVector4 vec )\n{\n    vmathSoaV4Print(&vec);\n}\n\nstatic inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name )\n{\n    vmathSoaV4Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromAos(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFrom4Aos(&result, &pnt0, &pnt1, &pnt2, &pnt3);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3Lerp(&result, t, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 )\n{\n    vmathSoaP3Get4Aos(&pnt, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *vec, const vec_float4 *threeQuads )\n{\n    vmathSoaP3LoadXYZArray(vec, threeQuads);\n}\n\nstatic inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 vec, vec_float4 *threeQuads )\n{\n    vmathSoaP3StoreXYZArray(&vec, threeQuads);\n}\n\nstatic inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads )\n{\n    vmathSoaP3StoreHalfFloats(&pnt0, &pnt1, threeQuads);\n}\n\nstatic inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 _x )\n{\n    vmathSoaP3SetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3GetX(&pnt);\n}\n\nstatic inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 _y )\n{\n    vmathSoaP3SetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3GetY(&pnt);\n}\n\nstatic inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 _z )\n{\n    vmathSoaP3SetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3GetZ(&pnt);\n}\n\nstatic inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value )\n{\n    vmathSoaP3SetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx )\n{\n    return vmathSoaP3GetElem(&pnt, idx);\n}\n\nstatic inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaP3Sub(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3AddV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3SubV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MulPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3DivPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3RecipPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3SqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3RsqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3AbsPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3CopySignPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MaxPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3MaxElem(&pnt);\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MinPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3MinElem(&pnt);\n}\n\nstatic inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3Sum(&pnt);\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3Scale(&result, &pnt, scaleVal);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3NonUniformScale(&result, &pnt, &scaleVec);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec )\n{\n    return vmathSoaP3Projection(&pnt, &unitVec);\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3DistSqrFromOrigin(&pnt);\n}\n\nstatic inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3DistFromOrigin(&pnt);\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    return vmathSoaP3DistSqr(&pnt0, &pnt1);\n}\n\nstatic inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    return vmathSoaP3Dist(&pnt0, &pnt1);\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3Select(&result, &pnt0, &pnt1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt )\n{\n    vmathSoaP3Print(&pnt);\n}\n\nstatic inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name )\n{\n    vmathSoaP3Prints(&pnt, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vec_types.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* Single token vector data types for the PowerPC SIMD/Vector Multi-media \n   eXtension */\n\n#ifndef _VEC_TYPES_H_\n#define _VEC_TYPES_H_\t1\n\n#define qword\t\tvector unsigned char\n\n#define vec_uchar16\tvector unsigned char\n#define vec_char16\tvector signed char\n#define vec_bchar16\tvector bool char\n\n#define vec_ushort8\tvector unsigned short\n#define vec_short8\tvector signed short\n#define vec_bshort8\tvector bool short\n\n#define vec_pixel8\tvector pixel\n\n#define vec_uint4\tvector unsigned int\n#define vec_int4\tvector signed int\n#define vec_bint4\tvector bool int\n\n#define vec_float4\tvector float\n\n#define vec_ullong2\tvector bool char\n#define vec_llong2\tvector bool short\n\n#define vec_double2\tvector bool int\n\n#endif /* _VEC_TYPES_H_ */\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_PPU_H\n#define _VECTORMATH_AOS_C_PPU_H\n\n#include <math.h>\n#include <altivec.h>\n#include <simdmath.h>\n#include \"vec_types.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_AOS_C_TYPES_H\n#define _VECTORMATH_AOS_C_TYPES_H\n\n/* A 3-D vector in array-of-structures format\n */\ntypedef struct _VmathVector3\n{\n    vec_float4 vec128;\n} VmathVector3;\n\n/* A 4-D vector in array-of-structures format\n */\ntypedef struct _VmathVector4\n{\n    vec_float4 vec128;\n} VmathVector4;\n\n/* A 3-D point in array-of-structures format\n */\ntypedef struct _VmathPoint3\n{\n    vec_float4 vec128;\n} VmathPoint3;\n\n/* A quaternion in array-of-structures format\n */\ntypedef struct _VmathQuat\n{\n    vec_float4 vec128;\n} VmathQuat;\n\n/* A 3x3 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n} VmathMatrix3;\n\n/* A 4x4 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix4\n{\n    VmathVector4 col0;\n    VmathVector4 col1;\n    VmathVector4 col2;\n    VmathVector4 col3;\n} VmathMatrix4;\n\n/* A 3x4 transformation matrix in array-of-structures format\n */\ntypedef struct _VmathTransform3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n    VmathVector3 col3;\n} VmathTransform3;\n\n#endif\n\n/*\n * Copy a 3-D vector\n */\nstatic inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline void vmathV3MakeFromElems( VmathVector3 *result, float x, float y, float z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar );\n\n/*\n * Set vector float data in a 3-D vector\n */\nstatic inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D vector\n */\nstatic inline vec_float4 vmathV3Get128( const VmathVector3 *vec );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathV3SetX( VmathVector3 *result, float x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathV3SetY( VmathVector3 *result, float y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathV3SetZ( VmathVector3 *result, float z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline float vmathV3GetX( const VmathVector3 *vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline float vmathV3GetY( const VmathVector3 *vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline float vmathV3GetZ( const VmathVector3 *vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathV3SetElem( VmathVector3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline float vmathV3GetElem( const VmathVector3 *vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathV3MakeXAxis( VmathVector3 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathV3MakeYAxis( VmathVector3 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathV3MakeZAxis( VmathVector3 *result );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline float vmathV3MaxElem( const VmathVector3 *vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline float vmathV3MinElem( const VmathVector3 *vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline float vmathV3Sum( const VmathVector3 *vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline float vmathV3LengthSqr( const VmathVector3 *vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline float vmathV3Length( const VmathVector3 *vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n * NOTE: \n * Slower than column post-multiply.\n */\nstatic inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D vector in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D vectors in three quadwords\n */\nstatic inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D vectors as half-floats\n */\nstatic inline void vmathV3StoreHalfFloats( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, const VmathVector3 *vec4, const VmathVector3 *vec5, const VmathVector3 *vec6, const VmathVector3 *vec7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Print( const VmathVector3 *vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Prints( const VmathVector3 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 4-D vector\n */\nstatic inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline void vmathV4MakeFromElems( VmathVector4 *result, float x, float y, float z, float w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar );\n\n/*\n * Set vector float data in a 4-D vector\n */\nstatic inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a 4-D vector\n */\nstatic inline vec_float4 vmathV4Get128( const VmathVector4 *vec );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathV4SetX( VmathVector4 *result, float x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathV4SetY( VmathVector4 *result, float y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathV4SetZ( VmathVector4 *result, float z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathV4SetW( VmathVector4 *result, float w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline float vmathV4GetX( const VmathVector4 *vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline float vmathV4GetY( const VmathVector4 *vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline float vmathV4GetZ( const VmathVector4 *vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline float vmathV4GetW( const VmathVector4 *vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathV4SetElem( VmathVector4 *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline float vmathV4GetElem( const VmathVector4 *vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathV4MakeXAxis( VmathVector4 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathV4MakeYAxis( VmathVector4 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathV4MakeZAxis( VmathVector4 *result );\n\n/*\n * Construct w axis\n */\nstatic inline void vmathV4MakeWAxis( VmathVector4 *result );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline float vmathV4MaxElem( const VmathVector4 *vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline float vmathV4MinElem( const VmathVector4 *vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline float vmathV4Sum( const VmathVector4 *vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline float vmathV4LengthSqr( const VmathVector4 *vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline float vmathV4Length( const VmathVector4 *vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 );\n\n/*\n * Store four 4-D vectors as half-floats\n */\nstatic inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Print( const VmathVector4 *vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Prints( const VmathVector4 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 3-D point\n */\nstatic inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline void vmathP3MakeFromElems( VmathPoint3 *result, float x, float y, float z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar );\n\n/*\n * Set vector float data in a 3-D point\n */\nstatic inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D point\n */\nstatic inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathP3SetX( VmathPoint3 *result, float x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathP3SetY( VmathPoint3 *result, float y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathP3SetZ( VmathPoint3 *result, float z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline float vmathP3GetX( const VmathPoint3 *pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline float vmathP3GetY( const VmathPoint3 *pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline float vmathP3GetZ( const VmathPoint3 *pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline float vmathP3MaxElem( const VmathPoint3 *pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline float vmathP3MinElem( const VmathPoint3 *pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline float vmathP3Sum( const VmathPoint3 *pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D point in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D points in three quadwords\n */\nstatic inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D points as half-floats\n */\nstatic inline void vmathP3StoreHalfFloats( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, const VmathPoint3 *pnt4, const VmathPoint3 *pnt5, const VmathPoint3 *pnt6, const VmathPoint3 *pnt7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Print( const VmathPoint3 *pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name );\n\n#endif\n\n/*\n * Copy a quaternion\n */\nstatic inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline void vmathQMakeFromElems( VmathQuat *result, float x, float y, float z, float w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline void vmathQMakeFromScalar( VmathQuat *result, float scalar );\n\n/*\n * Set vector float data in a quaternion\n */\nstatic inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a quaternion\n */\nstatic inline vec_float4 vmathQGet128( const VmathQuat *quat );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathQSetX( VmathQuat *result, float x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathQSetY( VmathQuat *result, float y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathQSetZ( VmathQuat *result, float z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathQSetW( VmathQuat *result, float w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline float vmathQGetX( const VmathQuat *quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline float vmathQGetY( const VmathQuat *quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline float vmathQGetZ( const VmathQuat *quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline float vmathQGetW( const VmathQuat *quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathQSetElem( VmathQuat *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline float vmathQGetElem( const VmathQuat *quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline void vmathQMakeIdentity( VmathQuat *result );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline void vmathQMakeRotationX( VmathQuat *result, float radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline void vmathQMakeRotationY( VmathQuat *result, float radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline void vmathQMakeRotationZ( VmathQuat *result, float radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline void vmathQConj( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline void vmathQRotate( VmathVector3 *result, const VmathQuat *unitQuat, const VmathVector3 *vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline float vmathQNorm( const VmathQuat *quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline float vmathQLength( const VmathQuat *quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrint( const VmathQuat *quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrints( const VmathQuat *quat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x3 matrix\n */\nstatic inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline void vmathM3MakeIdentity( VmathMatrix3 *result );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline float vmathM3Determinant( const VmathMatrix3 *mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Print( const VmathMatrix3 *mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 4x4 matrix\n */\nstatic inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *col0, const VmathVector4 *col1, const VmathVector4 *col2, const VmathVector4 *col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline void vmathM4MakeIdentity( VmathMatrix4 *result );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline float vmathM4Determinant( const VmathMatrix4 *mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Print( const VmathMatrix4 *mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x4 transformation matrix\n */\nstatic inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2, const VmathVector3 *col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline void vmathT3MakeIdentity( VmathTransform3 *result );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Print( const VmathTransform3 *tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vectormath_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_V_PPU_H\n#define _VECTORMATH_AOS_C_V_PPU_H\n\n#include <math.h>\n#include <altivec.h>\n#include \"vec_types.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_AOS_C_TYPES_H\n#define _VECTORMATH_AOS_C_TYPES_H\n\n/* A 3-D vector in array-of-structures format\n */\ntypedef struct _VmathVector3\n{\n    vec_float4 vec128;\n} VmathVector3;\n\n/* A 4-D vector in array-of-structures format\n */\ntypedef struct _VmathVector4\n{\n    vec_float4 vec128;\n} VmathVector4;\n\n/* A 3-D point in array-of-structures format\n */\ntypedef struct _VmathPoint3\n{\n    vec_float4 vec128;\n} VmathPoint3;\n\n/* A quaternion in array-of-structures format\n */\ntypedef struct _VmathQuat\n{\n    vec_float4 vec128;\n} VmathQuat;\n\n/* A 3x3 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n} VmathMatrix3;\n\n/* A 4x4 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix4\n{\n    VmathVector4 col0;\n    VmathVector4 col1;\n    VmathVector4 col2;\n    VmathVector4 col3;\n} VmathMatrix4;\n\n/* A 3x4 transformation matrix in array-of-structures format\n */\ntypedef struct _VmathTransform3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n    VmathVector3 col3;\n} VmathTransform3;\n\n#endif\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline VmathVector3 vmathV3MakeFromElems_V( float x, float y, float z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline VmathVector3 vmathV3MakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a 3-D vector\n */\nstatic inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D vector\n */\nstatic inline vec_float4 vmathV3Get128_V( VmathVector3 vec );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathV3SetX_V( VmathVector3 *result, float x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathV3SetY_V( VmathVector3 *result, float y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathV3SetZ_V( VmathVector3 *result, float z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline float vmathV3GetX_V( VmathVector3 vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline float vmathV3GetY_V( VmathVector3 vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline float vmathV3GetZ_V( VmathVector3 vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline float vmathV3GetElem_V( VmathVector3 vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline VmathVector3 vmathV3Neg_V( VmathVector3 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathVector3 vmathV3MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathVector3 vmathV3MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathVector3 vmathV3MakeZAxis_V( );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline float vmathV3MaxElem_V( VmathVector3 vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline float vmathV3MinElem_V( VmathVector3 vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline float vmathV3Sum_V( VmathVector3 vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline float vmathV3LengthSqr_V( VmathVector3 vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline float vmathV3Length_V( VmathVector3 vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline VmathMatrix3 vmathV3Outer_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n * NOTE: \n * Slower than column post-multiply.\n */\nstatic inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D vector in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D vectors in three quadwords\n */\nstatic inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D vectors as half-floats\n */\nstatic inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Print_V( VmathVector3 vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Prints_V( VmathVector3 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline VmathVector4 vmathV4MakeFromElems_V( float x, float y, float z, float w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline VmathVector4 vmathV4MakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a 4-D vector\n */\nstatic inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a 4-D vector\n */\nstatic inline vec_float4 vmathV4Get128_V( VmathVector4 vec );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathV4SetX_V( VmathVector4 *result, float x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathV4SetY_V( VmathVector4 *result, float y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathV4SetZ_V( VmathVector4 *result, float z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathV4SetW_V( VmathVector4 *result, float w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline float vmathV4GetX_V( VmathVector4 vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline float vmathV4GetY_V( VmathVector4 vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline float vmathV4GetZ_V( VmathVector4 vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline float vmathV4GetW_V( VmathVector4 vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline float vmathV4GetElem_V( VmathVector4 vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline VmathVector4 vmathV4Neg_V( VmathVector4 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathVector4 vmathV4MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathVector4 vmathV4MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathVector4 vmathV4MakeZAxis_V( );\n\n/*\n * Construct w axis\n */\nstatic inline VmathVector4 vmathV4MakeWAxis_V( );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline float vmathV4MaxElem_V( VmathVector4 vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline float vmathV4MinElem_V( VmathVector4 vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline float vmathV4Sum_V( VmathVector4 vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline float vmathV4LengthSqr_V( VmathVector4 vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline float vmathV4Length_V( VmathVector4 vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline VmathMatrix4 vmathV4Outer_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 );\n\n/*\n * Store four 4-D vectors as half-floats\n */\nstatic inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Print_V( VmathVector4 vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Prints_V( VmathVector4 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline VmathPoint3 vmathP3MakeFromElems_V( float x, float y, float z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a 3-D point\n */\nstatic inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D point\n */\nstatic inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathP3SetX_V( VmathPoint3 *result, float x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathP3SetY_V( VmathPoint3 *result, float y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathP3SetZ_V( VmathPoint3 *result, float z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline float vmathP3GetX_V( VmathPoint3 pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline float vmathP3GetY_V( VmathPoint3 pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline float vmathP3GetZ_V( VmathPoint3 pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline float vmathP3MaxElem_V( VmathPoint3 pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline float vmathP3MinElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline float vmathP3Sum_V( VmathPoint3 pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D point in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D points in three quadwords\n */\nstatic inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D points as half-floats\n */\nstatic inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Print_V( VmathPoint3 pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name );\n\n#endif\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline VmathQuat vmathQMakeFromElems_V( float x, float y, float z, float w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline VmathQuat vmathQMakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a quaternion\n */\nstatic inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a quaternion\n */\nstatic inline vec_float4 vmathQGet128_V( VmathQuat quat );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathQSetX_V( VmathQuat *result, float x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathQSetY_V( VmathQuat *result, float y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathQSetZ_V( VmathQuat *result, float z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathQSetW_V( VmathQuat *result, float w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline float vmathQGetX_V( VmathQuat quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline float vmathQGetY_V( VmathQuat quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline float vmathQGetZ_V( VmathQuat quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline float vmathQGetW_V( VmathQuat quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathQSetElem_V( VmathQuat *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline float vmathQGetElem_V( VmathQuat quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline VmathQuat vmathQNeg_V( VmathQuat quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline VmathQuat vmathQMakeIdentity_V( );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline VmathQuat vmathQMakeRotationX_V( float radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline VmathQuat vmathQMakeRotationY_V( float radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline VmathQuat vmathQMakeRotationZ_V( float radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline VmathQuat vmathQConj_V( VmathQuat quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline VmathVector3 vmathQRotate_V( VmathQuat unitQuat, VmathVector3 vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline float vmathQNorm_V( VmathQuat quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline float vmathQLength_V( VmathQuat quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline VmathQuat vmathQNormalize_V( VmathQuat quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrint_V( VmathQuat quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrints_V( VmathQuat quat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3MakeIdentity_V( );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationX_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationY_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline float vmathM3Determinant_V( VmathMatrix3 mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Print_V( VmathMatrix3 mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 col0, VmathVector4 col1, VmathVector4 col2, VmathVector4 col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeIdentity_V( );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationX_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationY_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline float vmathM4Determinant_V( VmathMatrix4 mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Print_V( VmathMatrix4 mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2, VmathVector3 col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline VmathTransform3 vmathT3MakeIdentity_V( );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationX_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationY_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationZ_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n * However, the transfer of select1 to a VMX register may use more processing time than a branch.\n */\nstatic inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Print_V( VmathTransform3 tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vectormath_aos.h\"\n#include \"vec_aos_v.h\"\n#include \"quat_aos_v.h\"\n#include \"mat_aos_v.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vectormath_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_C_PPU_H\n#define _VECTORMATH_SOA_C_PPU_H\n\n#include <math.h>\n#include <altivec.h>\n#include \"vectormath_aos.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_SOA_C_TYPES_H\n#define _VECTORMATH_SOA_C_TYPES_H\n\n/* A set of four 3-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaVector3;\n\n/* A set of four 4-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector4\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaVector4;\n\n/* A set of four 3-D points in structure-of-arrays format\n */\ntypedef struct _VmathSoaPoint3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaPoint3;\n\n/* A set of four quaternions in structure-of-arrays format\n */\ntypedef struct _VmathSoaQuat\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaQuat;\n\n/* A set of four 3x3 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n} VmathSoaMatrix3;\n\n/* A set of four 4x4 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix4\n{\n    VmathSoaVector4 col0;\n    VmathSoaVector4 col1;\n    VmathSoaVector4 col2;\n    VmathSoaVector4 col3;\n} VmathSoaMatrix4;\n\n/* A set of four 3x4 transformation matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaTransform3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n    VmathSoaVector3 col3;\n} VmathSoaTransform3;\n\n#endif\n\n/*\n * Copy a 3-D vector\n */\nstatic inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D vector\n */\nstatic inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec );\n\n/*\n * Insert four AoS 3-D vectors\n */\nstatic inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 );\n\n/*\n * Extract four AoS 3-D vectors\n */\nstatic inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n */\nstatic inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D vector in three quadwords\n */\nstatic inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D vectors as half-floats\n */\nstatic inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Print( const VmathSoaVector3 *vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 4-D vector\n */\nstatic inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 4-D vector\n */\nstatic inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec );\n\n/*\n * Insert four AoS 4-D vectors\n */\nstatic inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 );\n\n/*\n * Extract four AoS 4-D vectors\n */\nstatic inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result );\n\n/*\n * Construct w axis\n */\nstatic inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 );\n\n/*\n * Store four slots of an SoA 4-D vector as half-floats\n */\nstatic inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Print( const VmathSoaVector4 *vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 3-D point\n */\nstatic inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D point\n */\nstatic inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Insert four AoS 3-D points\n */\nstatic inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 );\n\n/*\n * Extract four AoS 3-D points\n */\nstatic inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D point in three quadwords\n */\nstatic inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *pnt, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D points as half-floats\n */\nstatic inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name );\n\n#endif\n\n/*\n * Copy a quaternion\n */\nstatic inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS quaternion\n */\nstatic inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat );\n\n/*\n * Insert four AoS quaternions\n */\nstatic inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 );\n\n/*\n * Extract four AoS quaternions\n */\nstatic inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline void vmathSoaQMakeIdentity( VmathSoaQuat *result );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrint( const VmathSoaQuat *quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x3 matrix\n */\nstatic inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x3 matrix\n */\nstatic inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Insert four AoS 3x3 matrices\n */\nstatic inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 );\n\n/*\n * Extract four AoS 3x3 matrices\n */\nstatic inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 4x4 matrix\n */\nstatic inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0, const VmathSoaVector4 *col1, const VmathSoaVector4 *col2, const VmathSoaVector4 *col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 4x4 matrix\n */\nstatic inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Insert four AoS 4x4 matrices\n */\nstatic inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 );\n\n/*\n * Extract four AoS 4x4 matrices\n */\nstatic inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2, const VmathSoaVector3 *col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Insert four AoS 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 );\n\n/*\n * Extract four AoS 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vec_soa.h\"\n#include \"quat_soa.h\"\n#include \"mat_soa.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/c/vectormath_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_C_V_PPU_H\n#define _VECTORMATH_SOA_C_V_PPU_H\n\n#include <math.h>\n#include <altivec.h>\n#include \"vectormath_aos_v.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_SOA_C_TYPES_H\n#define _VECTORMATH_SOA_C_TYPES_H\n\n/* A set of four 3-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaVector3;\n\n/* A set of four 4-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector4\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaVector4;\n\n/* A set of four 3-D points in structure-of-arrays format\n */\ntypedef struct _VmathSoaPoint3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaPoint3;\n\n/* A set of four quaternions in structure-of-arrays format\n */\ntypedef struct _VmathSoaQuat\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaQuat;\n\n/* A set of four 3x3 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n} VmathSoaMatrix3;\n\n/* A set of four 4x4 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix4\n{\n    VmathSoaVector4 col0;\n    VmathSoaVector4 col1;\n    VmathSoaVector4 col2;\n    VmathSoaVector4 col3;\n} VmathSoaMatrix4;\n\n/* A set of four 3x4 transformation matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaTransform3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n    VmathSoaVector3 col3;\n} VmathSoaTransform3;\n\n#endif\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec );\n\n/*\n * Insert four AoS 3-D vectors\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 );\n\n/*\n * Extract four AoS 3-D vectors\n */\nstatic inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D vector in three quadwords\n */\nstatic inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D vectors as half-floats\n */\nstatic inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Print_V( VmathSoaVector3 vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec );\n\n/*\n * Insert four AoS 4-D vectors\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 );\n\n/*\n * Extract four AoS 4-D vectors\n */\nstatic inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( );\n\n/*\n * Construct w axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 );\n\n/*\n * Store four slots of an SoA 4-D vector as half-floats\n */\nstatic inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Print_V( VmathSoaVector4 vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt );\n\n/*\n * Insert four AoS 3-D points\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 );\n\n/*\n * Extract four AoS 3-D points\n */\nstatic inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D point in three quadwords\n */\nstatic inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 pnt, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D points as half-floats\n */\nstatic inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name );\n\n#endif\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat );\n\n/*\n * Insert four AoS quaternions\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 );\n\n/*\n * Extract four AoS quaternions\n */\nstatic inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeIdentity_V( );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat unitQuat, VmathSoaVector3 vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrint_V( VmathSoaQuat quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat );\n\n/*\n * Insert four AoS 3x3 matrices\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 );\n\n/*\n * Extract four AoS 3x3 matrices\n */\nstatic inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 col0, VmathSoaVector4 col1, VmathSoaVector4 col2, VmathSoaVector4 col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat );\n\n/*\n * Insert four AoS 4x4 matrices\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 );\n\n/*\n * Extract four AoS 4x4 matrices\n */\nstatic inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2, VmathSoaVector3 col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x4 transformation matrix\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm );\n\n/*\n * Insert four AoS 3x4 transformation matrices\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 );\n\n/*\n * Extract four AoS 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vectormath_soa.h\"\n#include \"vec_soa_v.h\"\n#include \"quat_soa_v.h\"\n#include \"mat_soa_v.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/boolInVec.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _BOOLINVEC_H\n#define _BOOLINVEC_H\n\n#include <math.h>\n#include <altivec.h>\n#include \"../c/vec_types.h\"\n#undef bool\n\nnamespace Vectormath {\n\nclass floatInVec;\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec class\n//\n\nclass boolInVec\n{\n    private:\n        vec_uint4 mData;\n\n        inline boolInVec(vec_uint4 vec);\n    public:\n        inline boolInVec() {}\n\n        // matches standard type conversions\n        //\n        inline boolInVec(floatInVec vec);\n\n        // explicit cast from bool\n        //\n        explicit inline boolInVec(bool scalar);\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n        // explicit cast to bool\n        // \n        inline bool getAsBool() const;\n#else\n        // implicit cast to bool\n        // \n        inline operator bool() const;\n#endif\n        \n        // get vector data\n        // bool value is splatted across all word slots of vector as 0 (false) or -1 (true)\n        //\n        inline vec_uint4 get128() const;\n\n        // operators\n        //\n        inline const boolInVec operator ! () const;\n        inline boolInVec& operator = (boolInVec vec);\n        inline boolInVec& operator &= (boolInVec vec);\n        inline boolInVec& operator ^= (boolInVec vec);\n        inline boolInVec& operator |= (boolInVec vec);\n\n        // friend functions\n        //\n        friend inline const boolInVec operator == (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator != (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator < (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator > (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator == (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator != (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator & (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator | (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1);\n};\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec functions\n//\n\n// operators\n//\ninline const boolInVec operator == (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator != (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator & (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator | (boolInVec vec0, boolInVec vec1);\n\n// select between vec0 and vec1 using boolInVec.\n// false selects vec0, true selects vec1\n//\ninline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1);\n\n} // namespace Vectormath\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec implementation\n//\n\n#include \"floatInVec.h\"\n\nnamespace Vectormath {\n\ninline\nboolInVec::boolInVec(vec_uint4 vec)\n{\n    mData = vec;\n}\n\ninline\nboolInVec::boolInVec(floatInVec vec)\n{\n    *this = (vec != floatInVec(0.0f));\n}\n\ninline\nboolInVec::boolInVec(bool scalar)\n{\n#ifdef __GNUC__\n    if (__builtin_constant_p(scalar))\n    {\n        const unsigned int mask = -(int)scalar;\n        mData = (vec_uint4){mask, mask, mask, mask};\n    }\n    else\n#endif\n    {\n        unsigned int mask = -(int)scalar;\n        vec_uint4 vec = vec_ld(0, &mask);\n        mData = vec_splat(vec_perm(vec, vec, vec_lvsl(0, &mask)), 0);\n    }\n}\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline\nbool\nboolInVec::getAsBool() const\n#else\ninline\nboolInVec::operator bool() const\n#endif\n{\n    return vec_all_gt(mData, ((vec_uint4){0,0,0,0}));\n}\n\ninline\nvec_uint4\nboolInVec::get128() const\n{\n    return mData;\n}\n\ninline\nconst boolInVec\nboolInVec::operator ! () const\n{\n    return boolInVec(vec_nor(mData, mData));\n}\n\ninline\nboolInVec&\nboolInVec::operator = (boolInVec vec)\n{\n    mData = vec.mData;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator &= (boolInVec vec)\n{\n    *this = *this & vec;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator ^= (boolInVec vec)\n{\n    *this = *this ^ vec;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator |= (boolInVec vec)\n{\n    *this = *this | vec;\n    return *this;\n}\n\ninline\nconst boolInVec\noperator == (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec((vec_uint4)vec_cmpeq(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator != (boolInVec vec0, boolInVec vec1)\n{\n    return !(vec0 == vec1);\n}\n    \ninline\nconst boolInVec\noperator & (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(vec_and(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator | (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(vec_or(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator ^ (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(vec_xor(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\nselect(boolInVec vec0, boolInVec vec1, boolInVec select_vec1)\n{\n    return boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));\n}\n \n} // namespace Vectormath\n\n#endif // boolInVec_h\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/floatInVec.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _FLOATINVEC_H\n#define _FLOATINVEC_H\n\n#include <math.h>\n#include <altivec.h>\n#include <stddef.h>\n#include <simdmath.h>\n#include \"../c/vec_types.h\"\n#undef bool\n\nnamespace Vectormath {\n\nclass boolInVec;\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec class\n//\n\nclass floatInVec\n{\n    private:\n        vec_float4 mData;\n\n        inline floatInVec(vec_float4 vec);\n    public:\n        inline floatInVec() {}\n\n        // matches standard type conversions\n        //\n        inline floatInVec(boolInVec vec);\n\n        // construct from a slot of vec_float4\n        //\n        inline floatInVec(vec_float4 vec, int slot);\n        \n        // explicit cast from float\n        //\n        explicit inline floatInVec(float scalar);\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n        // explicit cast to float\n        // \n        inline float getAsFloat() const;\n#else\n        // implicit cast to float\n        //\n        inline operator float() const;\n#endif\n\n        // get vector data\n        // float value is splatted across all word slots of vector\n        //\n        inline vec_float4 get128() const;\n\n        // operators\n        // \n        inline const floatInVec operator ++ (int);\n        inline const floatInVec operator -- (int);\n        inline floatInVec& operator ++ ();\n        inline floatInVec& operator -- ();\n        inline const floatInVec operator - () const;\n        inline floatInVec& operator = (floatInVec vec);\n        inline floatInVec& operator *= (floatInVec vec);\n        inline floatInVec& operator /= (floatInVec vec);\n        inline floatInVec& operator += (floatInVec vec);\n        inline floatInVec& operator -= (floatInVec vec);\n\n        // friend functions\n        //\n        friend inline const floatInVec operator * (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec operator / (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec operator + (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec operator - (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1);\n};\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec functions\n//\n\n// operators\n// \ninline const floatInVec operator * (floatInVec vec0, floatInVec vec1);\ninline const floatInVec operator / (floatInVec vec0, floatInVec vec1);\ninline const floatInVec operator + (floatInVec vec0, floatInVec vec1);\ninline const floatInVec operator - (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator < (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator <= (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator > (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator >= (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator == (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator != (floatInVec vec0, floatInVec vec1);\n\n// select between vec0 and vec1 using boolInVec.\n// false selects vec0, true selects vec1\n//\ninline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1);\n\n} // namespace Vectormath\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec implementation\n//\n\n#include \"boolInVec.h\"\n\nnamespace Vectormath {\n\ninline\nfloatInVec::floatInVec(vec_float4 vec)\n{\n    mData = vec;\n}\n\ninline\nfloatInVec::floatInVec(boolInVec vec)\n{\n    mData = vec_ctf(vec_sub((vec_uint4){0,0,0,0}, vec.get128()), 0);\n}\n\ninline\nfloatInVec::floatInVec(vec_float4 vec, int slot)\n{\n#ifdef __GNUC__\n    if (__builtin_constant_p(slot))\n    {\n        mData = vec_splat(vec, slot);\n    }\n    else\n#endif\n    {\n        const vec_uchar16 shiftpattern = vec_lvsl(0, (float *)(size_t)(slot << 2));\n        mData = vec_splat(vec_perm(vec, vec, shiftpattern), 0);\n    }\n}\n\ninline\nfloatInVec::floatInVec(float scalar)\n{\n#ifdef __GNUC__\n    if (__builtin_constant_p(scalar))\n    {\n        mData = (vec_float4){scalar, scalar, scalar, scalar};\n    }\n    else\n#endif\n    {\n        vec_float4 vec = vec_ld(0, &scalar);\n        mData = vec_splat(vec_perm(vec, vec, vec_lvsl(0, &scalar)), 0);\n    }\n}\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline\nfloat\nfloatInVec::getAsFloat() const\n#else\ninline\nfloatInVec::operator float() const\n#endif\n{\n    return *((float *)&mData);\n}\n\ninline\nvec_float4\nfloatInVec::get128() const\n{\n    return mData;\n}\n\ninline\nconst floatInVec\nfloatInVec::operator ++ (int)\n{\n    vec_float4 olddata = mData;\n    operator ++();\n    return floatInVec(olddata);\n}\n\ninline\nconst floatInVec\nfloatInVec::operator -- (int)\n{\n    vec_float4 olddata = mData;\n    operator --();\n    return floatInVec(olddata);\n}\n\ninline\nfloatInVec&\nfloatInVec::operator ++ ()\n{\n    *this += floatInVec((vec_float4){1.0f,1.0f,1.0f,1.0f});\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator -- ()\n{\n    *this -= floatInVec((vec_float4){1.0f,1.0f,1.0f,1.0f});\n    return *this;\n}\n\ninline\nconst floatInVec\nfloatInVec::operator - () const\n{\n    return floatInVec((vec_float4)vec_xor((vec_uint4)mData, (vec_uint4){0x80000000,0x80000000,0x80000000,0x80000000}));\n}\n\ninline\nfloatInVec&\nfloatInVec::operator = (floatInVec vec)\n{\n    mData = vec.mData;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator *= (floatInVec vec)\n{\n    *this = *this * vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator /= (floatInVec vec)\n{\n    *this = *this / vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator += (floatInVec vec)\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator -= (floatInVec vec)\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline\nconst floatInVec\noperator * (floatInVec vec0, floatInVec vec1)\n{\n    return floatInVec(vec_madd(vec0.get128(), vec1.get128(), (vec_float4){0,0,0,0}));\n}\n\ninline\nconst floatInVec\noperator / (floatInVec num, floatInVec den)\n{\n    return floatInVec(divf4(num.get128(), den.get128()));\n}\n\ninline\nconst floatInVec\noperator + (floatInVec vec0, floatInVec vec1)\n{\n    return floatInVec(vec_add(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst floatInVec\noperator - (floatInVec vec0, floatInVec vec1)\n{\n    return floatInVec(vec_sub(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator < (floatInVec vec0, floatInVec vec1)\n{\n    return boolInVec((vec_uint4)vec_cmpgt(vec1.get128(), vec0.get128()));\n}\n\ninline\nconst boolInVec\noperator <= (floatInVec vec0, floatInVec vec1)\n{\n    return !(vec0 > vec1);\n}\n\ninline\nconst boolInVec\noperator > (floatInVec vec0, floatInVec vec1)\n{\n    return boolInVec((vec_uint4)vec_cmpgt(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator >= (floatInVec vec0, floatInVec vec1)\n{\n    return !(vec0 < vec1);\n}\n\ninline\nconst boolInVec\noperator == (floatInVec vec0, floatInVec vec1)\n{\n    return boolInVec((vec_uint4)vec_cmpeq(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator != (floatInVec vec0, floatInVec vec1)\n{\n    return !(vec0 == vec1);\n}\n    \ninline\nconst floatInVec\nselect(floatInVec vec0, floatInVec vec1, boolInVec select_vec1)\n{\n    return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));\n}\n\n} // namespace Vectormath\n\n#endif // floatInVec_h\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_CPP_H\n#define _VECTORMATH_MAT_AOS_CPP_H\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Constants\n// for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X })     \n#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z })\n#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y })\n#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C })\n#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\ninline Matrix3::Matrix3( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n}\n\ninline Matrix3::Matrix3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( floatInVec scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( Quat unitQuat )\n{\n    vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    vec_uint4 select_x = _VECTORMATH_MASK_0xF000;\n    vec_uint4 select_z = _VECTORMATH_MASK_0x00F0;\n    xyzw_2 = vec_add( unitQuat.get128(), unitQuat.get128() );\n    wwww = vec_splat( unitQuat.get128(), 3 );\n    yzxw = vec_perm( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_PERM_YZXW );\n    zxyw = vec_perm( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_PERM_ZXYW );\n    yzxw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_YZXW );\n    zxyw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_ZXYW );\n    tmp0 = vec_madd( yzxw_2, wwww, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_nmsub( yzxw, yzxw_2, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    tmp2 = vec_madd( yzxw, xyzw_2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp0 = vec_madd( zxyw, xyzw_2, tmp0 );\n    tmp1 = vec_nmsub( zxyw, zxyw_2, tmp1 );\n    tmp2 = vec_nmsub( zxyw_2, wwww, tmp2 );\n    tmp3 = vec_sel( tmp0, tmp1, select_x );\n    tmp4 = vec_sel( tmp1, tmp2, select_x );\n    tmp5 = vec_sel( tmp2, tmp0, select_x );\n    mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) );\n    mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) );\n    mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) );\n}\n\ninline Matrix3::Matrix3( Vector3 _col0, Vector3 _col1, Vector3 _col2 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n}\n\ninline Matrix3 & Matrix3::setCol0( Vector3 _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol1( Vector3 _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol2( Vector3 _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol( int col, Vector3 vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setRow( int row, Vector3 vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, floatInVec val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline const floatInVec Matrix3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Matrix3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Matrix3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Matrix3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Matrix3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::getRow( int row ) const\n{\n    return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) );\n}\n\ninline Vector3 & Matrix3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix3 & Matrix3::operator =( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    return *this;\n}\n\ninline const Matrix3 transpose( const Matrix3 & mat )\n{\n    vec_float4 tmp0, tmp1, res0, res1, res2;\n    tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() );\n    res0 = vec_mergeh( tmp0, mat.getCol1().get128() );\n    res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX );\n    res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 inverse( const Matrix3 & mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() );\n    tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() );\n    tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() );\n    dot = _vmathVfDot3( tmp2, mat.getCol2().get128() );\n    dot = vec_splat( dot, 0 );\n    invdet = recipf4( dot );\n    tmp3 = vec_mergeh( tmp0, tmp2 );\n    tmp4 = vec_mergel( tmp0, tmp2 );\n    inv0 = vec_mergeh( tmp3, tmp1 );\n    inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX );\n    inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX );\n    inv0 = vec_madd( inv0, invdet, zero );\n    inv1 = vec_madd( inv1, invdet, zero );\n    inv2 = vec_madd( inv2, invdet, zero );\n    return Matrix3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 )\n    );\n}\n\ninline const floatInVec determinant( const Matrix3 & mat )\n{\n    return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) );\n}\n\ninline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 )\n    );\n}\n\ninline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator +=( const Matrix3 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::operator -=( const Matrix3 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix3 Matrix3::operator -( ) const\n{\n    return Matrix3(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 )\n    );\n}\n\ninline const Matrix3 absPerElem( const Matrix3 & mat )\n{\n    return Matrix3(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Matrix3 Matrix3::operator *( floatInVec scalar ) const\n{\n    return Matrix3(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( float scalar )\n{\n    return *this *= floatInVec(scalar);\n}\n\ninline Matrix3 & Matrix3::operator *=( floatInVec scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix3 operator *( float scalar, const Matrix3 & mat )\n{\n    return floatInVec(scalar) * mat;\n}\n\ninline const Matrix3 operator *( floatInVec scalar, const Matrix3 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector3 Matrix3::operator *( Vector3 vec ) const\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec.get128(), 0 );\n    yyyy = vec_splat( vec.get128(), 1 );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_madd( mCol0.get128(), xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( mCol1.get128(), yyyy, res );\n    res = vec_madd( mCol2.get128(), zzzz, res );\n    return Vector3( res );\n}\n\ninline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( const Matrix3 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 )\n{\n    return Matrix3(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::identity( )\n{\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Matrix3 Matrix3::rotationX( floatInVec radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Matrix3 Matrix3::rotationY( floatInVec radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3::yAxis( ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Matrix3 Matrix3::rotationZ( floatInVec radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZYX( Vector3 radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    angles = Vector4( radiansXYZ, 0.0f ).get128();\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n    Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F );\n    Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX );\n    Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_madd( Z0, Y1, zero );\n    return Matrix3(\n        Vector3( vec_madd( Z0, Y0, zero ) ),\n        Vector3( vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ) ),\n        Vector3( vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( float radians, Vector3 unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Matrix3 Matrix3::rotation( floatInVec radians, Vector3 unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    axis = unitVec.get128();\n    sincosf4( radians.get128(), &s, &c );\n    xxxx = vec_splat( axis, 0 );\n    yyyy = vec_splat( axis, 1 );\n    zzzz = vec_splat( axis, 2 );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    axisS = vec_madd( axis, s, zero );\n    negAxisS = negatef4( axisS );\n    tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX );\n    tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX );\n    tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX );\n    tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 );\n    tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 );\n    tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 );\n    return Matrix3(\n        Vector3( vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 ) ),\n        Vector3( vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 ) ),\n        Vector3( vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( Quat unitQuat )\n{\n    return Matrix3( unitQuat );\n}\n\ninline const Matrix3 Matrix3::scale( Vector3 scaleVec )\n{\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    return Matrix3(\n        Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0xF000 ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x0F00 ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x00F0 ) )\n    );\n}\n\ninline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec )\n{\n    return Matrix3(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) )\n    );\n}\n\ninline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat )\n{\n    return Matrix3(\n        mulPerElem( mat.getCol0(), scaleVec ),\n        mulPerElem( mat.getCol1(), scaleVec ),\n        mulPerElem( mat.getCol2(), scaleVec )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, boolInVec select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix3 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n}\n\ninline void print( const Matrix3 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Matrix4::Matrix4( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n}\n\ninline Matrix4::Matrix4( float scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( floatInVec scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const Transform3 & mat )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( mat.getCol3(), 1.0f );\n}\n\ninline Matrix4::Matrix4( Vector4 _col0, Vector4 _col1, Vector4 _col2, Vector4 _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Matrix4::Matrix4( const Matrix3 & mat, Vector3 translateVec )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4::Matrix4( Quat unitQuat, Vector3 translateVec )\n{\n    Matrix3 mat;\n    mat = Matrix3( unitQuat );\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4 & Matrix4::setCol0( Vector4 _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol1( Vector4 _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol2( Vector4 _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol3( Vector4 _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol( int col, Vector4 vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setRow( int row, Vector4 vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, floatInVec val )\n{\n    Vector4 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline const floatInVec Matrix4::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector4 Matrix4::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector4 Matrix4::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector4 Matrix4::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector4 Matrix4::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector4 Matrix4::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector4 & Matrix4::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix4 & Matrix4::operator =( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n    return *this;\n}\n\ninline const Matrix4 transpose( const Matrix4 & mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3;\n    tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() );\n    tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() );\n    res0 = vec_mergeh( tmp0, tmp1 );\n    res1 = vec_mergel( tmp0, tmp1 );\n    res2 = vec_mergeh( tmp2, tmp3 );\n    res3 = vec_mergel( tmp2, tmp3 );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4( res1 ),\n        Vector4( res2 ),\n        Vector4( res3 )\n    );\n}\n\ninline const Matrix4 inverse( const Matrix4 & mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vector float in0, in1, in2, in3;\n    vector float tmp0, tmp1, tmp2, tmp3;\n    vector float cof0, cof1, cof2, cof3;\n    vector float t0, t1, t2, t3;\n    vector float t01, t02, t03, t12, t23;\n    vector float t1r, t2r;\n    vector float t01r, t02r, t03r, t12r, t23r;\n    vector float t1r3, t1r3r;\n    vector float det, det0, det1, det2, det3, invdet;\n    vector float vzero = (vector float){0.0};\n    in0 = mat.getCol0().get128();\n    in1 = mat.getCol1().get128();\n    in2 = mat.getCol2().get128();\n    in3 = mat.getCol3().get128();\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC);\t/* A E C G */\n    tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC);\t/* I M K O */\n    tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD);\t/* B F D H */\n    tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD);\t/* J N L P */\n    t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB);\t/* A E I M */\n    t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB);\t/* J N B F */\n    t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD);\t/* C G K O */\n    t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD);\t/* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = vec_madd(t2, t3, vzero);\t\t/* CL GP KD OH */\n    t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ);\t/* GP CL OH KD */\n    cof0 = vec_nmsub(t1, t23, vzero);\t\t/* -(JGP NCL FOH BKD) */\n    cof1 = vec_nmsub(t0, t23, vzero);\t\t/* -(AGP ECL IOH MKD) */\n    t23r = vec_sld(t23, t23, 8);\t\t\t/* OH KD GP CL */\n    cof0 = vec_madd(t1, t23r, cof0);\t\t/* JOH NKD BGP FCL + cof0 */\n    cof1 = vec_madd(t0, t23r, cof1);\t\t/* AOH EKD IGP MCL + cof1 */\n    cof1 = vec_sld(cof1, cof1, 8);\t\t/* IGP MCL AOH EKD - IOH MKD AGP ECL */\n    t12 = vec_madd(t1, t2, vzero);\t\t/* JC NG BK FO */\n    t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ);\t/* NG JC FO BK */\n    cof0 = vec_madd(t3, t12, cof0);\t\t/* LNG PJC DFO HBK + cof0 */\n    cof3 = vec_madd(t0, t12, vzero);\t\t/* ANG EJC IFO MBK */\n    t12r = vec_sld(t12, t12, 8);\t\t\t/* FO BK NG JC */\n    cof0 = vec_nmsub(t3, t12r, cof0);\t\t/* cof0 - LFO PBK DNG HJC */\n    cof3 = vec_nmsub(t0, t12r, cof3);\t\t/* cof3 - AFO EBK ING MJC */\n    cof3 = vec_sld(cof3, cof3, 8);\t\t/* ING MJC AFO EBK - IFO MBK ANG EJC */\n    t1r = vec_sld(t1, t1, 8);\t\t\t/* B F J N */\n    t2r = vec_sld(t2, t2, 8);\t\t\t/* K O C G */\n    t1r3 = vec_madd(t1r, t3, vzero);\t\t/* BL FP JD NH */\n    t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ);\t/* FP BL NH JD */\n    cof0 = vec_madd(t2r, t1r3, cof0);\t\t/* KFP OBL CNH GJD + cof0 */\n    cof2 = vec_madd(t0, t1r3, vzero);\t\t/* AFP EBL INH MJD */\n    t1r3r = vec_sld(t1r3, t1r3, 8);\t\t/* NH JD FP BL */\n    cof0 = vec_nmsub(t2r, t1r3r, cof0);\t\t/* cof0 - KNH OJD CFP GBL */\n    cof2 = vec_nmsub(t0, t1r3r, cof2);\t\t/* cof2 - ANH EJD IFP MBL */\n    cof2 = vec_sld(cof2, cof2, 8);\t\t/* IFP MBL ANH EJD - INH MJD AFP EBL */\n    t01 = vec_madd(t0, t1, vzero);\t\t/* AJ EN IB MF */\n    t01 = vec_perm(t01, t01, _VECTORMATH_PERM_YXWZ);\t/* EN AJ MF IB */\n    cof2 = vec_nmsub(t3, t01, cof2);\t\t/* cof2 - LEN PAJ DMF HIB */\n    cof3 = vec_madd(t2r, t01, cof3);\t\t/* KEN OAJ CMF GIB + cof3 */ \n    t01r = vec_sld(t01, t01, 8);\t\t\t/* MF IB EN AJ */\n    cof2 = vec_madd(t3, t01r, cof2);\t\t/* LMF PIB DEN HAJ + cof2 */\n    cof3 = vec_nmsub(t2r, t01r, cof3);\t\t/* cof3 - KMF OIB CEN GAJ */\n    t03 = vec_madd(t0, t3, vzero);\t\t/* AL EP ID MH */\n    t03 = vec_perm(t03, t03, _VECTORMATH_PERM_YXWZ);\t/* EP AL MH ID */\n    cof1 = vec_nmsub(t2r, t03, cof1);\t\t/* cof1 - KEP OAL CMH GID */\n    cof2 = vec_madd(t1, t03, cof2);\t\t/* JEP NAL BMH FID + cof2 */\n    t03r = vec_sld(t03, t03, 8);\t\t\t/* MH ID EP AL */\n    cof1 = vec_madd(t2r, t03r, cof1);\t\t/* KMH OID CEP GAL + cof1 */\n    cof2 = vec_nmsub(t1, t03r, cof2);\t\t/* cof2 - JMH NID BEP FAL */ \n    t02 = vec_madd(t0, t2r, vzero);\t\t/* AK EO IC MG */\n    t02 = vec_perm(t02, t02, _VECTORMATH_PERM_YXWZ);\t/* E0 AK MG IC */\n    cof1 = vec_madd(t3, t02, cof1);\t\t/* LEO PAK DMG HIC + cof1 */\n    cof3 = vec_nmsub(t1, t02, cof3);\t\t/* cof3 - JEO NAK BMG FIC */\n    t02r = vec_sld(t02, t02, 8);\t\t\t/* MG IC EO AK */\n    cof1 = vec_nmsub(t3, t02r, cof1);\t\t/* cof1 - LMG PIC DEO HAK */\n    cof3 = vec_madd(t1, t02r, cof3);\t\t/* JMG NIC BEO FAK + cof3 */\n    /* Compute the determinant of the matrix \n     *\n     * det = sum_across(t0 * cof0);\n     *\n     * We perform a sum across the entire vector so that \n     * we don't have to splat the result when multiplying the\n     * cofactors by the inverse of the determinant.\n     */\n    det  = vec_madd(t0, cof0, vzero);\n    det0 = vec_splat(det, 0);\n    det1 = vec_splat(det, 1);\n    det2 = vec_splat(det, 2);\n    det3 = vec_splat(det, 3);\n    det  = vec_add(det0, det1);\n    det2 = vec_add(det2, det3);\n    det  = vec_add(det, det2);\n    /* Compute the reciprocal of the determinant.\n     */\n    invdet = recipf4(det);\n    /* Multiply the cofactors by the reciprocal of the determinant.\n     */ \n    return Matrix4(\n        Vector4( vec_madd(cof0, invdet, vzero) ),\n        Vector4( vec_madd(cof1, invdet, vzero) ),\n        Vector4( vec_madd(cof2, invdet, vzero) ),\n        Vector4( vec_madd(cof3, invdet, vzero) )\n    );\n}\n\ninline const Matrix4 affineInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( inverse( affineMat ) );\n}\n\ninline const Matrix4 orthoInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( orthoInverse( affineMat ) );\n}\n\ninline const floatInVec determinant( const Matrix4 & mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vector float in0, in1, in2, in3;\n    vector float tmp0, tmp1, tmp2, tmp3;\n    vector float cof0;\n    vector float t0, t1, t2, t3;\n    vector float t12, t23;\n    vector float t1r, t2r;\n    vector float t12r, t23r;\n    vector float t1r3, t1r3r;\n    vector float vzero = (vector float){0.0};\n    in0 = mat.getCol0().get128();\n    in1 = mat.getCol1().get128();\n    in2 = mat.getCol2().get128();\n    in3 = mat.getCol3().get128();\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC);\t/* A E C G */\n    tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC);\t/* I M K O */\n    tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD);\t/* B F D H */\n    tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD);\t/* J N L P */\n    t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB);\t/* A E I M */\n    t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB);\t/* J N B F */\n    t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD);\t/* C G K O */\n    t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD);\t/* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = vec_madd(t2, t3, vzero);\t\t/* CL GP KD OH */\n    t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ);\t/* GP CL OH KD */\n    cof0 = vec_nmsub(t1, t23, vzero);\t\t/* -(JGP NCL FOH BKD) */\n    t23r = vec_sld(t23, t23, 8);\t\t\t/* OH KD GP CL */\n    cof0 = vec_madd(t1, t23r, cof0);\t\t/* JOH NKD BGP FCL + cof0 */\n    t12 = vec_madd(t1, t2, vzero);\t\t/* JC NG BK FO */\n    t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ);\t/* NG JC FO BK */\n    cof0 = vec_madd(t3, t12, cof0);\t\t/* LNG PJC DFO HBK + cof0 */\n    t12r = vec_sld(t12, t12, 8);\t\t\t/* FO BK NG JC */\n    cof0 = vec_nmsub(t3, t12r, cof0);\t\t/* cof0 - LFO PBK DNG HJC */\n    t1r = vec_sld(t1, t1, 8);\t\t\t/* B F J N */\n    t2r = vec_sld(t2, t2, 8);\t\t\t/* K O C G */\n    t1r3 = vec_madd(t1r, t3, vzero);\t\t/* BL FP JD NH */\n    t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ);\t/* FP BL NH JD */\n    cof0 = vec_madd(t2r, t1r3, cof0);\t\t/* KFP OBL CNH GJD + cof0 */\n    t1r3r = vec_sld(t1r3, t1r3, 8);\t\t/* NH JD FP BL */\n    cof0 = vec_nmsub(t2r, t1r3r, cof0);\t\t/* cof0 - KNH OJD CFP GBL */\n    return floatInVec( _vmathVfDot4(t0,cof0), 0 );\n}\n\ninline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 ),\n        ( mCol3 + mat.mCol3 )\n    );\n}\n\ninline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 ),\n        ( mCol3 - mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator +=( const Matrix4 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::operator -=( const Matrix4 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator -( ) const\n{\n    return Matrix4(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 ),\n        ( -mCol3 )\n    );\n}\n\ninline const Matrix4 absPerElem( const Matrix4 & mat )\n{\n    return Matrix4(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() ),\n        absPerElem( mat.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Matrix4 Matrix4::operator *( floatInVec scalar ) const\n{\n    return Matrix4(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar ),\n        ( mCol3 * scalar )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( float scalar )\n{\n    return *this *= floatInVec(scalar);\n}\n\ninline Matrix4 & Matrix4::operator *=( floatInVec scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix4 operator *( float scalar, const Matrix4 & mat )\n{\n    return floatInVec(scalar) * mat;\n}\n\ninline const Matrix4 operator *( floatInVec scalar, const Matrix4 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector4 Matrix4::operator *( Vector4 vec ) const\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz, wwww;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    xxxx = vec_splat( vec.get128(), 0 );\n    yyyy = vec_splat( vec.get128(), 1 );\n    zzzz = vec_splat( vec.get128(), 2 );\n    wwww = vec_splat( vec.get128(), 3 );\n    tmp0 = vec_madd( mCol0.get128(), xxxx, zero );\n    tmp1 = vec_madd( mCol1.get128(), yyyy, zero );\n    tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = vec_madd( mCol3.get128(), wwww, tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    return Vector4( res );\n}\n\ninline const Vector4 Matrix4::operator *( Vector3 vec ) const\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec.get128(), 0 );\n    yyyy = vec_splat( vec.get128(), 1 );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_madd( mCol0.get128(), xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( mCol1.get128(), yyyy, res );\n    res = vec_madd( mCol2.get128(), zzzz, res );\n    return Vector4( res );\n}\n\ninline const Vector4 Matrix4::operator *( Point3 pnt ) const\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    xxxx = vec_splat( pnt.get128(), 0 );\n    yyyy = vec_splat( pnt.get128(), 1 );\n    zzzz = vec_splat( pnt.get128(), 2 );\n    tmp0 = vec_madd( mCol0.get128(), xxxx, zero );\n    tmp1 = vec_madd( mCol1.get128(), yyyy, zero );\n    tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = vec_add( mCol3.get128(), tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    return Vector4( res );\n}\n\ninline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 ),\n        ( *this * mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Matrix4 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const\n{\n    return Matrix4(\n        ( *this * tfrm.getCol0() ),\n        ( *this * tfrm.getCol1() ),\n        ( *this * tfrm.getCol2() ),\n        ( *this * Point3( tfrm.getCol3() ) )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 )\n{\n    return Matrix4(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() ),\n        mulPerElem( mat0.getCol3(), mat1.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::identity( )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 )\n{\n    mCol0.setXYZ( mat3.getCol0() );\n    mCol1.setXYZ( mat3.getCol1() );\n    mCol2.setXYZ( mat3.getCol2() );\n    return *this;\n}\n\ninline const Matrix3 Matrix4::getUpper3x3( ) const\n{\n    return Matrix3(\n        mCol0.getXYZ( ),\n        mCol1.getXYZ( ),\n        mCol2.getXYZ( )\n    );\n}\n\ninline Matrix4 & Matrix4::setTranslation( Vector3 translateVec )\n{\n    mCol3.setXYZ( translateVec );\n    return *this;\n}\n\ninline const Vector3 Matrix4::getTranslation( ) const\n{\n    return mCol3.getXYZ( );\n}\n\ninline const Matrix4 Matrix4::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Matrix4 Matrix4::rotationX( floatInVec radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4( res1 ),\n        Vector4( res2 ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Matrix4 Matrix4::rotationY( floatInVec radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4::yAxis( ),\n        Vector4( res2 ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Matrix4 Matrix4::rotationZ( floatInVec radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4( res1 ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZYX( Vector3 radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    angles = Vector4( radiansXYZ, 0.0f ).get128();\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n    Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F );\n    Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX );\n    Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_madd( Z0, Y1, zero );\n    return Matrix4(\n        Vector4( vec_madd( Z0, Y0, zero ) ),\n        Vector4( vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ) ),\n        Vector4( vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( float radians, Vector3 unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Matrix4 Matrix4::rotation( floatInVec radians, Vector3 unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    axis = unitVec.get128();\n    sincosf4( radians.get128(), &s, &c );\n    xxxx = vec_splat( axis, 0 );\n    yyyy = vec_splat( axis, 1 );\n    zzzz = vec_splat( axis, 2 );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    axisS = vec_madd( axis, s, zero );\n    negAxisS = negatef4( axisS );\n    tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX );\n    tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX );\n    tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX );\n    tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 );\n    tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 );\n    tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 );\n    zeroW = (vec_float4)_VECTORMATH_MASK_0x000F;\n    axis = vec_andc( axis, zeroW );\n    tmp0 = vec_andc( tmp0, zeroW );\n    tmp1 = vec_andc( tmp1, zeroW );\n    tmp2 = vec_andc( tmp2, zeroW );\n    return Matrix4(\n        Vector4( vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 ) ),\n        Vector4( vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 ) ),\n        Vector4( vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( Quat unitQuat )\n{\n    return Matrix4( Transform3::rotation( unitQuat ) );\n}\n\ninline const Matrix4 Matrix4::scale( Vector3 scaleVec )\n{\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    return Matrix4(\n        Vector4( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0xF000 ) ),\n        Vector4( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x0F00 ) ),\n        Vector4( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x00F0 ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec )\n{\n    return Matrix4(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) ),\n        mat.getCol3()\n    );\n}\n\ninline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat )\n{\n    Vector4 scale4;\n    scale4 = Vector4( scaleVec, 1.0f );\n    return Matrix4(\n        mulPerElem( mat.getCol0(), scale4 ),\n        mulPerElem( mat.getCol1(), scale4 ),\n        mulPerElem( mat.getCol2(), scale4 ),\n        mulPerElem( mat.getCol3(), scale4 )\n    );\n}\n\ninline const Matrix4 Matrix4::translation( Vector3 translateVec )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4( translateVec, 1.0f )\n    );\n}\n\ninline const Matrix4 Matrix4::lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec )\n{\n    Matrix4 m4EyeFrame;\n    Vector3 v3X, v3Y, v3Z;\n    v3Y = normalize( upVec );\n    v3Z = normalize( ( eyePos - lookAtPos ) );\n    v3X = normalize( cross( v3Y, v3Z ) );\n    v3Y = cross( v3Z, v3X );\n    m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) );\n    return orthoInverse( m4EyeFrame );\n}\n\ninline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    vec_float4 zero, col0, col1, col2, col3;\n    union { vec_float4 v; float s[4]; } tmp;\n    f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f );\n    rangeInv = 1.0f / ( zNear - zFar );\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    tmp.v = zero;\n    tmp.s[0] = f / aspect;\n    col0 = tmp.v;\n    tmp.v = zero;\n    tmp.s[1] = f;\n    col1 = tmp.v;\n    tmp.v = zero;\n    tmp.s[2] = ( zNear + zFar ) * rangeInv;\n    tmp.s[3] = -1.0f;\n    col2 = tmp.v;\n    tmp.v = zero;\n    tmp.s[2] = zNear * zFar * rangeInv * 2.0f;\n    col3 = tmp.v;\n    return Matrix4(\n        Vector4( col0 ),\n        Vector4( col1 ),\n        Vector4( col2 ),\n        Vector4( col3 )\n    );\n}\n\ninline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff;\n    vec_float4 diagonal, column, near2;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    union { vec_float4 v; float s[4]; } l, f, r, n, b, t;\n    l.s[0] = left;\n    f.s[0] = zFar;\n    r.s[0] = right;\n    n.s[0] = zNear;\n    b.s[0] = bottom;\n    t.s[0] = top;\n    lbf = vec_mergeh( l.v, f.v );\n    rtn = vec_mergeh( r.v, n.v );\n    lbf = vec_mergeh( lbf, b.v );\n    rtn = vec_mergeh( rtn, t.v );\n    diff = vec_sub( rtn, lbf );\n    sum  = vec_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    near2 = vec_splat( n.v, 0 );\n    near2 = vec_add( near2, near2 );\n    diagonal = vec_madd( near2, inv_diff, zero );\n    column = vec_madd( sum, inv_diff, zero );\n    return Matrix4(\n        Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 ) ),\n        Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 ) ),\n        Vector4( vec_sel( column, ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}), _VECTORMATH_MASK_0x000F ) ),\n        Vector4( vec_sel( zero, vec_madd( diagonal, vec_splat( f.v, 0 ), zero ), _VECTORMATH_MASK_0x00F0 ) )\n    );\n}\n\ninline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff, neg_inv_diff;\n    vec_float4 diagonal, column;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    union { vec_float4 v; float s[4]; } l, f, r, n, b, t;\n    l.s[0] = left;\n    f.s[0] = zFar;\n    r.s[0] = right;\n    n.s[0] = zNear;\n    b.s[0] = bottom;\n    t.s[0] = top;\n    lbf = vec_mergeh( l.v, f.v );\n    rtn = vec_mergeh( r.v, n.v );\n    lbf = vec_mergeh( lbf, b.v );\n    rtn = vec_mergeh( rtn, t.v );\n    diff = vec_sub( rtn, lbf );\n    sum  = vec_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    neg_inv_diff = negatef4( inv_diff );\n    diagonal = vec_add( inv_diff, inv_diff );\n    column = vec_madd( sum, vec_sel( neg_inv_diff, inv_diff, _VECTORMATH_MASK_0x00F0 ), zero );\n    return Matrix4(\n        Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 ) ),\n        Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 ) ),\n        Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0x00F0 ) ),\n        Vector4( vec_sel( column, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), _VECTORMATH_MASK_0x000F ) )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, boolInVec select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix4 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n    print( mat.getRow( 3 ) );\n}\n\ninline void print( const Matrix4 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Transform3::Transform3( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n}\n\ninline Transform3::Transform3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( floatInVec scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( Vector3 _col0, Vector3 _col1, Vector3 _col2, Vector3 _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Transform3::Transform3( const Matrix3 & tfrm, Vector3 translateVec )\n{\n    this->setUpper3x3( tfrm );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( Quat unitQuat, Vector3 translateVec )\n{\n    this->setUpper3x3( Matrix3( unitQuat ) );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3 & Transform3::setCol0( Vector3 _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol1( Vector3 _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol2( Vector3 _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol3( Vector3 _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol( int col, Vector3 vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Transform3 & Transform3::setRow( int row, Vector4 vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, floatInVec val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline const floatInVec Transform3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Transform3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Transform3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Transform3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Transform3::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector3 Transform3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Transform3::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector3 & Transform3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Transform3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Transform3 & Transform3::operator =( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n    return *this;\n}\n\ninline const Transform3 inverse( const Transform3 & tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() );\n    tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() );\n    tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() );\n    inv3 = negatef4( tfrm.getCol3().get128() );\n    dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() );\n    dot = vec_splat( dot, 0 );\n    invdet = recipf4( dot );\n    tmp3 = vec_mergeh( tmp0, tmp2 );\n    tmp4 = vec_mergel( tmp0, tmp2 );\n    inv0 = vec_mergeh( tmp3, tmp1 );\n    xxxx = vec_splat( inv3, 0 );\n    inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX );\n    inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX );\n    yyyy = vec_splat( inv3, 1 );\n    zzzz = vec_splat( inv3, 2 );\n    inv3 = vec_madd( inv0, xxxx, zero );\n    inv3 = vec_madd( inv1, yyyy, inv3 );\n    inv3 = vec_madd( inv2, zzzz, inv3 );\n    inv0 = vec_madd( inv0, invdet, zero );\n    inv1 = vec_madd( inv1, invdet, zero );\n    inv2 = vec_madd( inv2, invdet, zero );\n    inv3 = vec_madd( inv3, invdet, zero );\n    return Transform3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 ),\n        Vector3( inv3 )\n    );\n}\n\ninline const Transform3 orthoInverse( const Transform3 & tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1;\n    vec_float4 xxxx, yyyy, zzzz;\n    tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() );\n    tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() );\n    inv3 = negatef4( tfrm.getCol3().get128() );\n    inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() );\n    xxxx = vec_splat( inv3, 0 );\n    inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX );\n    inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX );\n    yyyy = vec_splat( inv3, 1 );\n    zzzz = vec_splat( inv3, 2 );\n    inv3 = vec_madd( inv0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    inv3 = vec_madd( inv1, yyyy, inv3 );\n    inv3 = vec_madd( inv2, zzzz, inv3 );\n    return Transform3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 ),\n        Vector3( inv3 )\n    );\n}\n\ninline const Transform3 absPerElem( const Transform3 & tfrm )\n{\n    return Transform3(\n        absPerElem( tfrm.getCol0() ),\n        absPerElem( tfrm.getCol1() ),\n        absPerElem( tfrm.getCol2() ),\n        absPerElem( tfrm.getCol3() )\n    );\n}\n\ninline const Vector3 Transform3::operator *( Vector3 vec ) const\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    xxxx = vec_splat( vec.get128(), 0 );\n    yyyy = vec_splat( vec.get128(), 1 );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_madd( mCol0.get128(), xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( mCol1.get128(), yyyy, res );\n    res = vec_madd( mCol2.get128(), zzzz, res );\n    return Vector3( res );\n}\n\ninline const Point3 Transform3::operator *( Point3 pnt ) const\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    xxxx = vec_splat( pnt.get128(), 0 );\n    yyyy = vec_splat( pnt.get128(), 1 );\n    zzzz = vec_splat( pnt.get128(), 2 );\n    tmp0 = vec_madd( mCol0.get128(), xxxx, zero );\n    tmp1 = vec_madd( mCol1.get128(), yyyy, zero );\n    tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = vec_add( mCol3.get128(), tmp1 );\n    res = vec_add( tmp0, tmp1 );\n    return Point3( res );\n}\n\ninline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const\n{\n    return Transform3(\n        ( *this * tfrm.mCol0 ),\n        ( *this * tfrm.mCol1 ),\n        ( *this * tfrm.mCol2 ),\n        Vector3( ( *this * Point3( tfrm.mCol3 ) ) )\n    );\n}\n\ninline Transform3 & Transform3::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 )\n{\n    return Transform3(\n        mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ),\n        mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ),\n        mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ),\n        mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() )\n    );\n}\n\ninline const Transform3 Transform3::identity( )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm )\n{\n    mCol0 = tfrm.getCol0();\n    mCol1 = tfrm.getCol1();\n    mCol2 = tfrm.getCol2();\n    return *this;\n}\n\ninline const Matrix3 Transform3::getUpper3x3( ) const\n{\n    return Matrix3( mCol0, mCol1, mCol2 );\n}\n\ninline Transform3 & Transform3::setTranslation( Vector3 translateVec )\n{\n    mCol3 = translateVec;\n    return *this;\n}\n\ninline const Vector3 Transform3::getTranslation( ) const\n{\n    return mCol3;\n}\n\ninline const Transform3 Transform3::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Transform3 Transform3::rotationX( floatInVec radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res1 = vec_sel( zero, c, select_y );\n    res1 = vec_sel( res1, s, select_z );\n    res2 = vec_sel( zero, negatef4(s), select_y );\n    res2 = vec_sel( res2, c, select_z );\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3( res1 ),\n        Vector3( res2 ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Transform3 Transform3::rotationY( floatInVec radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_z = _VECTORMATH_MASK_0x00F0;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, negatef4(s), select_z );\n    res2 = vec_sel( zero, s, select_x );\n    res2 = vec_sel( res2, c, select_z );\n    return Transform3(\n        Vector3( res0 ),\n        Vector3::yAxis( ),\n        Vector3( res2 ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Transform3 Transform3::rotationZ( floatInVec radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = _VECTORMATH_MASK_0xF000;\n    select_y = _VECTORMATH_MASK_0x0F00;\n    zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    sincosf4( radians.get128(), &s, &c );\n    res0 = vec_sel( zero, c, select_x );\n    res0 = vec_sel( res0, s, select_y );\n    res1 = vec_sel( zero, negatef4(s), select_x );\n    res1 = vec_sel( res1, c, select_y );\n    return Transform3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZYX( Vector3 radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    angles = Vector4( radiansXYZ, 0.0f ).get128();\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = vec_mergel( c, s );\n    Z1 = vec_mergel( negS, c );\n    Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F );\n    Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX );\n    Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX );\n    X0 = vec_splat( s, 0 );\n    X1 = vec_splat( c, 0 );\n    tmp = vec_madd( Z0, Y1, zero );\n    return Transform3(\n        Vector3( vec_madd( Z0, Y0, zero ) ),\n        Vector3( vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ) ),\n        Vector3( vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotation( float radians, Vector3 unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Transform3 Transform3::rotation( floatInVec radians, Vector3 unitVec )\n{\n    return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::rotation( Quat unitQuat )\n{\n    return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::scale( Vector3 scaleVec )\n{\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n    return Transform3(\n        Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0xF000 ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x0F00 ) ),\n        Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x00F0 ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec )\n{\n    return Transform3(\n        ( tfrm.getCol0() * scaleVec.getX( ) ),\n        ( tfrm.getCol1() * scaleVec.getY( ) ),\n        ( tfrm.getCol2() * scaleVec.getZ( ) ),\n        tfrm.getCol3()\n    );\n}\n\ninline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm )\n{\n    return Transform3(\n        mulPerElem( tfrm.getCol0(), scaleVec ),\n        mulPerElem( tfrm.getCol1(), scaleVec ),\n        mulPerElem( tfrm.getCol2(), scaleVec ),\n        mulPerElem( tfrm.getCol3(), scaleVec )\n    );\n}\n\ninline const Transform3 Transform3::translation( Vector3 translateVec )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        translateVec\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, boolInVec select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Transform3 & tfrm )\n{\n    print( tfrm.getRow( 0 ) );\n    print( tfrm.getRow( 1 ) );\n    print( tfrm.getRow( 2 ) );\n}\n\ninline void print( const Transform3 & tfrm, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( tfrm );\n}\n\n#endif\n\ninline Quat::Quat( const Matrix3 & tfrm )\n{\n    vec_float4 res;\n    vec_float4 col0, col1, col2;\n    vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff;\n    vec_float4 zy_xz_yx, yz_zx_xy, sum, diff;\n    vec_float4 radicand, invSqrt, scale;\n    vec_float4 res0, res1, res2, res3;\n    vec_float4 xx, yy, zz;\n    vec_uint4 select_x = _VECTORMATH_MASK_0xF000;\n    vec_uint4 select_y = _VECTORMATH_MASK_0x0F00;\n    vec_uint4 select_z = _VECTORMATH_MASK_0x00F0;\n    vec_uint4 select_w = _VECTORMATH_MASK_0x000F;\n    vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n\n    col0 = tfrm.getCol0().get128();\n    col1 = tfrm.getCol1().get128();\n    col2 = tfrm.getCol2().get128();\n\n    /* four cases: */\n    /* trace > 0 */\n    /* else */\n    /*    xx largest diagonal element */\n    /*    yy largest diagonal element */\n    /*    zz largest diagonal element */\n\n    /* compute quaternion for each case */\n\n    xx_yy = vec_sel( col0, col1, select_y );\n    xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX );\n    yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY );\n    zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC );\n\n    diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    invSqrt = rsqrtf4( radicand );\n\n    zy_xz_yx = vec_sel( col0, col1, select_z );\n    zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX );\n    yz_zx_xy = vec_sel( col0, col1, select_x );\n    yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX );\n\n    sum = vec_add( zy_xz_yx, yz_zx_xy );\n    diff = vec_sub( zy_xz_yx, yz_zx_xy );\n\n    scale = vec_madd( invSqrt, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), zero );\n    res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA );\n    res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB );\n    res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC );\n    res3 = diff;\n    res0 = vec_sel( res0, radicand, select_x );\n    res1 = vec_sel( res1, radicand, select_y );\n    res2 = vec_sel( res2, radicand, select_z );\n    res3 = vec_sel( res3, radicand, select_w );\n    res0 = vec_madd( res0, vec_splat( scale, 0 ), zero );\n    res1 = vec_madd( res1, vec_splat( scale, 1 ), zero );\n    res2 = vec_madd( res2, vec_splat( scale, 2 ), zero );\n    res3 = vec_madd( res3, vec_splat( scale, 3 ), zero );\n\n    /* determine case and select answer */\n\n    xx = vec_splat( col0, 0 );\n    yy = vec_splat( col1, 1 );\n    zz = vec_splat( col2, 2 );\n    res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) );\n    res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) );\n    res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), zero ) );\n    mVec128 = res;\n}\n\ninline const Matrix3 outer( Vector3 tfrm0, Vector3 tfrm1 )\n{\n    return Matrix3(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) )\n    );\n}\n\ninline const Matrix4 outer( Vector4 tfrm0, Vector4 tfrm1 )\n{\n    return Matrix4(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) ),\n        ( tfrm0 * tfrm1.getW( ) )\n    );\n}\n\ninline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat )\n{\n    vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() );\n    tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() );\n    xxxx = vec_splat( vec.get128(), 0 );\n    mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() );\n    mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX );\n    mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX );\n    yyyy = vec_splat( vec.get128(), 1 );\n    res = vec_madd( mcol0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    zzzz = vec_splat( vec.get128(), 2 );\n    res = vec_madd( mcol1, yyyy, res );\n    res = vec_madd( mcol2, zzzz, res );\n    return Vector3( res );\n}\n\ninline const Matrix3 crossMatrix( Vector3 vec )\n{\n    vec_float4 neg, res0, res1, res2;\n    neg = negatef4( vec.get128() );\n    res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX );\n    res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX );\n    res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX );\n    res0 = vec_andc( res0, (vec_float4)_VECTORMATH_MASK_0xF000 );\n    res1 = vec_andc( res1, (vec_float4)_VECTORMATH_MASK_0x0F00 );\n    res2 = vec_andc( res2, (vec_float4)_VECTORMATH_MASK_0x00F0 );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat )\n{\n    return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) );\n}\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/mat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_SOA_CPP_H\n#define _VECTORMATH_MAT_SOA_CPP_H\n\nnamespace Vectormath {\nnamespace Soa {\n\n//-----------------------------------------------------------------------------\n// Constants\n\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\ninline Matrix3::Matrix3( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n}\n\ninline Matrix3::Matrix3( vec_float4 scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( const Quat & unitQuat )\n{\n    vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2;\n    qx = unitQuat.getX();\n    qy = unitQuat.getY();\n    qz = unitQuat.getZ();\n    qw = unitQuat.getW();\n    qx2 = vec_add( qx, qx );\n    qy2 = vec_add( qy, qy );\n    qz2 = vec_add( qz, qz );\n    qxqx2 = vec_madd( qx, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qxqy2 = vec_madd( qx, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qxqz2 = vec_madd( qx, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qxqw2 = vec_madd( qw, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qyqy2 = vec_madd( qy, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qyqz2 = vec_madd( qy, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qyqw2 = vec_madd( qw, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qzqz2 = vec_madd( qz, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qzqw2 = vec_madd( qw, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol0 = Vector3( vec_sub( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), qyqy2 ), qzqz2 ), vec_add( qxqy2, qzqw2 ), vec_sub( qxqz2, qyqw2 ) );\n    mCol1 = Vector3( vec_sub( qxqy2, qzqw2 ), vec_sub( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), qxqx2 ), qzqz2 ), vec_add( qyqz2, qxqw2 ) );\n    mCol2 = Vector3( vec_add( qxqz2, qyqw2 ), vec_sub( qyqz2, qxqw2 ), vec_sub( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), qxqx2 ), qyqy2 ) );\n}\n\ninline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n}\n\ninline Matrix3::Matrix3( const Aos::Matrix3 & mat )\n{\n    mCol0 = Vector3( mat.getCol0() );\n    mCol1 = Vector3( mat.getCol1() );\n    mCol2 = Vector3( mat.getCol2() );\n}\n\ninline Matrix3::Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 )\n{\n    mCol0 = Vector3( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() );\n    mCol1 = Vector3( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() );\n    mCol2 = Vector3( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() );\n}\n\ninline void Matrix3::get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const\n{\n    Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol0( tmpV3_0 );\n    result1.setCol0( tmpV3_1 );\n    result2.setCol0( tmpV3_2 );\n    result3.setCol0( tmpV3_3 );\n    mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol1( tmpV3_0 );\n    result1.setCol1( tmpV3_1 );\n    result2.setCol1( tmpV3_2 );\n    result3.setCol1( tmpV3_3 );\n    mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol2( tmpV3_0 );\n    result1.setCol2( tmpV3_1 );\n    result2.setCol2( tmpV3_2 );\n    result3.setCol2( tmpV3_3 );\n}\n\ninline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, vec_float4 val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline vec_float4 Matrix3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Matrix3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Matrix3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Matrix3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Matrix3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::getRow( int row ) const\n{\n    return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) );\n}\n\ninline Vector3 & Matrix3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix3 & Matrix3::operator =( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    return *this;\n}\n\ninline const Matrix3 transpose( const Matrix3 & mat )\n{\n    return Matrix3(\n        Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ),\n        Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ),\n        Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() )\n    );\n}\n\ninline const Matrix3 inverse( const Matrix3 & mat )\n{\n    Vector3 tmp0, tmp1, tmp2;\n    vec_float4 detinv;\n    tmp0 = cross( mat.getCol1(), mat.getCol2() );\n    tmp1 = cross( mat.getCol2(), mat.getCol0() );\n    tmp2 = cross( mat.getCol0(), mat.getCol1() );\n    detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), dot( mat.getCol2(), tmp2 ) );\n    return Matrix3(\n        Vector3( vec_madd( tmp0.getX(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.getX(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.getX(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        Vector3( vec_madd( tmp0.getY(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.getY(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.getY(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        Vector3( vec_madd( tmp0.getZ(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.getZ(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.getZ(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline vec_float4 determinant( const Matrix3 & mat )\n{\n    return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) );\n}\n\ninline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 )\n    );\n}\n\ninline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator +=( const Matrix3 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::operator -=( const Matrix3 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix3 Matrix3::operator -( ) const\n{\n    return Matrix3(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 )\n    );\n}\n\ninline const Matrix3 absPerElem( const Matrix3 & mat )\n{\n    return Matrix3(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( vec_float4 scalar ) const\n{\n    return Matrix3(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector3 Matrix3::operator *( const Vector3 & vec ) const\n{\n    return Vector3(\n        vec_add( vec_add( vec_madd( mCol0.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getX(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getX(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getY(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getY(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getZ(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getZ(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( const Matrix3 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 )\n{\n    return Matrix3(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::identity( )\n{\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix3(\n        Vector3( c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) ),\n        Vector3::yAxis( ),\n        Vector3( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix3(\n        Vector3( c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3( negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ.getX(), &sX, &cX );\n    sincosf4( radiansXYZ.getY(), &sY, &cY );\n    sincosf4( radiansXYZ.getZ(), &sZ, &cZ );\n    tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    return Matrix3(\n        Vector3( vec_madd( cZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), negatef4( sY ) ),\n        Vector3( vec_sub( vec_madd( tmp0, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( tmp1, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        Vector3( vec_add( vec_madd( tmp0, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( tmp1, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec.getX();\n    y = unitVec.getY();\n    z = unitVec.getZ();\n    xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    return Matrix3(\n        Vector3( vec_add( vec_madd( vec_madd( x, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) ),\n        Vector3( vec_sub( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( y, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) ),\n        Vector3( vec_add( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( z, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( const Quat & unitQuat )\n{\n    return Matrix3( unitQuat );\n}\n\ninline const Matrix3 Matrix3::scale( const Vector3 & scaleVec )\n{\n    return Matrix3(\n        Vector3( scaleVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getZ() )\n    );\n}\n\ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec )\n{\n    return Matrix3(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) )\n    );\n}\n\ninline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat )\n{\n    return Matrix3(\n        mulPerElem( mat.getCol0(), scaleVec ),\n        mulPerElem( mat.getCol1(), scaleVec ),\n        mulPerElem( mat.getCol2(), scaleVec )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix3 & mat )\n{\n    Aos::Matrix3 mat0, mat1, mat2, mat3;\n    mat.get4Aos( mat0, mat1, mat2, mat3 );\n    printf(\"slot 0:\\n\");\n    print( mat0 );\n    printf(\"slot 1:\\n\");\n    print( mat1 );\n    printf(\"slot 2:\\n\");\n    print( mat2 );\n    printf(\"slot 3:\\n\");\n    print( mat3 );\n}\n\ninline void print( const Matrix3 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Matrix4::Matrix4( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n}\n\ninline Matrix4::Matrix4( vec_float4 scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const Transform3 & mat )\n{\n    mCol0 = Vector4( mat.getCol0(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol1 = Vector4( mat.getCol1(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol2 = Vector4( mat.getCol2(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol3 = Vector4( mat.getCol3(), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\ninline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec )\n{\n    mCol0 = Vector4( mat.getCol0(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol1 = Vector4( mat.getCol1(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol2 = Vector4( mat.getCol2(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol3 = Vector4( translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\ninline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec )\n{\n    Matrix3 mat;\n    mat = Matrix3( unitQuat );\n    mCol0 = Vector4( mat.getCol0(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol1 = Vector4( mat.getCol1(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol2 = Vector4( mat.getCol2(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    mCol3 = Vector4( translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\ninline Matrix4::Matrix4( const Aos::Matrix4 & mat )\n{\n    mCol0 = Vector4( mat.getCol0() );\n    mCol1 = Vector4( mat.getCol1() );\n    mCol2 = Vector4( mat.getCol2() );\n    mCol3 = Vector4( mat.getCol3() );\n}\n\ninline Matrix4::Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 )\n{\n    mCol0 = Vector4( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() );\n    mCol1 = Vector4( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() );\n    mCol2 = Vector4( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() );\n    mCol3 = Vector4( mat0.getCol3(), mat1.getCol3(), mat2.getCol3(), mat3.getCol3() );\n}\n\ninline void Matrix4::get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const\n{\n    Aos::Vector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    mCol0.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol0( tmpV4_0 );\n    result1.setCol0( tmpV4_1 );\n    result2.setCol0( tmpV4_2 );\n    result3.setCol0( tmpV4_3 );\n    mCol1.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol1( tmpV4_0 );\n    result1.setCol1( tmpV4_1 );\n    result2.setCol1( tmpV4_2 );\n    result3.setCol1( tmpV4_3 );\n    mCol2.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol2( tmpV4_0 );\n    result1.setCol2( tmpV4_1 );\n    result2.setCol2( tmpV4_2 );\n    result3.setCol2( tmpV4_3 );\n    mCol3.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol3( tmpV4_0 );\n    result1.setCol3( tmpV4_1 );\n    result2.setCol3( tmpV4_2 );\n    result3.setCol3( tmpV4_3 );\n}\n\ninline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, vec_float4 val )\n{\n    Vector4 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline vec_float4 Matrix4::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector4 Matrix4::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector4 Matrix4::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector4 Matrix4::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector4 Matrix4::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector4 Matrix4::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector4 & Matrix4::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix4 & Matrix4::operator =( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n    return *this;\n}\n\ninline const Matrix4 transpose( const Matrix4 & mat )\n{\n    return Matrix4(\n        Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ),\n        Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ),\n        Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ),\n        Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() )\n    );\n}\n\ninline const Matrix4 inverse( const Matrix4 & mat )\n{\n    Vector4 res0, res1, res2, res3;\n    vec_float4 mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv;\n    mA = mat.getCol0().getX();\n    mB = mat.getCol0().getY();\n    mC = mat.getCol0().getZ();\n    mD = mat.getCol0().getW();\n    mE = mat.getCol1().getX();\n    mF = mat.getCol1().getY();\n    mG = mat.getCol1().getZ();\n    mH = mat.getCol1().getW();\n    mI = mat.getCol2().getX();\n    mJ = mat.getCol2().getY();\n    mK = mat.getCol2().getZ();\n    mL = mat.getCol2().getW();\n    mM = mat.getCol3().getX();\n    mN = mat.getCol3().getY();\n    mO = mat.getCol3().getZ();\n    mP = mat.getCol3().getW();\n    tmp0 = vec_sub( vec_madd( mK, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp1 = vec_sub( vec_madd( mO, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp2 = vec_sub( vec_madd( mB, mK, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mJ, mC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp3 = vec_sub( vec_madd( mF, mO, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mN, mG, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp4 = vec_sub( vec_madd( mJ, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mB, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp5 = vec_sub( vec_madd( mN, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mF, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res0.setX( vec_sub( vec_sub( vec_madd( mJ, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mL, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mK, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    res0.setY( vec_sub( vec_sub( vec_madd( mN, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mP, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mO, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    res0.setZ( vec_sub( vec_add( vec_madd( mD, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mB, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    res0.setW( vec_sub( vec_add( vec_madd( mH, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mF, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    detInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_add( vec_add( vec_add( vec_madd( mA, res0.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, res0.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mI, res0.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mM, res0.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    res1.setX( vec_madd( mI, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res1.setY( vec_madd( mM, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res1.setZ( vec_madd( mA, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res1.setW( vec_madd( mE, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res3.setX( vec_madd( mI, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res3.setY( vec_madd( mM, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res3.setZ( vec_madd( mA, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res3.setW( vec_madd( mE, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res2.setX( vec_madd( mI, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res2.setY( vec_madd( mM, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res2.setZ( vec_madd( mA, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res2.setW( vec_madd( mE, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp0 = vec_sub( vec_madd( mI, mB, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mA, mJ, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp1 = vec_sub( vec_madd( mM, mF, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, mN, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp2 = vec_sub( vec_madd( mI, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mA, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp3 = vec_sub( vec_madd( mM, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp4 = vec_sub( vec_madd( mI, mC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mA, mK, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp5 = vec_sub( vec_madd( mM, mG, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, mO, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    res2.setX( vec_add( vec_sub( vec_madd( mL, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mJ, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.getX() ) );\n    res2.setY( vec_add( vec_sub( vec_madd( mP, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mN, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.getY() ) );\n    res2.setZ( vec_sub( vec_sub( vec_madd( mB, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mD, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.getZ() ) );\n    res2.setW( vec_sub( vec_sub( vec_madd( mF, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mH, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res2.getW() ) );\n    res3.setX( vec_add( vec_sub( vec_madd( mJ, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mK, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.getX() ) );\n    res3.setY( vec_add( vec_sub( vec_madd( mN, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mO, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.getY() ) );\n    res3.setZ( vec_sub( vec_sub( vec_madd( mC, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mB, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.getZ() ) );\n    res3.setW( vec_sub( vec_sub( vec_madd( mG, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mF, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res3.getW() ) );\n    res1.setX( vec_sub( vec_sub( vec_madd( mK, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mL, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.getX() ) );\n    res1.setY( vec_sub( vec_sub( vec_madd( mO, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mP, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.getY() ) );\n    res1.setZ( vec_add( vec_sub( vec_madd( mD, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.getZ() ) );\n    res1.setW( vec_add( vec_sub( vec_madd( mH, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), res1.getW() ) );\n    return Matrix4(\n        ( res0 * detInv ),\n        ( res1 * detInv ),\n        ( res2 * detInv ),\n        ( res3 * detInv )\n    );\n}\n\ninline const Matrix4 affineInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( inverse( affineMat ) );\n}\n\ninline const Matrix4 orthoInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( orthoInverse( affineMat ) );\n}\n\ninline vec_float4 determinant( const Matrix4 & mat )\n{\n    vec_float4 dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    mA = mat.getCol0().getX();\n    mB = mat.getCol0().getY();\n    mC = mat.getCol0().getZ();\n    mD = mat.getCol0().getW();\n    mE = mat.getCol1().getX();\n    mF = mat.getCol1().getY();\n    mG = mat.getCol1().getZ();\n    mH = mat.getCol1().getW();\n    mI = mat.getCol2().getX();\n    mJ = mat.getCol2().getY();\n    mK = mat.getCol2().getZ();\n    mL = mat.getCol2().getW();\n    mM = mat.getCol3().getX();\n    mN = mat.getCol3().getY();\n    mO = mat.getCol3().getZ();\n    mP = mat.getCol3().getW();\n    tmp0 = vec_sub( vec_madd( mK, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp1 = vec_sub( vec_madd( mO, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp2 = vec_sub( vec_madd( mB, mK, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mJ, mC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp3 = vec_sub( vec_madd( mF, mO, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mN, mG, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp4 = vec_sub( vec_madd( mJ, mD, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mB, mL, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmp5 = vec_sub( vec_madd( mN, mH, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mF, mP, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dx = vec_sub( vec_sub( vec_madd( mJ, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mL, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mK, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dy = vec_sub( vec_sub( vec_madd( mN, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mP, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mO, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dz = vec_sub( vec_add( vec_madd( mD, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mC, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mB, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    dw = vec_sub( vec_add( vec_madd( mH, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mG, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mF, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return vec_add( vec_add( vec_add( vec_madd( mA, dx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mE, dy, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mI, dz, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mM, dw, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 ),\n        ( mCol3 + mat.mCol3 )\n    );\n}\n\ninline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 ),\n        ( mCol3 - mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator +=( const Matrix4 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::operator -=( const Matrix4 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator -( ) const\n{\n    return Matrix4(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 ),\n        ( -mCol3 )\n    );\n}\n\ninline const Matrix4 absPerElem( const Matrix4 & mat )\n{\n    return Matrix4(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() ),\n        absPerElem( mat.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( vec_float4 scalar ) const\n{\n    return Matrix4(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar ),\n        ( mCol3 * scalar )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector4 Matrix4::operator *( const Vector4 & vec ) const\n{\n    return Vector4(\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getX(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getX(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol3.getX(), vec.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getY(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getY(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol3.getY(), vec.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getZ(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getZ(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol3.getZ(), vec.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getW(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getW(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getW(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol3.getW(), vec.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Vector4 Matrix4::operator *( const Vector3 & vec ) const\n{\n    return Vector4(\n        vec_add( vec_add( vec_madd( mCol0.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getX(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getX(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getY(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getY(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getZ(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getZ(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getW(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getW(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getW(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Vector4 Matrix4::operator *( const Point3 & pnt ) const\n{\n    return Vector4(\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getX(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getX(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getX(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getX() ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getY(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getY(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getY(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getY() ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getZ(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getZ(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getZ(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getZ() ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getW(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getW(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getW(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getW() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 ),\n        ( *this * mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Matrix4 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const\n{\n    return Matrix4(\n        ( *this * tfrm.getCol0() ),\n        ( *this * tfrm.getCol1() ),\n        ( *this * tfrm.getCol2() ),\n        ( *this * Point3( tfrm.getCol3() ) )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 )\n{\n    return Matrix4(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() ),\n        mulPerElem( mat0.getCol3(), mat1.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::identity( )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 )\n{\n    mCol0.setXYZ( mat3.getCol0() );\n    mCol1.setXYZ( mat3.getCol1() );\n    mCol2.setXYZ( mat3.getCol2() );\n    return *this;\n}\n\ninline const Matrix3 Matrix4::getUpper3x3( ) const\n{\n    return Matrix3(\n        mCol0.getXYZ( ),\n        mCol1.getXYZ( ),\n        mCol2.getXYZ( )\n    );\n}\n\ninline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec )\n{\n    mCol3.setXYZ( translateVec );\n    return *this;\n}\n\ninline const Vector3 Matrix4::getTranslation( ) const\n{\n    return mCol3.getXYZ( );\n}\n\ninline const Matrix4 Matrix4::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix4(\n        Vector4( c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::yAxis( ),\n        Vector4( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix4(\n        Vector4( c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ.getX(), &sX, &cX );\n    sincosf4( radiansXYZ.getY(), &sY, &cY );\n    sincosf4( radiansXYZ.getZ(), &sZ, &cZ );\n    tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    return Matrix4(\n        Vector4( vec_madd( cZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), negatef4( sY ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( vec_sub( vec_madd( tmp0, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( tmp1, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( vec_add( vec_madd( tmp0, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( tmp1, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec.getX();\n    y = unitVec.getY();\n    z = unitVec.getZ();\n    xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c );\n    return Matrix4(\n        Vector4( vec_add( vec_madd( vec_madd( x, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( vec_sub( vec_madd( xy, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( z, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( y, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), vec_add( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( vec_add( vec_madd( zx, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( y, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( yz, oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( x, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( vec_madd( z, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), oneMinusC, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( const Quat & unitQuat )\n{\n    return Matrix4( Transform3::rotation( unitQuat ) );\n}\n\ninline const Matrix4 Matrix4::scale( const Vector3 & scaleVec )\n{\n    return Matrix4(\n        Vector4( scaleVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec )\n{\n    return Matrix4(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) ),\n        mat.getCol3()\n    );\n}\n\ninline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat )\n{\n    Vector4 scale4;\n    scale4 = Vector4( scaleVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    return Matrix4(\n        mulPerElem( mat.getCol0(), scale4 ),\n        mulPerElem( mat.getCol1(), scale4 ),\n        mulPerElem( mat.getCol2(), scale4 ),\n        mulPerElem( mat.getCol3(), scale4 )\n    );\n}\n\ninline const Matrix4 Matrix4::translation( const Vector3 & translateVec )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4( translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) )\n    );\n}\n\ninline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec )\n{\n    Matrix4 m4EyeFrame;\n    Vector3 v3X, v3Y, v3Z;\n    v3Y = normalize( upVec );\n    v3Z = normalize( ( eyePos - lookAtPos ) );\n    v3X = normalize( cross( v3Y, v3Z ) );\n    v3Y = cross( v3Z, v3X );\n    m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) );\n    return orthoInverse( m4EyeFrame );\n}\n\ninline const Matrix4 Matrix4::perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 f, rangeInv;\n    f = tanf4( vec_sub( ((vec_float4){_VECTORMATH_PI_OVER_2,_VECTORMATH_PI_OVER_2,_VECTORMATH_PI_OVER_2,_VECTORMATH_PI_OVER_2}), vec_madd( ((vec_float4){0.5f,0.5f,0.5f,0.5f}), fovyRadians, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n    rangeInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) );\n    return Matrix4(\n        Vector4( divf4( f, aspect ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), f, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( vec_add( zNear, zFar ), rangeInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( vec_madd( vec_madd( zNear, zFar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), rangeInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){2.0f,2.0f,2.0f,2.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Matrix4 Matrix4::frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2;\n    sum_rl = vec_add( right, left );\n    sum_tb = vec_add( top, bottom );\n    sum_nf = vec_add( zNear, zFar );\n    inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) );\n    inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) );\n    inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) );\n    n2 = vec_add( zNear, zNear );\n    return Matrix4(\n        Vector4( vec_madd( n2, inv_rl, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( n2, inv_tb, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( vec_madd( sum_rl, inv_rl, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sum_tb, inv_tb, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sum_nf, inv_nf, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_madd( vec_madd( n2, inv_nf, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), zFar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Matrix4 Matrix4::orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf;\n    sum_rl = vec_add( right, left );\n    sum_tb = vec_add( top, bottom );\n    sum_nf = vec_add( zNear, zFar );\n    inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) );\n    inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) );\n    inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) );\n    return Matrix4(\n        Vector4( vec_add( inv_rl, inv_rl ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_add( inv_tb, inv_tb ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec_add( inv_nf, inv_nf ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector4( vec_madd( negatef4( sum_rl ), inv_rl, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( negatef4( sum_tb ), inv_tb, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sum_nf, inv_nf, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix4 & mat )\n{\n    Aos::Matrix4 mat0, mat1, mat2, mat3;\n    mat.get4Aos( mat0, mat1, mat2, mat3 );\n    printf(\"slot 0:\\n\");\n    print( mat0 );\n    printf(\"slot 1:\\n\");\n    print( mat1 );\n    printf(\"slot 2:\\n\");\n    print( mat2 );\n    printf(\"slot 3:\\n\");\n    print( mat3 );\n}\n\ninline void print( const Matrix4 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Transform3::Transform3( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n}\n\ninline Transform3::Transform3( vec_float4 scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec )\n{\n    this->setUpper3x3( tfrm );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec )\n{\n    this->setUpper3x3( Matrix3( unitQuat ) );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( const Aos::Transform3 & tfrm )\n{\n    mCol0 = Vector3( tfrm.getCol0() );\n    mCol1 = Vector3( tfrm.getCol1() );\n    mCol2 = Vector3( tfrm.getCol2() );\n    mCol3 = Vector3( tfrm.getCol3() );\n}\n\ninline Transform3::Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 )\n{\n    mCol0 = Vector3( tfrm0.getCol0(), tfrm1.getCol0(), tfrm2.getCol0(), tfrm3.getCol0() );\n    mCol1 = Vector3( tfrm0.getCol1(), tfrm1.getCol1(), tfrm2.getCol1(), tfrm3.getCol1() );\n    mCol2 = Vector3( tfrm0.getCol2(), tfrm1.getCol2(), tfrm2.getCol2(), tfrm3.getCol2() );\n    mCol3 = Vector3( tfrm0.getCol3(), tfrm1.getCol3(), tfrm2.getCol3(), tfrm3.getCol3() );\n}\n\ninline void Transform3::get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const\n{\n    Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol0( tmpV3_0 );\n    result1.setCol0( tmpV3_1 );\n    result2.setCol0( tmpV3_2 );\n    result3.setCol0( tmpV3_3 );\n    mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol1( tmpV3_0 );\n    result1.setCol1( tmpV3_1 );\n    result2.setCol1( tmpV3_2 );\n    result3.setCol1( tmpV3_3 );\n    mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol2( tmpV3_0 );\n    result1.setCol2( tmpV3_1 );\n    result2.setCol2( tmpV3_2 );\n    result3.setCol2( tmpV3_3 );\n    mCol3.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol3( tmpV3_0 );\n    result1.setCol3( tmpV3_1 );\n    result2.setCol3( tmpV3_2 );\n    result3.setCol3( tmpV3_3 );\n}\n\ninline Transform3 & Transform3::setCol0( const Vector3 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol1( const Vector3 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol2( const Vector3 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol3( const Vector3 & _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol( int col, const Vector3 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Transform3 & Transform3::setRow( int row, const Vector4 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, vec_float4 val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline vec_float4 Transform3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Transform3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Transform3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Transform3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Transform3::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector3 Transform3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Transform3::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector3 & Transform3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Transform3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Transform3 & Transform3::operator =( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n    return *this;\n}\n\ninline const Transform3 inverse( const Transform3 & tfrm )\n{\n    Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2;\n    vec_float4 detinv;\n    tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() );\n    tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() );\n    tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() );\n    detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), dot( tfrm.getCol2(), tmp2 ) );\n    inv0 = Vector3( vec_madd( tmp0.getX(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.getX(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.getX(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    inv1 = Vector3( vec_madd( tmp0.getY(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.getY(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.getY(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    inv2 = Vector3( vec_madd( tmp0.getZ(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp1.getZ(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmp2.getZ(), detinv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return Transform3(\n        inv0,\n        inv1,\n        inv2,\n        Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) )\n    );\n}\n\ninline const Transform3 orthoInverse( const Transform3 & tfrm )\n{\n    Vector3 inv0, inv1, inv2;\n    inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() );\n    inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() );\n    inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() );\n    return Transform3(\n        inv0,\n        inv1,\n        inv2,\n        Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) )\n    );\n}\n\ninline const Transform3 absPerElem( const Transform3 & tfrm )\n{\n    return Transform3(\n        absPerElem( tfrm.getCol0() ),\n        absPerElem( tfrm.getCol1() ),\n        absPerElem( tfrm.getCol2() ),\n        absPerElem( tfrm.getCol3() )\n    );\n}\n\ninline const Vector3 Transform3::operator *( const Vector3 & vec ) const\n{\n    return Vector3(\n        vec_add( vec_add( vec_madd( mCol0.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getX(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getX(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getY(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getY(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( mCol0.getZ(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getZ(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Point3 Transform3::operator *( const Point3 & pnt ) const\n{\n    return Point3(\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getX(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getX(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getX(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getX() ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getY(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getY(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getY(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getY() ),\n        vec_add( vec_add( vec_add( vec_madd( mCol0.getZ(), pnt.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mCol1.getZ(), pnt.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mCol2.getZ(), pnt.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), mCol3.getZ() )\n    );\n}\n\ninline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const\n{\n    return Transform3(\n        ( *this * tfrm.mCol0 ),\n        ( *this * tfrm.mCol1 ),\n        ( *this * tfrm.mCol2 ),\n        Vector3( ( *this * Point3( tfrm.mCol3 ) ) )\n    );\n}\n\ninline Transform3 & Transform3::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 )\n{\n    return Transform3(\n        mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ),\n        mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ),\n        mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ),\n        mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() )\n    );\n}\n\ninline const Transform3 Transform3::identity( )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm )\n{\n    mCol0 = tfrm.getCol0();\n    mCol1 = tfrm.getCol1();\n    mCol2 = tfrm.getCol2();\n    return *this;\n}\n\ninline const Matrix3 Transform3::getUpper3x3( ) const\n{\n    return Matrix3( mCol0, mCol1, mCol2 );\n}\n\ninline Transform3 & Transform3::setTranslation( const Vector3 & translateVec )\n{\n    mCol3 = translateVec;\n    return *this;\n}\n\ninline const Vector3 Transform3::getTranslation( ) const\n{\n    return mCol3;\n}\n\ninline const Transform3 Transform3::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Transform3 Transform3::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Transform3(\n        Vector3( c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) ),\n        Vector3::yAxis( ),\n        Vector3( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Transform3 Transform3::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Transform3(\n        Vector3( c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3( negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3::zAxis( ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ.getX(), &sX, &cX );\n    sincosf4( radiansXYZ.getY(), &sY, &cY );\n    sincosf4( radiansXYZ.getZ(), &sZ, &cZ );\n    tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    return Transform3(\n        Vector3( vec_madd( cZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), negatef4( sY ) ),\n        Vector3( vec_sub( vec_madd( tmp0, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_add( vec_madd( tmp1, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        Vector3( vec_add( vec_madd( tmp0, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( sZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_sub( vec_madd( tmp1, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( cZ, sX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( cY, cX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Transform3 Transform3::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Transform3 Transform3::rotation( const Quat & unitQuat )\n{\n    return Transform3( Matrix3( unitQuat ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Transform3 Transform3::scale( const Vector3 & scaleVec )\n{\n    return Transform3(\n        Vector3( scaleVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getZ() ),\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec )\n{\n    return Transform3(\n        ( tfrm.getCol0() * scaleVec.getX( ) ),\n        ( tfrm.getCol1() * scaleVec.getY( ) ),\n        ( tfrm.getCol2() * scaleVec.getZ( ) ),\n        tfrm.getCol3()\n    );\n}\n\ninline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm )\n{\n    return Transform3(\n        mulPerElem( tfrm.getCol0(), scaleVec ),\n        mulPerElem( tfrm.getCol1(), scaleVec ),\n        mulPerElem( tfrm.getCol2(), scaleVec ),\n        mulPerElem( tfrm.getCol3(), scaleVec )\n    );\n}\n\ninline const Transform3 Transform3::translation( const Vector3 & translateVec )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        translateVec\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Transform3 & tfrm )\n{\n    Aos::Transform3 mat0, mat1, mat2, mat3;\n    tfrm.get4Aos( mat0, mat1, mat2, mat3 );\n    printf(\"slot 0:\\n\");\n    print( mat0 );\n    printf(\"slot 1:\\n\");\n    print( mat1 );\n    printf(\"slot 2:\\n\");\n    print( mat2 );\n    printf(\"slot 3:\\n\");\n    print( mat3 );\n}\n\ninline void print( const Transform3 & tfrm, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( tfrm );\n}\n\n#endif\n\ninline Quat::Quat( const Matrix3 & tfrm )\n{\n    vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw;\n    vec_uint4 negTrace, ZgtX, ZgtY, YgtX;\n    vec_uint4 largestXorY, largestYorZ, largestZorX;\n\n    xx = tfrm.getCol0().getX();\n    yx = tfrm.getCol0().getY();\n    zx = tfrm.getCol0().getZ();\n    xy = tfrm.getCol1().getX();\n    yy = tfrm.getCol1().getY();\n    zy = tfrm.getCol1().getZ();\n    xz = tfrm.getCol2().getX();\n    yz = tfrm.getCol2().getY();\n    zz = tfrm.getCol2().getZ();\n\n    trace = vec_add( vec_add( xx, yy ), zz );\n\n    negTrace = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), trace );\n    ZgtX = (vec_uint4)vec_cmpgt( zz, xx );\n    ZgtY = (vec_uint4)vec_cmpgt( zz, yy );\n    YgtX = (vec_uint4)vec_cmpgt( yy, xx );\n    largestXorY = vec_andc( negTrace, vec_and( ZgtX, ZgtY ) );\n    largestYorZ = vec_and( negTrace, vec_or( YgtX, ZgtX ) );\n    largestZorX = vec_andc( negTrace, vec_andc( YgtX, ZgtY ) );\n    \n    zz = vec_sel( zz, negatef4(zz), largestXorY );\n    xy = vec_sel( xy, negatef4(xy), largestXorY );\n    xx = vec_sel( xx, negatef4(xx), largestYorZ );\n    yz = vec_sel( yz, negatef4(yz), largestYorZ );\n    yy = vec_sel( yy, negatef4(yy), largestZorX );\n    zx = vec_sel( zx, negatef4(zx), largestZorX );\n\n    radicand = vec_add( vec_add( vec_add( xx, yy ), zz ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n    scale = vec_madd( ((vec_float4){0.5f,0.5f,0.5f,0.5f}), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( radicand ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n\n    tmpx = vec_madd( vec_sub( zy, yz ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmpy = vec_madd( vec_sub( xz, zx ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmpz = vec_madd( vec_sub( yx, xy ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    tmpw = vec_madd( radicand, scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qx = tmpx;\n    qy = tmpy;\n    qz = tmpz;\n    qw = tmpw;\n\n    qx = vec_sel( qx, tmpw, largestXorY );\n    qy = vec_sel( qy, tmpz, largestXorY );\n    qz = vec_sel( qz, tmpy, largestXorY );\n    qw = vec_sel( qw, tmpx, largestXorY );\n    tmpx = qx;\n    tmpz = qz;\n    qx = vec_sel( qx, qy, largestYorZ );\n    qy = vec_sel( qy, tmpx, largestYorZ );\n    qz = vec_sel( qz, qw, largestYorZ );\n    qw = vec_sel( qw, tmpz, largestYorZ );\n\n    mX = qx;\n    mY = qy;\n    mZ = qz;\n    mW = qw;\n}\n\ninline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 )\n{\n    return Matrix3(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) )\n    );\n}\n\ninline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 )\n{\n    return Matrix4(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) ),\n        ( tfrm0 * tfrm1.getW( ) )\n    );\n}\n\ninline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat )\n{\n    return Vector3(\n        vec_add( vec_add( vec_madd( vec.getX(), mat.getCol0().getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getY(), mat.getCol0().getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( vec.getZ(), mat.getCol0().getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( vec.getX(), mat.getCol1().getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getY(), mat.getCol1().getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( vec.getZ(), mat.getCol1().getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_add( vec_madd( vec.getX(), mat.getCol2().getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getY(), mat.getCol2().getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( vec.getZ(), mat.getCol2().getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Matrix3 crossMatrix( const Vector3 & vec )\n{\n    return Matrix3(\n        Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec.getZ(), negatef4( vec.getY() ) ),\n        Vector3( negatef4( vec.getZ() ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec.getX() ),\n        Vector3( vec.getY(), negatef4( vec.getX() ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat )\n{\n    return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) );\n}\n\n} // namespace Soa\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_CPP_H\n#define _VECTORMATH_QUAT_AOS_CPP_H\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\ninline Quat::Quat( float _x, float _y, float _z, float _w )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) &\n        __builtin_constant_p(_z) & __builtin_constant_p(_w)) {\n        mVec128 = (vec_float4){_x, _y, _z, _w};\n    } else {\n        float *pf = (float *)&mVec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n        pf[3] = _w;\n    }\n}\n\ninline Quat::Quat( floatInVec _x, floatInVec _y, floatInVec _z, floatInVec _w )\n{\n    vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() );\n    vec_float4 yw = vec_mergeh( _y.get128(), _w.get128() );\n    mVec128 = vec_mergeh( xz, yw );\n}\n\ninline Quat::Quat( Vector3 xyz, float _w )\n{\n    mVec128 = xyz.get128();\n    _vmathVfSetElement(mVec128, _w, 3);\n}\n\ninline Quat::Quat( Vector3 xyz, floatInVec _w )\n{\n    mVec128 = xyz.get128();\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n}\n\ninline Quat::Quat( Vector4 vec )\n{\n    mVec128 = vec.get128();\n}\n\ninline Quat::Quat( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Quat::Quat( floatInVec scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Quat::Quat( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Quat Quat::identity( )\n{\n    return Quat( _VECTORMATH_UNIT_0001 );\n}\n\ninline const Quat lerp( float t, Quat quat0, Quat quat1 )\n{\n    return lerp( floatInVec(t), quat0, quat1 );\n}\n\ninline const Quat lerp( floatInVec t, Quat quat0, Quat quat1 )\n{\n    return ( quat0 + ( ( quat1 - quat0 ) * t ) );\n}\n\ninline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 )\n{\n    return slerp( floatInVec(t), unitQuat0, unitQuat1 );\n}\n\ninline const Quat slerp( floatInVec t, Quat unitQuat0, Quat unitQuat1 )\n{\n    Quat start;\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() );\n    cosAngle = vec_splat( cosAngle, 0 );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), cosAngle );\n    cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = t.get128();\n    oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sines = sinf4( angles );\n    scales = divf4( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    return Quat( vec_madd( start.get128(), scale0, vec_madd( unitQuat1.get128(), scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n}\n\ninline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 )\n{\n    return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 );\n}\n\ninline const Quat squad( floatInVec t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 )\n{\n    Quat tmp0, tmp1;\n    tmp0 = slerp( t, unitQuat0, unitQuat3 );\n    tmp1 = slerp( t, unitQuat1, unitQuat2 );\n    return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), tmp0, tmp1 );\n}\n\ninline vec_float4 Quat::get128( ) const\n{\n    return mVec128;\n}\n\ninline Quat & Quat::operator =( Quat quat )\n{\n    mVec128 = quat.mVec128;\n    return *this;\n}\n\ninline Quat & Quat::setXYZ( Vector3 vec )\n{\n    mVec128 = vec_sel( vec.get128(), mVec128, _VECTORMATH_MASK_0x000F );\n    return *this;\n}\n\ninline const Vector3 Quat::getXYZ( ) const\n{\n    return Vector3( mVec128 );\n}\n\ninline Quat & Quat::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Quat & Quat::setX( floatInVec _x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Quat::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Quat & Quat::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Quat & Quat::setY( floatInVec _y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Quat::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Quat & Quat::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Quat & Quat::setZ( floatInVec _z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Quat::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Quat & Quat::setW( float _w )\n{\n    _vmathVfSetElement(mVec128, _w, 3);\n    return *this;\n}\n\ninline Quat & Quat::setW( floatInVec _w )\n{\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n    return *this;\n}\n\ninline const floatInVec Quat::getW( ) const\n{\n    return floatInVec( mVec128, 3 );\n}\n\ninline Quat & Quat::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Quat & Quat::setElem( int idx, floatInVec value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Quat::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Quat::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Quat::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Quat Quat::operator +( Quat quat ) const\n{\n    return Quat( vec_add( mVec128, quat.mVec128 ) );\n}\n\ninline const Quat Quat::operator -( Quat quat ) const\n{\n    return Quat( vec_sub( mVec128, quat.mVec128 ) );\n}\n\ninline const Quat Quat::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Quat Quat::operator *( floatInVec scalar ) const\n{\n    return Quat( vec_madd( mVec128, scalar.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline Quat & Quat::operator +=( Quat quat )\n{\n    *this = *this + quat;\n    return *this;\n}\n\ninline Quat & Quat::operator -=( Quat quat )\n{\n    *this = *this - quat;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( floatInVec scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator /( float scalar ) const\n{\n    return *this / floatInVec(scalar);\n}\n\ninline const Quat Quat::operator /( floatInVec scalar ) const\n{\n    return Quat( divf4( mVec128, scalar.get128() ) );\n}\n\ninline Quat & Quat::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline Quat & Quat::operator /=( floatInVec scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator -( ) const\n{\n    return Quat( negatef4( mVec128 ) );\n}\n\ninline const Quat operator *( float scalar, Quat quat )\n{\n    return floatInVec(scalar) * quat;\n}\n\ninline const Quat operator *( floatInVec scalar, Quat quat )\n{\n    return quat * scalar;\n}\n\ninline const floatInVec dot( Quat quat0, Quat quat1 )\n{\n    return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 );\n}\n\ninline const floatInVec norm( Quat quat )\n{\n    return floatInVec(  _vmathVfDot4( quat.get128(), quat.get128() ), 0 );\n}\n\ninline const floatInVec length( Quat quat )\n{\n    return floatInVec(  sqrtf4(_vmathVfDot4( quat.get128(), quat.get128() )), 0 );\n}\n\ninline const Quat normalize( Quat quat )\n{\n    vec_float4 dot = _vmathVfDot4( quat.get128(), quat.get128() );\n    return Quat( vec_madd( quat.get128(), rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Quat Quat::rotation( Vector3 unitVec0, Vector3 unitVec1 )\n{\n    Vector3 crossVec;\n    vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res;\n    cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() );\n    cosAngle = vec_splat( cosAngle, 0 );\n    cosAngleX2Plus2 = vec_madd( cosAngle, ((vec_float4){2.0f,2.0f,2.0f,2.0f}), ((vec_float4){2.0f,2.0f,2.0f,2.0f}) );\n    recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 );\n    cosHalfAngleX2 = vec_madd( recipCosHalfAngleX2, cosAngleX2Plus2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    crossVec = cross( unitVec0, unitVec1 );\n    res = vec_madd( crossVec.get128(), recipCosHalfAngleX2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_sel( res, vec_madd( cosHalfAngleX2, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), _VECTORMATH_MASK_0x000F );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotation( float radians, Vector3 unitVec )\n{\n    return rotation( floatInVec(radians), unitVec );\n}\n\ninline const Quat Quat::rotation( floatInVec radians, Vector3 unitVec )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( radians.get128(), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( vec_madd( unitVec.get128(), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c, _VECTORMATH_MASK_0x000F );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationX( float radians )\n{\n    return rotationX( floatInVec(radians) );\n}\n\ninline const Quat Quat::rotationX( floatInVec radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( radians.get128(), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0xF000 );\n    res = vec_sel( res, c, _VECTORMATH_MASK_0x000F );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationY( float radians )\n{\n    return rotationY( floatInVec(radians) );\n}\n\ninline const Quat Quat::rotationY( floatInVec radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( radians.get128(), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x0F00 );\n    res = vec_sel( res, c, _VECTORMATH_MASK_0x000F );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationZ( float radians )\n{\n    return rotationZ( floatInVec(radians) );\n}\n\ninline const Quat Quat::rotationZ( floatInVec radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = vec_madd( radians.get128(), ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x00F0 );\n    res = vec_sel( res, c, _VECTORMATH_MASK_0x000F );\n    return Quat( res );\n}\n\ninline const Quat Quat::operator *( Quat quat ) const\n{\n    vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;\n    vec_float4 product, l_wxyz, r_wxyz, xy, qw;\n    ldata = mVec128;\n    rdata = quat.mVec128;\n    tmp0 = vec_perm( ldata, ldata, _VECTORMATH_PERM_YZXW );\n    tmp1 = vec_perm( rdata, rdata, _VECTORMATH_PERM_ZXYW );\n    tmp2 = vec_perm( ldata, ldata, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( rdata, rdata, _VECTORMATH_PERM_YZXW );\n    qv = vec_madd( vec_splat( ldata, 3 ), rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv );\n    qv = vec_madd( tmp0, tmp1, qv );\n    qv = vec_nmsub( tmp2, tmp3, qv );\n    product = vec_madd( ldata, rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    l_wxyz = vec_sld( ldata, ldata, 12 );\n    r_wxyz = vec_sld( rdata, rdata, 12 );\n    qw = vec_nmsub( l_wxyz, r_wxyz, product );\n    xy = vec_madd( l_wxyz, r_wxyz, product );\n    qw = vec_sub( qw, vec_sld( xy, xy, 8 ) );\n    return Quat( vec_sel( qv, qw, _VECTORMATH_MASK_0x000F ) );\n}\n\ninline Quat & Quat::operator *=( Quat quat )\n{\n    *this = *this * quat;\n    return *this;\n}\n\ninline const Vector3 rotate( Quat quat, Vector3 vec )\n{\n    vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res;\n    qdata = quat.get128();\n    vdata = vec.get128();\n    tmp0 = vec_perm( qdata, qdata, _VECTORMATH_PERM_YZXW );\n    tmp1 = vec_perm( vdata, vdata, _VECTORMATH_PERM_ZXYW );\n    tmp2 = vec_perm( qdata, qdata, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( vdata, vdata, _VECTORMATH_PERM_YZXW );\n    wwww = vec_splat( qdata, 3 );\n    qv = vec_madd( wwww, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qv = vec_madd( tmp0, tmp1, qv );\n    qv = vec_nmsub( tmp2, tmp3, qv );\n    product = vec_madd( qdata, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product );\n    qw = vec_add( vec_sld( product, product, 8 ), qw );\n    tmp1 = vec_perm( qv, qv, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( qv, qv, _VECTORMATH_PERM_YZXW );\n    res = vec_madd( vec_splat( qw, 0 ), qdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    res = vec_madd( wwww, qv, res );\n    res = vec_madd( tmp0, tmp1, res );\n    res = vec_nmsub( tmp2, tmp3, res );\n    return Vector3( res );\n}\n\ninline const Quat conj( Quat quat )\n{\n    return Quat( vec_xor( quat.get128(), ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) ) );\n}\n\ninline const Quat select( Quat quat0, Quat quat1, bool select1 )\n{\n    return select( quat0, quat1, boolInVec(select1) );\n}\n\ninline const Quat select( Quat quat0, Quat quat1, boolInVec select1 )\n{\n    return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Quat quat )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat.get128();\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\ninline void print( Quat quat, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat.get128();\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/quat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_SOA_CPP_H\n#define _VECTORMATH_QUAT_SOA_CPP_H\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Soa {\n\ninline Quat::Quat( const Quat & quat )\n{\n    mX = quat.mX;\n    mY = quat.mY;\n    mZ = quat.mZ;\n    mW = quat.mW;\n}\n\ninline Quat::Quat( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n    mW = _w;\n}\n\ninline Quat::Quat( const Vector3 & xyz, vec_float4 _w )\n{\n    this->setXYZ( xyz );\n    this->setW( _w );\n}\n\ninline Quat::Quat( const Vector4 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    mW = vec.getW();\n}\n\ninline Quat::Quat( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n    mW = scalar;\n}\n\ninline Quat::Quat( Aos::Quat quat )\n{\n    vec_float4 vec128 = quat.get128();\n    mX = vec_splat( vec128, 0 );\n    mY = vec_splat( vec128, 1 );\n    mZ = vec_splat( vec128, 2 );\n    mW = vec_splat( vec128, 3 );\n}\n\ninline Quat::Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( quat0.get128(), quat2.get128() );\n    tmp1 = vec_mergeh( quat1.get128(), quat3.get128() );\n    tmp2 = vec_mergel( quat0.get128(), quat2.get128() );\n    tmp3 = vec_mergel( quat1.get128(), quat3.get128() );\n    mX = vec_mergeh( tmp0, tmp1 );\n    mY = vec_mergel( tmp0, tmp1 );\n    mZ = vec_mergeh( tmp2, tmp3 );\n    mW = vec_mergel( tmp2, tmp3 );\n}\n\ninline const Quat Quat::identity( )\n{\n    return Quat( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\ninline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 )\n{\n    return ( quat0 + ( ( quat1 - quat0 ) * t ) );\n}\n\ninline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 )\n{\n    Quat start;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = dot( unitQuat0, unitQuat1 );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){0.0f,0.0f,0.0f,0.0f}, cosAngle );\n    cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start.setX( vec_sel( unitQuat0.getX(), negatef4( unitQuat0.getX() ), selectMask ) );\n    start.setY( vec_sel( unitQuat0.getY(), negatef4( unitQuat0.getY() ), selectMask ) );\n    start.setZ( vec_sel( unitQuat0.getZ(), negatef4( unitQuat0.getZ() ), selectMask ) );\n    start.setW( vec_sel( unitQuat0.getW(), negatef4( unitQuat0.getW() ), selectMask ) );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );\n    scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) );\n}\n\ninline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 )\n{\n    Quat tmp0, tmp1;\n    tmp0 = slerp( t, unitQuat0, unitQuat3 );\n    tmp1 = slerp( t, unitQuat1, unitQuat2 );\n    return slerp( vec_madd( vec_madd( ((vec_float4){2.0f,2.0f,2.0f,2.0f}), t, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), tmp0, tmp1 );\n}\n\ninline void Quat::get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( mX, mZ );\n    tmp1 = vec_mergeh( mY, mW );\n    tmp2 = vec_mergel( mX, mZ );\n    tmp3 = vec_mergel( mY, mW );\n    result0 = Aos::Quat( vec_mergeh( tmp0, tmp1 ) );\n    result1 = Aos::Quat( vec_mergel( tmp0, tmp1 ) );\n    result2 = Aos::Quat( vec_mergeh( tmp2, tmp3 ) );\n    result3 = Aos::Quat( vec_mergel( tmp2, tmp3 ) );\n}\n\ninline Quat & Quat::operator =( const Quat & quat )\n{\n    mX = quat.mX;\n    mY = quat.mY;\n    mZ = quat.mZ;\n    mW = quat.mW;\n    return *this;\n}\n\ninline Quat & Quat::setXYZ( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    return *this;\n}\n\ninline const Vector3 Quat::getXYZ( ) const\n{\n    return Vector3( mX, mY, mZ );\n}\n\ninline Quat & Quat::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Quat::getX( ) const\n{\n    return mX;\n}\n\ninline Quat & Quat::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Quat::getY( ) const\n{\n    return mY;\n}\n\ninline Quat & Quat::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Quat::getZ( ) const\n{\n    return mZ;\n}\n\ninline Quat & Quat::setW( vec_float4 _w )\n{\n    mW = _w;\n    return *this;\n}\n\ninline vec_float4 Quat::getW( ) const\n{\n    return mW;\n}\n\ninline Quat & Quat::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Quat::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Quat::vec_float4_t & Quat::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Quat::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Quat Quat::operator +( const Quat & quat ) const\n{\n    return Quat(\n        vec_add( mX, quat.mX ),\n        vec_add( mY, quat.mY ),\n        vec_add( mZ, quat.mZ ),\n        vec_add( mW, quat.mW )\n    );\n}\n\ninline const Quat Quat::operator -( const Quat & quat ) const\n{\n    return Quat(\n        vec_sub( mX, quat.mX ),\n        vec_sub( mY, quat.mY ),\n        vec_sub( mZ, quat.mZ ),\n        vec_sub( mW, quat.mW )\n    );\n}\n\ninline const Quat Quat::operator *( vec_float4 scalar ) const\n{\n    return Quat(\n        vec_madd( mX, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mY, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mZ, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mW, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline Quat & Quat::operator +=( const Quat & quat )\n{\n    *this = *this + quat;\n    return *this;\n}\n\ninline Quat & Quat::operator -=( const Quat & quat )\n{\n    *this = *this - quat;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator /( vec_float4 scalar ) const\n{\n    return Quat(\n        divf4( mX, scalar ),\n        divf4( mY, scalar ),\n        divf4( mZ, scalar ),\n        divf4( mW, scalar )\n    );\n}\n\ninline Quat & Quat::operator /=( vec_float4 scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator -( ) const\n{\n    return Quat(\n        negatef4( mX ),\n        negatef4( mY ),\n        negatef4( mZ ),\n        negatef4( mW )\n    );\n}\n\ninline const Quat operator *( vec_float4 scalar, const Quat & quat )\n{\n    return quat * scalar;\n}\n\ninline vec_float4 dot( const Quat & quat0, const Quat & quat1 )\n{\n    vec_float4 result;\n    result = vec_madd( quat0.getX(), quat1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( quat0.getY(), quat1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat0.getZ(), quat1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat0.getW(), quat1.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 norm( const Quat & quat )\n{\n    vec_float4 result;\n    result = vec_madd( quat.getX(), quat.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( quat.getY(), quat.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat.getZ(), quat.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( quat.getW(), quat.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 length( const Quat & quat )\n{\n    return sqrtf4( norm( quat ) );\n}\n\ninline const Quat normalize( const Quat & quat )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = norm( quat );\n    lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );\n    return Quat(\n        vec_madd( quat.getX(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( quat.getY(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( quat.getZ(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( quat.getW(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 )\n{\n    vec_float4 cosHalfAngleX2, recipCosHalfAngleX2;\n    cosHalfAngleX2 = sqrtf4( vec_madd( ((vec_float4){2.0f,2.0f,2.0f,2.0f}), vec_add( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), dot( unitVec0, unitVec1 ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    recipCosHalfAngleX2 = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), cosHalfAngleX2 );\n    return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), vec_madd( cosHalfAngleX2, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Quat Quat::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    return Quat( ( unitVec * s ), c );\n}\n\ninline const Quat Quat::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    return Quat( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );\n}\n\ninline const Quat Quat::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    return Quat( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );\n}\n\ninline const Quat Quat::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sincosf4( angle, &s, &c );\n    return Quat( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, c );\n}\n\ninline const Quat Quat::operator *( const Quat & quat ) const\n{\n    return Quat(\n        vec_sub( vec_add( vec_add( vec_madd( mW, quat.mX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mX, quat.mW, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mY, quat.mZ, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mZ, quat.mY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_sub( vec_add( vec_add( vec_madd( mW, quat.mY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mY, quat.mW, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mZ, quat.mX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mX, quat.mZ, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_sub( vec_add( vec_add( vec_madd( mW, quat.mZ, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mZ, quat.mW, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mX, quat.mY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mY, quat.mX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_sub( vec_sub( vec_sub( vec_madd( mW, quat.mW, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mX, quat.mX, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mY, quat.mY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( mZ, quat.mZ, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline Quat & Quat::operator *=( const Quat & quat )\n{\n    *this = *this * quat;\n    return *this;\n}\n\ninline const Vector3 rotate( const Quat & quat, const Vector3 & vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = vec_sub( vec_add( vec_madd( quat.getW(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getY(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat.getZ(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpY = vec_sub( vec_add( vec_madd( quat.getW(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getZ(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat.getX(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpZ = vec_sub( vec_add( vec_madd( quat.getW(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getX(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat.getY(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    tmpW = vec_add( vec_add( vec_madd( quat.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return Vector3(\n        vec_add( vec_sub( vec_add( vec_madd( tmpW, quat.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpX, quat.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpY, quat.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpZ, quat.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_sub( vec_add( vec_madd( tmpW, quat.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpY, quat.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpZ, quat.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpX, quat.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_add( vec_sub( vec_add( vec_madd( tmpW, quat.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpZ, quat.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpX, quat.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpY, quat.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Quat conj( const Quat & quat )\n{\n    return Quat( negatef4( quat.getX() ), negatef4( quat.getY() ), negatef4( quat.getZ() ), quat.getW() );\n}\n\ninline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 )\n{\n    return Quat(\n        vec_sel( quat0.getX(), quat1.getX(), select1 ),\n        vec_sel( quat0.getY(), quat1.getY(), select1 ),\n        vec_sel( quat0.getZ(), quat1.getZ(), select1 ),\n        vec_sel( quat0.getW(), quat1.getW(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Quat & quat )\n{\n    Aos::Quat vec0, vec1, vec2, vec3;\n    quat.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Quat & quat, const char * name )\n{\n    Aos::Quat vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    quat.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\n} // namespace Soa\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_CPP_H\n#define _VECTORMATH_VEC_AOS_CPP_H\n//-----------------------------------------------------------------------------\n// Constants\n// for permutes words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A }\n#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }\n#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C }\n#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W }\n#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W }\n#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 }\n#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 }\n#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 }\n#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff }\n#define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\nstatic inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} );\n    result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result );\n    return vec_madd( vec_sld( vec0, vec0, 8 ), vec_sld( vec1, vec1, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} );\n    result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result );\n    return vec_add( vec_sld( result, result, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, result;\n    tmp0 = vec_perm( vec0, vec0, _VECTORMATH_PERM_YZXW );\n    tmp1 = vec_perm( vec1, vec1, _VECTORMATH_PERM_ZXYW );\n    tmp2 = vec_perm( vec0, vec0, _VECTORMATH_PERM_ZXYW );\n    tmp3 = vec_perm( vec1, vec1, _VECTORMATH_PERM_YZXW );\n    result = vec_madd( tmp0, tmp1, (vec_float4){0.0f,0.0f,0.0f,0.0f} );\n    result = vec_nmsub( tmp2, tmp3, result );\n    return result;\n}\n\nstatic inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v)\n{\n    vec_int4 bexp;\n    vec_uint4 mant, sign, hfloat;\n    vec_uint4 notZero, isInf;\n    const vec_uint4 hfloatInf = (vec_uint4){0x00007c00u,0x00007c00u,0x00007c00u,0x00007c00u};\n    const vec_uint4 mergeMant = (vec_uint4){0x000003ffu,0x000003ffu,0x000003ffu,0x000003ffu};\n    const vec_uint4 mergeSign = (vec_uint4){0x00008000u,0x00008000u,0x00008000u,0x00008000u};\n\n    sign = vec_sr((vec_uint4)v, (vec_uint4){16,16,16,16});\n    mant = vec_sr((vec_uint4)v, (vec_uint4){13,13,13,13});\n    bexp = vec_and(vec_sr((vec_int4)v, (vec_uint4){23,23,23,23}), (vec_int4){0xff,0xff,0xff,0xff});\n\n    notZero = (vec_uint4)vec_cmpgt(bexp, (vec_int4){112,112,112,112});\n    isInf = (vec_uint4)vec_cmpgt(bexp, (vec_int4){142,142,142,142});\n\n    bexp = vec_add(bexp, (vec_int4){-112,-112,-112,-112});\n    bexp = vec_sl(bexp, (vec_uint4){10,10,10,10});\n\n    hfloat = vec_sel((vec_uint4)bexp, mant, mergeMant);\n    hfloat = vec_sel((vec_uint4){0,0,0,0}, hfloat, notZero);\n    hfloat = vec_sel(hfloat, hfloatInf, isInf);\n    hfloat = vec_sel(hfloat, sign, mergeSign);\n\n    return hfloat;\n}\n\nstatic inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v)\n{\n    vec_uint4 hfloat_u, hfloat_v;\n    const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31};\n    hfloat_u = _vmathVfToHalfFloatsUnpacked(u);\n    hfloat_v = _vmathVfToHalfFloatsUnpacked(v);\n    return (vec_ushort8)vec_perm(hfloat_u, hfloat_v, pack);\n}\n\n#ifndef __GNUC__\n#define __builtin_constant_p(x) 0\n#endif\n\nstatic inline vec_float4 _vmathVfInsert(vec_float4 dst, vec_float4 src, int slot)\n{\n#ifdef __GNUC__\n    if (__builtin_constant_p(slot)) {\n        dst = vec_sld(dst, dst, slot<<2);\n        dst = vec_sld(dst, src, 4);\n        if (slot != 3) dst = vec_sld(dst, dst, (3-slot)<<2);\n        return dst;\n    } else\n#endif\n    {\n        vec_uchar16 shiftpattern = vec_lvsr( 0, (float *)(size_t)(slot<<2) );\n        vec_uint4 selectmask = (vec_uint4)vec_perm( (vec_uint4){0,0,0,0}, _VECTORMATH_MASK_0xF000, shiftpattern );\n        return vec_sel( dst, src, selectmask );\n    }\n}\n\n#define _vmathVfGetElement(vec, slot) ((float *)&(vec))[slot]\n#ifdef _VECTORMATH_SET_CONSTS_IN_MEM\n#define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar\n#else\n#define _vmathVfSetElement(vec, scalar, slot)                                            \\\n{                                                                                        \\\n    if (__builtin_constant_p(scalar)) {                                                  \\\n        (vec) = _vmathVfInsert(vec, (vec_float4){scalar, scalar, scalar, scalar}, slot); \\\n    } else {                                                                             \\\n        ((float *)&(vec))[slot] = scalar;                                                \\\n    }                                                                                    \\\n}\n#endif\n\nstatic inline vec_float4 _vmathVfSplatScalar(float scalar)\n{\n    vec_float4 result;\n    if (__builtin_constant_p(scalar)) {\n        result = (vec_float4){scalar, scalar, scalar, scalar};\n    } else {\n        result = vec_ld(0, &scalar);\n        result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0);\n    } \n    return result;\n}\n\nstatic inline vec_uint4 _vmathVuiSplatScalar(unsigned int scalar)\n{\n    vec_uint4 result;\n    if (__builtin_constant_p(scalar)) {\n        result = (vec_uint4){scalar, scalar, scalar, scalar};\n    } else {\n        result = vec_ld(0, &scalar);\n        result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0);\n    } \n    return result;\n}\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline VecIdx::operator floatInVec() const\n{\n    return floatInVec(ref, i);\n}\n\ninline float VecIdx::getAsFloat() const\n#else\ninline VecIdx::operator float() const\n#endif\n{\n    return _vmathVfGetElement(ref, i);\n}\n\ninline float VecIdx::operator =( float scalar )\n{\n    _vmathVfSetElement(ref, scalar, i);\n    return scalar;\n}\n\ninline floatInVec VecIdx::operator =( floatInVec scalar )\n{\n    ref = _vmathVfInsert(ref, scalar.get128(), i);\n    return scalar;\n}\n\ninline floatInVec VecIdx::operator =( const VecIdx& scalar )\n{\n    return *this = floatInVec(scalar.ref, scalar.i);\n}\n\ninline floatInVec VecIdx::operator *=( float scalar )\n{\n    return *this *= floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator *=( floatInVec scalar )\n{\n    return *this = floatInVec(ref, i) * scalar;\n}\n\ninline floatInVec VecIdx::operator /=( float scalar )\n{\n    return *this /= floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator /=( floatInVec scalar )\n{\n    return *this = floatInVec(ref, i) / scalar;\n}\n\ninline floatInVec VecIdx::operator +=( float scalar )\n{\n    return *this += floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator +=( floatInVec scalar )\n{\n    return *this = floatInVec(ref, i) + scalar;\n}\n\ninline floatInVec VecIdx::operator -=( float scalar )\n{\n    return *this -= floatInVec(scalar);\n}\n\ninline floatInVec VecIdx::operator -=( floatInVec scalar )\n{\n    return *this = floatInVec(ref, i) - scalar;\n}\n\ninline Vector3::Vector3( float _x, float _y, float _z )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) {\n        mVec128 = (vec_float4){_x, _y, _z, 0.0f};\n    } else {\n        float *pf = (float *)&mVec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n    }\n}\n\ninline Vector3::Vector3( floatInVec _x, floatInVec _y, floatInVec _z )\n{\n    vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() );\n    mVec128 = vec_mergeh( xz, _y.get128() );\n}\n\ninline Vector3::Vector3( Point3 pnt )\n{\n    mVec128 = pnt.get128();\n}\n\ninline Vector3::Vector3( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Vector3::Vector3( floatInVec scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Vector3::Vector3( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Vector3 Vector3::xAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_1000 );\n}\n\ninline const Vector3 Vector3::yAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_0100 );\n}\n\ninline const Vector3 Vector3::zAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_0010 );\n}\n\ninline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 )\n{\n    return lerp( floatInVec(t), vec0, vec1 );\n}\n\ninline const Vector3 lerp( floatInVec t, Vector3 vec0, Vector3 vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 )\n{\n    return slerp( floatInVec(t), unitVec0, unitVec1 );\n}\n\ninline const Vector3 slerp( floatInVec t, Vector3 unitVec0, Vector3 unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() );\n    cosAngle = vec_splat( cosAngle, 0 );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = t.get128();\n    oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sines = sinf4( angles );\n    scales = divf4( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    return Vector3( vec_madd( unitVec0.get128(), scale0, vec_madd( unitVec1.get128(), scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n}\n\ninline vec_float4 Vector3::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeXYZ( Vector3 vec, vec_float4 * quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = _VECTORMATH_MASK_0x000F;\n    dstVec = vec_sel(vec.get128(), dstVec, mask);\n    *quad = dstVec;\n}\n\ninline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = vec_sld( xyzx, yzxy, 12 );\n    xyz2 = vec_sld( yzxy, zxyz, 8 );\n    xyz3 = vec_sld( zxyz, zxyz, 4 );\n    vec0 = Vector3( xyzx );\n    vec1 = Vector3( xyz1 );\n    vec2 = Vector3( xyz2 );\n    vec3 = Vector3( xyz3 );\n}\n\ninline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = vec_perm( vec0.get128(), vec1.get128(), _VECTORMATH_PERM_XYZA );\n    yzxy = vec_perm( vec1.get128(), vec2.get128(), _VECTORMATH_PERM_YZAB );\n    zxyz = vec_perm( vec2.get128(), vec3.get128(), _VECTORMATH_PERM_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( vec0, vec1, vec2, vec3, xyz0 );\n    storeXYZArray( vec4, vec5, vec6, vec7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Vector3 & Vector3::operator =( Vector3 vec )\n{\n    mVec128 = vec.mVec128;\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( floatInVec _x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Vector3::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Vector3 & Vector3::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Vector3 & Vector3::setY( floatInVec _y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Vector3::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Vector3 & Vector3::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Vector3 & Vector3::setZ( floatInVec _z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Vector3::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Vector3 & Vector3::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Vector3 & Vector3::setElem( int idx, floatInVec value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Vector3::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Vector3::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Vector3::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Vector3 Vector3::operator +( Vector3 vec ) const\n{\n    return Vector3( vec_add( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector3 Vector3::operator -( Vector3 vec ) const\n{\n    return Vector3( vec_sub( mVec128, vec.mVec128 ) );\n}\n\ninline const Point3 Vector3::operator +( Point3 pnt ) const\n{\n    return Point3( vec_add( mVec128, pnt.get128() ) );\n}\n\ninline const Vector3 Vector3::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Vector3 Vector3::operator *( floatInVec scalar ) const\n{\n    return Vector3( vec_madd( mVec128, scalar.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline Vector3 & Vector3::operator +=( Vector3 vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator -=( Vector3 vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( floatInVec scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator /( float scalar ) const\n{\n    return *this / floatInVec(scalar);\n}\n\ninline const Vector3 Vector3::operator /( floatInVec scalar ) const\n{\n    return Vector3( divf4( mVec128, scalar.get128() ) );\n}\n\ninline Vector3 & Vector3::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator /=( floatInVec scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator -( ) const\n{\n    return Vector3( negatef4( mVec128 ) );\n}\n\ninline const Vector3 operator *( float scalar, Vector3 vec )\n{\n    return floatInVec(scalar) * vec;\n}\n\ninline const Vector3 operator *( floatInVec scalar, Vector3 vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( vec_madd( vec0.get128(), vec1.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( divf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 recipPerElem( Vector3 vec )\n{\n    return Vector3( recipf4( vec.get128() ) );\n}\n\ninline const Vector3 sqrtPerElem( Vector3 vec )\n{\n    return Vector3( sqrtf4( vec.get128() ) );\n}\n\ninline const Vector3 rsqrtPerElem( Vector3 vec )\n{\n    return Vector3( rsqrtf4( vec.get128() ) );\n}\n\ninline const Vector3 absPerElem( Vector3 vec )\n{\n    return Vector3( fabsf4( vec.get128() ) );\n}\n\ninline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( copysignf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( fmaxf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec maxElem( Vector3 vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec_splat( vec.get128(), 1 ), vec.get128() );\n    result = fmaxf4( vec_splat( vec.get128(), 2 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( fminf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec minElem( Vector3 vec )\n{\n    vec_float4 result;\n    result = fminf4( vec_splat( vec.get128(), 1 ), vec.get128() );\n    result = fminf4( vec_splat( vec.get128(), 2 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const floatInVec sum( Vector3 vec )\n{\n    vec_float4 result;\n    result = vec_add( vec_splat( vec.get128(), 1 ), vec.get128() );\n    result = vec_add( vec_splat( vec.get128(), 2 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const floatInVec dot( Vector3 vec0, Vector3 vec1 )\n{\n    return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 );\n}\n\ninline const floatInVec lengthSqr( Vector3 vec )\n{\n    return floatInVec(  _vmathVfDot3( vec.get128(), vec.get128() ), 0 );\n}\n\ninline const floatInVec length( Vector3 vec )\n{\n    return floatInVec(  sqrtf4(_vmathVfDot3( vec.get128(), vec.get128() )), 0 );\n}\n\ninline const Vector3 normalize( Vector3 vec )\n{\n    vec_float4 dot = _vmathVfDot3( vec.get128(), vec.get128() );\n    dot = vec_splat( dot, 0 );\n    return Vector3( vec_madd( vec.get128(), rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Vector3 cross( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 )\n{\n    return select( vec0, vec1, boolInVec(select1) );\n}\n\ninline const Vector3 select( Vector3 vec0, Vector3 vec1, boolInVec select1 )\n{\n    return Vector3( vec_sel( vec0.get128(), vec1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Vector3 vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\ninline void print( Vector3 vec, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\ninline Vector4::Vector4( float _x, float _y, float _z, float _w )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) &\n        __builtin_constant_p(_z) & __builtin_constant_p(_w)) {\n        mVec128 = (vec_float4){_x, _y, _z, _w};\n    } else {\n        float *pf = (float *)&mVec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n        pf[3] = _w;\n    }\n}\n\ninline Vector4::Vector4( floatInVec _x, floatInVec _y, floatInVec _z, floatInVec _w )\n{\n    vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() );\n    vec_float4 yw = vec_mergeh( _y.get128(), _w.get128() );\n    mVec128 = vec_mergeh( xz, yw );\n}\n\ninline Vector4::Vector4( Vector3 xyz, float _w )\n{\n    mVec128 = xyz.get128();\n    _vmathVfSetElement(mVec128, _w, 3);\n}\n\ninline Vector4::Vector4( Vector3 xyz, floatInVec _w )\n{\n    mVec128 = xyz.get128();\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n}\n\ninline Vector4::Vector4( Vector3 vec )\n{\n    mVec128 = vec.get128();\n    mVec128 = _vmathVfInsert(mVec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), 3);\n}\n\ninline Vector4::Vector4( Point3 pnt )\n{\n    mVec128 = pnt.get128();\n    mVec128 = _vmathVfInsert(mVec128, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), 3);\n}\n\ninline Vector4::Vector4( Quat quat )\n{\n    mVec128 = quat.get128();\n}\n\ninline Vector4::Vector4( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Vector4::Vector4( floatInVec scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Vector4::Vector4( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Vector4 Vector4::xAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_1000 );\n}\n\ninline const Vector4 Vector4::yAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0100 );\n}\n\ninline const Vector4 Vector4::zAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0010 );\n}\n\ninline const Vector4 Vector4::wAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0001 );\n}\n\ninline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 )\n{\n    return lerp( floatInVec(t), vec0, vec1 );\n}\n\ninline const Vector4 lerp( floatInVec t, Vector4 vec0, Vector4 vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 )\n{\n    return slerp( floatInVec(t), unitVec0, unitVec1 );\n}\n\ninline const Vector4 slerp( floatInVec t, Vector4 unitVec0, Vector4 unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() );\n    cosAngle = vec_splat( cosAngle, 0 );\n    selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = t.get128();\n    oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt );\n    angles = vec_mergeh( angles, oneMinusT );\n    angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    sines = sinf4( angles );\n    scales = divf4( sines, vec_splat( sines, 0 ) );\n    scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask );\n    scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask );\n    return Vector4( vec_madd( unitVec0.get128(), scale0, vec_madd( unitVec1.get128(), scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) );\n}\n\ninline vec_float4 Vector4::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads )\n{\n    twoQuads[0] = _vmath2VfToHalfFloats(vec0.get128(), vec1.get128());\n    twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128());\n}\n\ninline Vector4 & Vector4::operator =( Vector4 vec )\n{\n    mVec128 = vec.mVec128;\n    return *this;\n}\n\ninline Vector4 & Vector4::setXYZ( Vector3 vec )\n{\n    mVec128 = vec_sel( vec.get128(), mVec128, _VECTORMATH_MASK_0x000F );\n    return *this;\n}\n\ninline const Vector3 Vector4::getXYZ( ) const\n{\n    return Vector3( mVec128 );\n}\n\ninline Vector4 & Vector4::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Vector4 & Vector4::setX( floatInVec _x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Vector4::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Vector4 & Vector4::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Vector4 & Vector4::setY( floatInVec _y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Vector4::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Vector4 & Vector4::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Vector4 & Vector4::setZ( floatInVec _z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Vector4::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Vector4 & Vector4::setW( float _w )\n{\n    _vmathVfSetElement(mVec128, _w, 3);\n    return *this;\n}\n\ninline Vector4 & Vector4::setW( floatInVec _w )\n{\n    mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);\n    return *this;\n}\n\ninline const floatInVec Vector4::getW( ) const\n{\n    return floatInVec( mVec128, 3 );\n}\n\ninline Vector4 & Vector4::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Vector4 & Vector4::setElem( int idx, floatInVec value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Vector4::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Vector4::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Vector4::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Vector4 Vector4::operator +( Vector4 vec ) const\n{\n    return Vector4( vec_add( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector4 Vector4::operator -( Vector4 vec ) const\n{\n    return Vector4( vec_sub( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector4 Vector4::operator *( float scalar ) const\n{\n    return *this * floatInVec(scalar);\n}\n\ninline const Vector4 Vector4::operator *( floatInVec scalar ) const\n{\n    return Vector4( vec_madd( mVec128, scalar.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline Vector4 & Vector4::operator +=( Vector4 vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator -=( Vector4 vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( floatInVec scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator /( float scalar ) const\n{\n    return *this / floatInVec(scalar);\n}\n\ninline const Vector4 Vector4::operator /( floatInVec scalar ) const\n{\n    return Vector4( divf4( mVec128, scalar.get128() ) );\n}\n\ninline Vector4 & Vector4::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator /=( floatInVec scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator -( ) const\n{\n    return Vector4( negatef4( mVec128 ) );\n}\n\ninline const Vector4 operator *( float scalar, Vector4 vec )\n{\n    return floatInVec(scalar) * vec;\n}\n\ninline const Vector4 operator *( floatInVec scalar, Vector4 vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( vec_madd( vec0.get128(), vec1.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( divf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 recipPerElem( Vector4 vec )\n{\n    return Vector4( recipf4( vec.get128() ) );\n}\n\ninline const Vector4 sqrtPerElem( Vector4 vec )\n{\n    return Vector4( sqrtf4( vec.get128() ) );\n}\n\ninline const Vector4 rsqrtPerElem( Vector4 vec )\n{\n    return Vector4( rsqrtf4( vec.get128() ) );\n}\n\ninline const Vector4 absPerElem( Vector4 vec )\n{\n    return Vector4( fabsf4( vec.get128() ) );\n}\n\ninline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( copysignf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( fmaxf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec maxElem( Vector4 vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec_splat( vec.get128(), 1 ), vec.get128() );\n    result = fmaxf4( vec_splat( vec.get128(), 2 ), result );\n    result = fmaxf4( vec_splat( vec.get128(), 3 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( fminf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const floatInVec minElem( Vector4 vec )\n{\n    vec_float4 result;\n    result = fminf4( vec_splat( vec.get128(), 1 ), vec.get128() );\n    result = fminf4( vec_splat( vec.get128(), 2 ), result );\n    result = fminf4( vec_splat( vec.get128(), 3 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const floatInVec sum( Vector4 vec )\n{\n    vec_float4 result;\n    result = vec_add( vec_splat( vec.get128(), 1 ), vec.get128() );\n    result = vec_add( vec_splat( vec.get128(), 2 ), result );\n    result = vec_add( vec_splat( vec.get128(), 3 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const floatInVec dot( Vector4 vec0, Vector4 vec1 )\n{\n    return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 );\n}\n\ninline const floatInVec lengthSqr( Vector4 vec )\n{\n    return floatInVec(  _vmathVfDot4( vec.get128(), vec.get128() ), 0 );\n}\n\ninline const floatInVec length( Vector4 vec )\n{\n    return floatInVec(  sqrtf4(_vmathVfDot4( vec.get128(), vec.get128() )), 0 );\n}\n\ninline const Vector4 normalize( Vector4 vec )\n{\n    vec_float4 dot = _vmathVfDot4( vec.get128(), vec.get128() );\n    return Vector4( vec_madd( vec.get128(), rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 )\n{\n    return select( vec0, vec1, boolInVec(select1) );\n}\n\ninline const Vector4 select( Vector4 vec0, Vector4 vec1, boolInVec select1 )\n{\n    return Vector4( vec_sel( vec0.get128(), vec1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Vector4 vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\ninline void print( Vector4 vec, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\ninline Point3::Point3( float _x, float _y, float _z )\n{\n    if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) {\n        mVec128 = (vec_float4){_x, _y, _z, 0.0f};\n    } else {\n        float *pf = (float *)&mVec128;\n        pf[0] = _x;\n        pf[1] = _y;\n        pf[2] = _z;\n    }\n}\n\ninline Point3::Point3( floatInVec _x, floatInVec _y, floatInVec _z )\n{\n    vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() );\n    mVec128 = vec_mergeh( xz, _y.get128() );\n}\n\ninline Point3::Point3( Vector3 vec )\n{\n    mVec128 = vec.get128();\n}\n\ninline Point3::Point3( float scalar )\n{\n    mVec128 = floatInVec(scalar).get128();\n}\n\ninline Point3::Point3( floatInVec scalar )\n{\n    mVec128 = scalar.get128();\n}\n\ninline Point3::Point3( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 )\n{\n    return lerp( floatInVec(t), pnt0, pnt1 );\n}\n\ninline const Point3 lerp( floatInVec t, Point3 pnt0, Point3 pnt1 )\n{\n    return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) );\n}\n\ninline vec_float4 Point3::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeXYZ( Point3 pnt, vec_float4 * quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = _VECTORMATH_MASK_0x000F;\n    dstVec = vec_sel(pnt.get128(), dstVec, mask);\n    *quad = dstVec;\n}\n\ninline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = vec_sld( xyzx, yzxy, 12 );\n    xyz2 = vec_sld( yzxy, zxyz, 8 );\n    xyz3 = vec_sld( zxyz, zxyz, 4 );\n    pnt0 = Point3( xyzx );\n    pnt1 = Point3( xyz1 );\n    pnt2 = Point3( xyz2 );\n    pnt3 = Point3( xyz3 );\n}\n\ninline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = vec_perm( pnt0.get128(), pnt1.get128(), _VECTORMATH_PERM_XYZA );\n    yzxy = vec_perm( pnt1.get128(), pnt2.get128(), _VECTORMATH_PERM_YZAB );\n    zxyz = vec_perm( pnt2.get128(), pnt3.get128(), _VECTORMATH_PERM_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 );\n    storeXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Point3 & Point3::operator =( Point3 pnt )\n{\n    mVec128 = pnt.mVec128;\n    return *this;\n}\n\ninline Point3 & Point3::setX( float _x )\n{\n    _vmathVfSetElement(mVec128, _x, 0);\n    return *this;\n}\n\ninline Point3 & Point3::setX( floatInVec _x )\n{\n    mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);\n    return *this;\n}\n\ninline const floatInVec Point3::getX( ) const\n{\n    return floatInVec( mVec128, 0 );\n}\n\ninline Point3 & Point3::setY( float _y )\n{\n    _vmathVfSetElement(mVec128, _y, 1);\n    return *this;\n}\n\ninline Point3 & Point3::setY( floatInVec _y )\n{\n    mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);\n    return *this;\n}\n\ninline const floatInVec Point3::getY( ) const\n{\n    return floatInVec( mVec128, 1 );\n}\n\ninline Point3 & Point3::setZ( float _z )\n{\n    _vmathVfSetElement(mVec128, _z, 2);\n    return *this;\n}\n\ninline Point3 & Point3::setZ( floatInVec _z )\n{\n    mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);\n    return *this;\n}\n\ninline const floatInVec Point3::getZ( ) const\n{\n    return floatInVec( mVec128, 2 );\n}\n\ninline Point3 & Point3::setElem( int idx, float value )\n{\n    _vmathVfSetElement(mVec128, value, idx);\n    return *this;\n}\n\ninline Point3 & Point3::setElem( int idx, floatInVec value )\n{\n    mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);\n    return *this;\n}\n\ninline const floatInVec Point3::getElem( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline VecIdx Point3::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline const floatInVec Point3::operator []( int idx ) const\n{\n    return floatInVec( mVec128, idx );\n}\n\ninline const Vector3 Point3::operator -( Point3 pnt ) const\n{\n    return Vector3( vec_sub( mVec128, pnt.mVec128 ) );\n}\n\ninline const Point3 Point3::operator +( Vector3 vec ) const\n{\n    return Point3( vec_add( mVec128, vec.get128() ) );\n}\n\ninline const Point3 Point3::operator -( Vector3 vec ) const\n{\n    return Point3( vec_sub( mVec128, vec.get128() ) );\n}\n\ninline Point3 & Point3::operator +=( Vector3 vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Point3 & Point3::operator -=( Vector3 vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( vec_madd( pnt0.get128(), pnt1.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n}\n\ninline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( divf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 recipPerElem( Point3 pnt )\n{\n    return Point3( recipf4( pnt.get128() ) );\n}\n\ninline const Point3 sqrtPerElem( Point3 pnt )\n{\n    return Point3( sqrtf4( pnt.get128() ) );\n}\n\ninline const Point3 rsqrtPerElem( Point3 pnt )\n{\n    return Point3( rsqrtf4( pnt.get128() ) );\n}\n\ninline const Point3 absPerElem( Point3 pnt )\n{\n    return Point3( fabsf4( pnt.get128() ) );\n}\n\ninline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( copysignf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( fmaxf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const floatInVec maxElem( Point3 pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( vec_splat( pnt.get128(), 1 ), pnt.get128() );\n    result = fmaxf4( vec_splat( pnt.get128(), 2 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( fminf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const floatInVec minElem( Point3 pnt )\n{\n    vec_float4 result;\n    result = fminf4( vec_splat( pnt.get128(), 1 ), pnt.get128() );\n    result = fminf4( vec_splat( pnt.get128(), 2 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const floatInVec sum( Point3 pnt )\n{\n    vec_float4 result;\n    result = vec_add( vec_splat( pnt.get128(), 1 ), pnt.get128() );\n    result = vec_add( vec_splat( pnt.get128(), 2 ), result );\n    return floatInVec( result, 0 );\n}\n\ninline const Point3 scale( Point3 pnt, float scaleVal )\n{\n    return scale( pnt, floatInVec( scaleVal ) );\n}\n\ninline const Point3 scale( Point3 pnt, floatInVec scaleVal )\n{\n    return mulPerElem( pnt, Point3( scaleVal ) );\n}\n\ninline const Point3 scale( Point3 pnt, Vector3 scaleVec )\n{\n    return mulPerElem( pnt, Point3( scaleVec ) );\n}\n\ninline const floatInVec projection( Point3 pnt, Vector3 unitVec )\n{\n    return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 );\n}\n\ninline const floatInVec distSqrFromOrigin( Point3 pnt )\n{\n    return lengthSqr( Vector3( pnt ) );\n}\n\ninline const floatInVec distFromOrigin( Point3 pnt )\n{\n    return length( Vector3( pnt ) );\n}\n\ninline const floatInVec distSqr( Point3 pnt0, Point3 pnt1 )\n{\n    return lengthSqr( ( pnt1 - pnt0 ) );\n}\n\ninline const floatInVec dist( Point3 pnt0, Point3 pnt1 )\n{\n    return length( ( pnt1 - pnt0 ) );\n}\n\ninline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 )\n{\n    return select( pnt0, pnt1, boolInVec(select1) );\n}\n\ninline const Point3 select( Point3 pnt0, Point3 pnt1, boolInVec select1 )\n{\n    return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Point3 pnt )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt.get128();\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\ninline void print( Point3 pnt, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt.get128();\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/vec_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_SOA_CPP_H\n#define _VECTORMATH_VEC_SOA_CPP_H\n//-----------------------------------------------------------------------------\n// Constants\n// for permutes, words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_PERM_X 0x00010203\n#define _VECTORMATH_PERM_Y 0x04050607\n#define _VECTORMATH_PERM_Z 0x08090a0b\n#define _VECTORMATH_PERM_W 0x0c0d0e0f\n#define _VECTORMATH_PERM_A 0x10111213\n#define _VECTORMATH_PERM_B 0x14151617\n#define _VECTORMATH_PERM_C 0x18191a1b\n#define _VECTORMATH_PERM_D 0x1c1d1e1f\n#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_ZDWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X })\n#define _VECTORMATH_PERM_ZCXA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_XBZD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_WDYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B })\n#define _VECTORMATH_PERM_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X, _VECTORMATH_PERM_D })\n#define _VECTORMATH_PERM_WCYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A })\n#define _VECTORMATH_PERM_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B })\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Soa {\n\ninline Vector3::Vector3( const Vector3 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n}\n\ninline Vector3::Vector3( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n}\n\ninline Vector3::Vector3( const Point3 & pnt )\n{\n    mX = pnt.getX();\n    mY = pnt.getY();\n    mZ = pnt.getZ();\n}\n\ninline Vector3::Vector3( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n}\n\ninline Vector3::Vector3( Aos::Vector3 vec )\n{\n    vec_float4 vec128 = vec.get128();\n    mX = vec_splat( vec128, 0 );\n    mY = vec_splat( vec128, 1 );\n    mZ = vec_splat( vec128, 2 );\n}\n\ninline Vector3::Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( vec0.get128(), vec2.get128() );\n    tmp1 = vec_mergeh( vec1.get128(), vec3.get128() );\n    tmp2 = vec_mergel( vec0.get128(), vec2.get128() );\n    tmp3 = vec_mergel( vec1.get128(), vec3.get128() );\n    mX = vec_mergeh( tmp0, tmp1 );\n    mY = vec_mergel( tmp0, tmp1 );\n    mZ = vec_mergeh( tmp2, tmp3 );\n}\n\ninline const Vector3 Vector3::xAxis( )\n{\n    return Vector3( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\ninline const Vector3 Vector3::yAxis( )\n{\n    return Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\ninline const Vector3 Vector3::zAxis( )\n{\n    return Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\ninline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 )\n{\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );\n    scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) );\n}\n\ninline void Vector3::get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = vec_mergeh( mX, mZ );\n    tmp1 = vec_mergel( mX, mZ );\n    result0 = Aos::Vector3( vec_mergeh( tmp0, mY ) );\n    result1 = Aos::Vector3( vec_perm( tmp0, mY, _VECTORMATH_PERM_ZBWX ) );\n    result2 = Aos::Vector3( vec_perm( tmp1, mY, _VECTORMATH_PERM_XCYX ) );\n    result3 = Aos::Vector3( vec_perm( tmp1, mY, _VECTORMATH_PERM_ZDWX ) );\n}\n\ninline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = vec_sld( yzxy, xyzx, 8 );\n    zxzx = vec_sld( xyzx, zxyz, 8 );\n    yzyz = vec_sld( zxyz, yzxy, 8 );\n    vec.setX( vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) );\n    vec.setY( vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) );\n    vec.setZ( vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) );\n}\n\ninline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = vec_perm( vec.getX(), vec.getY(), _VECTORMATH_PERM_ZCXA );\n    zxzx = vec_perm( vec.getZ(), vec.getX(), _VECTORMATH_PERM_XBZD );\n    yzyz = vec_perm( vec.getY(), vec.getZ(), _VECTORMATH_PERM_WDYB );\n    xyzx = vec_sld( xyxy, zxzx, 8 );\n    yzxy = vec_sld( yzyz, xyxy, 8 );\n    zxyz = vec_sld( zxzx, yzyz, 8 );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( vec0, xyz0 );\n    storeXYZArray( vec1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Vector3 & Vector3::operator =( const Vector3 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Vector3::getX( ) const\n{\n    return mX;\n}\n\ninline Vector3 & Vector3::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Vector3::getY( ) const\n{\n    return mY;\n}\n\ninline Vector3 & Vector3::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Vector3::getZ( ) const\n{\n    return mZ;\n}\n\ninline Vector3 & Vector3::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Vector3::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Vector3::vec_float4_t & Vector3::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Vector3::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector3 Vector3::operator +( const Vector3 & vec ) const\n{\n    return Vector3(\n        vec_add( mX, vec.mX ),\n        vec_add( mY, vec.mY ),\n        vec_add( mZ, vec.mZ )\n    );\n}\n\ninline const Vector3 Vector3::operator -( const Vector3 & vec ) const\n{\n    return Vector3(\n        vec_sub( mX, vec.mX ),\n        vec_sub( mY, vec.mY ),\n        vec_sub( mZ, vec.mZ )\n    );\n}\n\ninline const Point3 Vector3::operator +( const Point3 & pnt ) const\n{\n    return Point3(\n        vec_add( mX, pnt.getX() ),\n        vec_add( mY, pnt.getY() ),\n        vec_add( mZ, pnt.getZ() )\n    );\n}\n\ninline const Vector3 Vector3::operator *( vec_float4 scalar ) const\n{\n    return Vector3(\n        vec_madd( mX, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mY, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mZ, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline Vector3 & Vector3::operator +=( const Vector3 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator -=( const Vector3 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator /( vec_float4 scalar ) const\n{\n    return Vector3(\n        divf4( mX, scalar ),\n        divf4( mY, scalar ),\n        divf4( mZ, scalar )\n    );\n}\n\ninline Vector3 & Vector3::operator /=( vec_float4 scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator -( ) const\n{\n    return Vector3(\n        negatef4( mX ),\n        negatef4( mY ),\n        negatef4( mZ )\n    );\n}\n\ninline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        divf4( vec0.getX(), vec1.getX() ),\n        divf4( vec0.getY(), vec1.getY() ),\n        divf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline const Vector3 recipPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getX() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getY() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getZ() )\n    );\n}\n\ninline const Vector3 sqrtPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        sqrtf4( vec.getX() ),\n        sqrtf4( vec.getY() ),\n        sqrtf4( vec.getZ() )\n    );\n}\n\ninline const Vector3 rsqrtPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getX() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getY() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getZ() ) )\n    );\n}\n\ninline const Vector3 absPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        fabsf4( vec.getX() ),\n        fabsf4( vec.getY() ),\n        fabsf4( vec.getZ() )\n    );\n}\n\ninline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        copysignf4( vec0.getX(), vec1.getX() ),\n        copysignf4( vec0.getY(), vec1.getY() ),\n        copysignf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        fmaxf4( vec0.getX(), vec1.getX() ),\n        fmaxf4( vec0.getY(), vec1.getY() ),\n        fmaxf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline vec_float4 maxElem( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec.getX(), vec.getY() );\n    result = fmaxf4( vec.getZ(), result );\n    return result;\n}\n\ninline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        fminf4( vec0.getX(), vec1.getX() ),\n        fminf4( vec0.getY(), vec1.getY() ),\n        fminf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline vec_float4 minElem( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = fminf4( vec.getX(), vec.getY() );\n    result = fminf4( vec.getZ(), result );\n    return result;\n}\n\ninline vec_float4 sum( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = vec_add( vec.getX(), vec.getY() );\n    result = vec_add( result, vec.getZ() );\n    return result;\n}\n\ninline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 lengthSqr( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = vec_madd( vec.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 length( const Vector3 & vec )\n{\n    return sqrtf4( lengthSqr( vec ) );\n}\n\ninline const Vector3 normalize( const Vector3 & vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = lengthSqr( vec );\n    lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );\n    return Vector3(\n        vec_madd( vec.getX(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec.getY(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec.getZ(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        vec_sub( vec_madd( vec0.getY(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getZ(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_sub( vec_madd( vec0.getZ(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getX(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ),\n        vec_sub( vec_madd( vec0.getX(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getY(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) )\n    );\n}\n\ninline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 )\n{\n    return Vector3(\n        vec_sel( vec0.getX(), vec1.getX(), select1 ),\n        vec_sel( vec0.getY(), vec1.getY(), select1 ),\n        vec_sel( vec0.getZ(), vec1.getZ(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector3 & vec )\n{\n    Aos::Vector3 vec0, vec1, vec2, vec3;\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Vector3 & vec, const char * name )\n{\n    Aos::Vector3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\ninline Vector4::Vector4( const Vector4 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    mW = vec.mW;\n}\n\ninline Vector4::Vector4( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n    mW = _w;\n}\n\ninline Vector4::Vector4( const Vector3 & xyz, vec_float4 _w )\n{\n    this->setXYZ( xyz );\n    this->setW( _w );\n}\n\ninline Vector4::Vector4( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    mW = ((vec_float4){0.0f,0.0f,0.0f,0.0f});\n}\n\ninline Vector4::Vector4( const Point3 & pnt )\n{\n    mX = pnt.getX();\n    mY = pnt.getY();\n    mZ = pnt.getZ();\n    mW = ((vec_float4){1.0f,1.0f,1.0f,1.0f});\n}\n\ninline Vector4::Vector4( const Quat & quat )\n{\n    mX = quat.getX();\n    mY = quat.getY();\n    mZ = quat.getZ();\n    mW = quat.getW();\n}\n\ninline Vector4::Vector4( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n    mW = scalar;\n}\n\ninline Vector4::Vector4( Aos::Vector4 vec )\n{\n    vec_float4 vec128 = vec.get128();\n    mX = vec_splat( vec128, 0 );\n    mY = vec_splat( vec128, 1 );\n    mZ = vec_splat( vec128, 2 );\n    mW = vec_splat( vec128, 3 );\n}\n\ninline Vector4::Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( vec0.get128(), vec2.get128() );\n    tmp1 = vec_mergeh( vec1.get128(), vec3.get128() );\n    tmp2 = vec_mergel( vec0.get128(), vec2.get128() );\n    tmp3 = vec_mergel( vec1.get128(), vec3.get128() );\n    mX = vec_mergeh( tmp0, tmp1 );\n    mY = vec_mergel( tmp0, tmp1 );\n    mZ = vec_mergeh( tmp2, tmp3 );\n    mW = vec_mergel( tmp2, tmp3 );\n}\n\ninline const Vector4 Vector4::xAxis( )\n{\n    return Vector4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\ninline const Vector4 Vector4::yAxis( )\n{\n    return Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\ninline const Vector4 Vector4::zAxis( )\n{\n    return Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n}\n\ninline const Vector4 Vector4::wAxis( )\n{\n    return Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );\n}\n\ninline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 )\n{\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );\n    scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );\n    return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) );\n}\n\ninline void Vector4::get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( mX, mZ );\n    tmp1 = vec_mergeh( mY, mW );\n    tmp2 = vec_mergel( mX, mZ );\n    tmp3 = vec_mergel( mY, mW );\n    result0 = Aos::Vector4( vec_mergeh( tmp0, tmp1 ) );\n    result1 = Aos::Vector4( vec_mergel( tmp0, tmp1 ) );\n    result2 = Aos::Vector4( vec_mergeh( tmp2, tmp3 ) );\n    result3 = Aos::Vector4( vec_mergel( tmp2, tmp3 ) );\n}\n\ninline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads )\n{\n    Aos::Vector4 v0, v1, v2, v3;\n    vec.get4Aos( v0, v1, v2, v3 );\n    twoQuads[0] = _vmath2VfToHalfFloats(v0.get128(), v1.get128());\n    twoQuads[1] = _vmath2VfToHalfFloats(v2.get128(), v3.get128());\n}\n\ninline Vector4 & Vector4::operator =( const Vector4 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    mW = vec.mW;\n    return *this;\n}\n\ninline Vector4 & Vector4::setXYZ( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    return *this;\n}\n\ninline const Vector3 Vector4::getXYZ( ) const\n{\n    return Vector3( mX, mY, mZ );\n}\n\ninline Vector4 & Vector4::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Vector4::getX( ) const\n{\n    return mX;\n}\n\ninline Vector4 & Vector4::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Vector4::getY( ) const\n{\n    return mY;\n}\n\ninline Vector4 & Vector4::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Vector4::getZ( ) const\n{\n    return mZ;\n}\n\ninline Vector4 & Vector4::setW( vec_float4 _w )\n{\n    mW = _w;\n    return *this;\n}\n\ninline vec_float4 Vector4::getW( ) const\n{\n    return mW;\n}\n\ninline Vector4 & Vector4::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Vector4::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Vector4::vec_float4_t & Vector4::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Vector4::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector4 Vector4::operator +( const Vector4 & vec ) const\n{\n    return Vector4(\n        vec_add( mX, vec.mX ),\n        vec_add( mY, vec.mY ),\n        vec_add( mZ, vec.mZ ),\n        vec_add( mW, vec.mW )\n    );\n}\n\ninline const Vector4 Vector4::operator -( const Vector4 & vec ) const\n{\n    return Vector4(\n        vec_sub( mX, vec.mX ),\n        vec_sub( mY, vec.mY ),\n        vec_sub( mZ, vec.mZ ),\n        vec_sub( mW, vec.mW )\n    );\n}\n\ninline const Vector4 Vector4::operator *( vec_float4 scalar ) const\n{\n    return Vector4(\n        vec_madd( mX, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mY, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mZ, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( mW, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline Vector4 & Vector4::operator +=( const Vector4 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator -=( const Vector4 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator /( vec_float4 scalar ) const\n{\n    return Vector4(\n        divf4( mX, scalar ),\n        divf4( mY, scalar ),\n        divf4( mZ, scalar ),\n        divf4( mW, scalar )\n    );\n}\n\ninline Vector4 & Vector4::operator /=( vec_float4 scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator -( ) const\n{\n    return Vector4(\n        negatef4( mX ),\n        negatef4( mY ),\n        negatef4( mZ ),\n        negatef4( mW )\n    );\n}\n\ninline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec0.getW(), vec1.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        divf4( vec0.getX(), vec1.getX() ),\n        divf4( vec0.getY(), vec1.getY() ),\n        divf4( vec0.getZ(), vec1.getZ() ),\n        divf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline const Vector4 recipPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getX() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getY() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getZ() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getW() )\n    );\n}\n\ninline const Vector4 sqrtPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        sqrtf4( vec.getX() ),\n        sqrtf4( vec.getY() ),\n        sqrtf4( vec.getZ() ),\n        sqrtf4( vec.getW() )\n    );\n}\n\ninline const Vector4 rsqrtPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getX() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getY() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getZ() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getW() ) )\n    );\n}\n\ninline const Vector4 absPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        fabsf4( vec.getX() ),\n        fabsf4( vec.getY() ),\n        fabsf4( vec.getZ() ),\n        fabsf4( vec.getW() )\n    );\n}\n\ninline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        copysignf4( vec0.getX(), vec1.getX() ),\n        copysignf4( vec0.getY(), vec1.getY() ),\n        copysignf4( vec0.getZ(), vec1.getZ() ),\n        copysignf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        fmaxf4( vec0.getX(), vec1.getX() ),\n        fmaxf4( vec0.getY(), vec1.getY() ),\n        fmaxf4( vec0.getZ(), vec1.getZ() ),\n        fmaxf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline vec_float4 maxElem( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec.getX(), vec.getY() );\n    result = fmaxf4( vec.getZ(), result );\n    result = fmaxf4( vec.getW(), result );\n    return result;\n}\n\ninline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        fminf4( vec0.getX(), vec1.getX() ),\n        fminf4( vec0.getY(), vec1.getY() ),\n        fminf4( vec0.getZ(), vec1.getZ() ),\n        fminf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline vec_float4 minElem( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = fminf4( vec.getX(), vec.getY() );\n    result = fminf4( vec.getZ(), result );\n    result = fminf4( vec.getW(), result );\n    return result;\n}\n\ninline vec_float4 sum( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = vec_add( vec.getX(), vec.getY() );\n    result = vec_add( result, vec.getZ() );\n    result = vec_add( result, vec.getW() );\n    return result;\n}\n\ninline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    vec_float4 result;\n    result = vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec0.getW(), vec1.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 lengthSqr( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = vec_madd( vec.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( vec.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( vec.getW(), vec.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 length( const Vector4 & vec )\n{\n    return sqrtf4( lengthSqr( vec ) );\n}\n\ninline const Vector4 normalize( const Vector4 & vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = lengthSqr( vec );\n    lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );\n    return Vector4(\n        vec_madd( vec.getX(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec.getY(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec.getZ(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( vec.getW(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 )\n{\n    return Vector4(\n        vec_sel( vec0.getX(), vec1.getX(), select1 ),\n        vec_sel( vec0.getY(), vec1.getY(), select1 ),\n        vec_sel( vec0.getZ(), vec1.getZ(), select1 ),\n        vec_sel( vec0.getW(), vec1.getW(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector4 & vec )\n{\n    Aos::Vector4 vec0, vec1, vec2, vec3;\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Vector4 & vec, const char * name )\n{\n    Aos::Vector4 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\ninline Point3::Point3( const Point3 & pnt )\n{\n    mX = pnt.mX;\n    mY = pnt.mY;\n    mZ = pnt.mZ;\n}\n\ninline Point3::Point3( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n}\n\ninline Point3::Point3( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n}\n\ninline Point3::Point3( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n}\n\ninline Point3::Point3( Aos::Point3 pnt )\n{\n    vec_float4 vec128 = pnt.get128();\n    mX = vec_splat( vec128, 0 );\n    mY = vec_splat( vec128, 1 );\n    mZ = vec_splat( vec128, 2 );\n}\n\ninline Point3::Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = vec_mergeh( pnt0.get128(), pnt2.get128() );\n    tmp1 = vec_mergeh( pnt1.get128(), pnt3.get128() );\n    tmp2 = vec_mergel( pnt0.get128(), pnt2.get128() );\n    tmp3 = vec_mergel( pnt1.get128(), pnt3.get128() );\n    mX = vec_mergeh( tmp0, tmp1 );\n    mY = vec_mergel( tmp0, tmp1 );\n    mZ = vec_mergeh( tmp2, tmp3 );\n}\n\ninline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) );\n}\n\ninline void Point3::get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = vec_mergeh( mX, mZ );\n    tmp1 = vec_mergel( mX, mZ );\n    result0 = Aos::Point3( vec_mergeh( tmp0, mY ) );\n    result1 = Aos::Point3( vec_perm( tmp0, mY, _VECTORMATH_PERM_ZBWX ) );\n    result2 = Aos::Point3( vec_perm( tmp1, mY, _VECTORMATH_PERM_XCYX ) );\n    result3 = Aos::Point3( vec_perm( tmp1, mY, _VECTORMATH_PERM_ZDWX ) );\n}\n\ninline void loadXYZArray( Point3 & vec, const vec_float4 * threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = vec_sld( yzxy, xyzx, 8 );\n    zxzx = vec_sld( xyzx, zxyz, 8 );\n    yzyz = vec_sld( zxyz, yzxy, 8 );\n    vec.setX( vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) );\n    vec.setY( vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) );\n    vec.setZ( vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) );\n}\n\ninline void storeXYZArray( const Point3 & vec, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = vec_perm( vec.getX(), vec.getY(), _VECTORMATH_PERM_ZCXA );\n    zxzx = vec_perm( vec.getZ(), vec.getX(), _VECTORMATH_PERM_XBZD );\n    yzyz = vec_perm( vec.getY(), vec.getZ(), _VECTORMATH_PERM_WDYB );\n    xyzx = vec_sld( xyxy, zxzx, 8 );\n    yzxy = vec_sld( yzyz, xyxy, 8 );\n    zxyz = vec_sld( zxzx, yzyz, 8 );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( pnt0, xyz0 );\n    storeXYZArray( pnt1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Point3 & Point3::operator =( const Point3 & pnt )\n{\n    mX = pnt.mX;\n    mY = pnt.mY;\n    mZ = pnt.mZ;\n    return *this;\n}\n\ninline Point3 & Point3::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Point3::getX( ) const\n{\n    return mX;\n}\n\ninline Point3 & Point3::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Point3::getY( ) const\n{\n    return mY;\n}\n\ninline Point3 & Point3::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Point3::getZ( ) const\n{\n    return mZ;\n}\n\ninline Point3 & Point3::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Point3::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Point3::vec_float4_t & Point3::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Point3::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector3 Point3::operator -( const Point3 & pnt ) const\n{\n    return Vector3(\n        vec_sub( mX, pnt.mX ),\n        vec_sub( mY, pnt.mY ),\n        vec_sub( mZ, pnt.mZ )\n    );\n}\n\ninline const Point3 Point3::operator +( const Vector3 & vec ) const\n{\n    return Point3(\n        vec_add( mX, vec.getX() ),\n        vec_add( mY, vec.getY() ),\n        vec_add( mZ, vec.getZ() )\n    );\n}\n\ninline const Point3 Point3::operator -( const Vector3 & vec ) const\n{\n    return Point3(\n        vec_sub( mX, vec.getX() ),\n        vec_sub( mY, vec.getY() ),\n        vec_sub( mZ, vec.getZ() )\n    );\n}\n\ninline Point3 & Point3::operator +=( const Vector3 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Point3 & Point3::operator -=( const Vector3 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        vec_madd( pnt0.getX(), pnt1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( pnt0.getY(), pnt1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ),\n        vec_madd( pnt0.getZ(), pnt1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) )\n    );\n}\n\ninline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        divf4( pnt0.getX(), pnt1.getX() ),\n        divf4( pnt0.getY(), pnt1.getY() ),\n        divf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline const Point3 recipPerElem( const Point3 & pnt )\n{\n    return Point3(\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt.getX() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt.getY() ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt.getZ() )\n    );\n}\n\ninline const Point3 sqrtPerElem( const Point3 & pnt )\n{\n    return Point3(\n        sqrtf4( pnt.getX() ),\n        sqrtf4( pnt.getY() ),\n        sqrtf4( pnt.getZ() )\n    );\n}\n\ninline const Point3 rsqrtPerElem( const Point3 & pnt )\n{\n    return Point3(\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt.getX() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt.getY() ) ),\n        divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt.getZ() ) )\n    );\n}\n\ninline const Point3 absPerElem( const Point3 & pnt )\n{\n    return Point3(\n        fabsf4( pnt.getX() ),\n        fabsf4( pnt.getY() ),\n        fabsf4( pnt.getZ() )\n    );\n}\n\ninline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        copysignf4( pnt0.getX(), pnt1.getX() ),\n        copysignf4( pnt0.getY(), pnt1.getY() ),\n        copysignf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        fmaxf4( pnt0.getX(), pnt1.getX() ),\n        fmaxf4( pnt0.getY(), pnt1.getY() ),\n        fmaxf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline vec_float4 maxElem( const Point3 & pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( pnt.getX(), pnt.getY() );\n    result = fmaxf4( pnt.getZ(), result );\n    return result;\n}\n\ninline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        fminf4( pnt0.getX(), pnt1.getX() ),\n        fminf4( pnt0.getY(), pnt1.getY() ),\n        fminf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline vec_float4 minElem( const Point3 & pnt )\n{\n    vec_float4 result;\n    result = fminf4( pnt.getX(), pnt.getY() );\n    result = fminf4( pnt.getZ(), result );\n    return result;\n}\n\ninline vec_float4 sum( const Point3 & pnt )\n{\n    vec_float4 result;\n    result = vec_add( pnt.getX(), pnt.getY() );\n    result = vec_add( result, pnt.getZ() );\n    return result;\n}\n\ninline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal )\n{\n    return mulPerElem( pnt, Point3( scaleVal ) );\n}\n\ninline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec )\n{\n    return mulPerElem( pnt, Point3( scaleVec ) );\n}\n\ninline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec )\n{\n    vec_float4 result;\n    result = vec_madd( pnt.getX(), unitVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );\n    result = vec_add( result, vec_madd( pnt.getY(), unitVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    result = vec_add( result, vec_madd( pnt.getZ(), unitVec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );\n    return result;\n}\n\ninline vec_float4 distSqrFromOrigin( const Point3 & pnt )\n{\n    return lengthSqr( Vector3( pnt ) );\n}\n\ninline vec_float4 distFromOrigin( const Point3 & pnt )\n{\n    return length( Vector3( pnt ) );\n}\n\ninline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return lengthSqr( ( pnt1 - pnt0 ) );\n}\n\ninline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return length( ( pnt1 - pnt0 ) );\n}\n\ninline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 )\n{\n    return Point3(\n        vec_sel( pnt0.getX(), pnt1.getX(), select1 ),\n        vec_sel( pnt0.getY(), pnt1.getY(), select1 ),\n        vec_sel( pnt0.getZ(), pnt1.getZ(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Point3 & pnt )\n{\n    Aos::Point3 vec0, vec1, vec2, vec3;\n    pnt.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Point3 & pnt, const char * name )\n{\n    Aos::Point3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    pnt.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\n} // namespace Soa\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/vecidx_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VECIDX_AOS_H\n#define _VECTORMATH_VECIDX_AOS_H\n\n#include \"floatInVec.h\"\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// VecIdx \n// Used in setting elements of Vector3, Vector4, Point3, or Quat with the \n// subscripting operator.\n//\n\nclass VecIdx\n{\nprivate:\n    typedef vec_float4 vec_float4_t;\n    vec_float4_t &ref __attribute__ ((aligned(16)));\n    int i __attribute__ ((aligned(16)));\npublic:\n    inline VecIdx( vec_float4_t& vec, int idx ): ref(vec) { i = idx; }\n\n    // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined\n    // in which case, implicitly casts to floatInVec, and one must call\n    // getAsFloat to convert to float.\n    //\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n    inline operator floatInVec() const;\n    inline float getAsFloat() const;\n#else\n    inline operator float() const;\n#endif\n\n    inline float operator =( float scalar );\n    inline floatInVec operator =( floatInVec scalar );\n    inline floatInVec operator =( const VecIdx& scalar );\n    inline floatInVec operator *=( float scalar );\n    inline floatInVec operator *=( floatInVec scalar );\n    inline floatInVec operator /=( float scalar );\n    inline floatInVec operator /=( floatInVec scalar );\n    inline floatInVec operator +=( float scalar );\n    inline floatInVec operator +=( floatInVec scalar );\n    inline floatInVec operator -=( float scalar );\n    inline floatInVec operator -=( floatInVec scalar );\n};\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_CPP_PPU_H\n#define _VECTORMATH_AOS_CPP_PPU_H\n\n#include <math.h>\n#include <altivec.h>\n#include \"vecidx_aos.h\"\n#include \"floatInVec.h\"\n#include \"boolInVec.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\nnamespace Vectormath {\n\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Forward Declarations\n//\n\nclass Vector3;\nclass Vector4;\nclass Point3;\nclass Quat;\nclass Matrix3;\nclass Matrix4;\nclass Transform3;\n\n// A 3-D vector in array-of-structures format\n//\nclass Vector3\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector3( ) { };\n\n    // Construct a 3-D vector from x, y, and z elements\n    // \n    inline Vector3( float x, float y, float z );\n\n    // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type)\n    // \n    inline Vector3( floatInVec x, floatInVec y, floatInVec z );\n\n    // Copy elements from a 3-D point into a 3-D vector\n    // \n    explicit inline Vector3( Point3 pnt );\n\n    // Set all elements of a 3-D vector to the same scalar value\n    // \n    explicit inline Vector3( float scalar );\n\n    // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Vector3( floatInVec scalar );\n\n    // Set vector float data in a 3-D vector\n    // \n    explicit inline Vector3( vec_float4 vf4 );\n\n    // Get vector float data from a 3-D vector\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one 3-D vector to another\n    // \n    inline Vector3 & operator =( Vector3 vec );\n\n    // Set the x element of a 3-D vector\n    // \n    inline Vector3 & setX( float x );\n\n    // Set the y element of a 3-D vector\n    // \n    inline Vector3 & setY( float y );\n\n    // Set the z element of a 3-D vector\n    // \n    inline Vector3 & setZ( float z );\n\n    // Set the x element of a 3-D vector (scalar data contained in vector data type)\n    // \n    inline Vector3 & setX( floatInVec x );\n\n    // Set the y element of a 3-D vector (scalar data contained in vector data type)\n    // \n    inline Vector3 & setY( floatInVec y );\n\n    // Set the z element of a 3-D vector (scalar data contained in vector data type)\n    // \n    inline Vector3 & setZ( floatInVec z );\n\n    // Get the x element of a 3-D vector\n    // \n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a 3-D vector\n    // \n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a 3-D vector\n    // \n    inline const floatInVec getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D vector by index\n    // \n    inline Vector3 & setElem( int idx, float value );\n\n    // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type)\n    // \n    inline Vector3 & setElem( int idx, floatInVec value );\n\n    // Get an x, y, or z element of a 3-D vector by index\n    // \n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline const floatInVec operator []( int idx ) const;\n\n    // Add two 3-D vectors\n    // \n    inline const Vector3 operator +( Vector3 vec ) const;\n\n    // Subtract a 3-D vector from another 3-D vector\n    // \n    inline const Vector3 operator -( Vector3 vec ) const;\n\n    // Add a 3-D vector to a 3-D point\n    // \n    inline const Point3 operator +( Point3 pnt ) const;\n\n    // Multiply a 3-D vector by a scalar\n    // \n    inline const Vector3 operator *( float scalar ) const;\n\n    // Divide a 3-D vector by a scalar\n    // \n    inline const Vector3 operator /( float scalar ) const;\n\n    // Multiply a 3-D vector by a scalar (scalar data contained in vector data type)\n    // \n    inline const Vector3 operator *( floatInVec scalar ) const;\n\n    // Divide a 3-D vector by a scalar (scalar data contained in vector data type)\n    // \n    inline const Vector3 operator /( floatInVec scalar ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Vector3 & operator +=( Vector3 vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Vector3 & operator -=( Vector3 vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector3 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector3 & operator /=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    // \n    inline Vector3 & operator *=( floatInVec scalar );\n\n    // Perform compound assignment and division by a scalar (scalar data contained in vector data type)\n    // \n    inline Vector3 & operator /=( floatInVec scalar );\n\n    // Negate all elements of a 3-D vector\n    // \n    inline const Vector3 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector3 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector3 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector3 zAxis( );\n\n};\n\n// Multiply a 3-D vector by a scalar\n// \ninline const Vector3 operator *( float scalar, Vector3 vec );\n\n// Multiply a 3-D vector by a scalar (scalar data contained in vector data type)\n// \ninline const Vector3 operator *( floatInVec scalar, Vector3 vec );\n\n// Multiply two 3-D vectors per element\n// \ninline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Divide two 3-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Compute the reciprocal of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector3 recipPerElem( Vector3 vec );\n\n// Compute the square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector3 sqrtPerElem( Vector3 vec );\n\n// Compute the reciprocal square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector3 rsqrtPerElem( Vector3 vec );\n\n// Compute the absolute value of a 3-D vector per element\n// \ninline const Vector3 absPerElem( Vector3 vec );\n\n// Copy sign from one 3-D vector to another, per element\n// \ninline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Maximum of two 3-D vectors per element\n// \ninline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Minimum of two 3-D vectors per element\n// \ninline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Maximum element of a 3-D vector\n// \ninline const floatInVec maxElem( Vector3 vec );\n\n// Minimum element of a 3-D vector\n// \ninline const floatInVec minElem( Vector3 vec );\n\n// Compute the sum of all elements of a 3-D vector\n// \ninline const floatInVec sum( Vector3 vec );\n\n// Compute the dot product of two 3-D vectors\n// \ninline const floatInVec dot( Vector3 vec0, Vector3 vec1 );\n\n// Compute the square of the length of a 3-D vector\n// \ninline const floatInVec lengthSqr( Vector3 vec );\n\n// Compute the length of a 3-D vector\n// \ninline const floatInVec length( Vector3 vec );\n\n// Normalize a 3-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector3 normalize( Vector3 vec );\n\n// Compute cross product of two 3-D vectors\n// \ninline const Vector3 cross( Vector3 vec0, Vector3 vec1 );\n\n// Outer product of two 3-D vectors\n// \ninline const Matrix3 outer( Vector3 vec0, Vector3 vec1 );\n\n// Pre-multiply a row vector by a 3x3 matrix\n// NOTE: \n// Slower than column post-multiply.\n// \ninline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat );\n\n// Cross-product matrix of a 3-D vector\n// \ninline const Matrix3 crossMatrix( Vector3 vec );\n\n// Create cross-product matrix and multiply\n// NOTE: \n// Faster than separately creating a cross-product matrix and multiplying.\n// \ninline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat );\n\n// Linear interpolation between two 3-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 );\n\n// Linear interpolation between two 3-D vectors (scalar data contained in vector data type)\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 lerp( floatInVec t, Vector3 vec0, Vector3 vec1 );\n\n// Spherical linear interpolation between two 3-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 );\n\n// Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type)\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 slerp( floatInVec t, Vector3 unitVec0, Vector3 unitVec1 );\n\n// Conditionally select between two 3-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 );\n\n// Conditionally select between two 3-D vectors (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector3 select( Vector3 vec0, Vector3 vec1, boolInVec select1 );\n\n// Store x, y, and z elements of a 3-D vector in the first three words of a quadword.\n// The value of the fourth word (the word with the highest address) remains unchanged\n// \ninline void storeXYZ( Vector3 vec, vec_float4 * quad );\n\n// Load four three-float 3-D vectors, stored in three quadwords\n// \ninline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads );\n\n// Store four 3-D vectors in three quadwords\n// \ninline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads );\n\n// Store eight 3-D vectors as half-floats\n// \ninline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector3 vec );\n\n// Print a 3-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector3 vec, const char * name );\n\n#endif\n\n// A 4-D vector in array-of-structures format\n//\nclass Vector4\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector4( ) { };\n\n    // Construct a 4-D vector from x, y, z, and w elements\n    // \n    inline Vector4( float x, float y, float z, float w );\n\n    // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type)\n    // \n    inline Vector4( floatInVec x, floatInVec y, floatInVec z, floatInVec w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar\n    // \n    inline Vector4( Vector3 xyz, float w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type)\n    // \n    inline Vector4( Vector3 xyz, floatInVec w );\n\n    // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n    // \n    explicit inline Vector4( Vector3 vec );\n\n    // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n    // \n    explicit inline Vector4( Point3 pnt );\n\n    // Copy elements from a quaternion into a 4-D vector\n    // \n    explicit inline Vector4( Quat quat );\n\n    // Set all elements of a 4-D vector to the same scalar value\n    // \n    explicit inline Vector4( float scalar );\n\n    // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Vector4( floatInVec scalar );\n\n    // Set vector float data in a 4-D vector\n    // \n    explicit inline Vector4( vec_float4 vf4 );\n\n    // Get vector float data from a 4-D vector\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one 4-D vector to another\n    // \n    inline Vector4 & operator =( Vector4 vec );\n\n    // Set the x, y, and z elements of a 4-D vector\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Vector4 & setXYZ( Vector3 vec );\n\n    // Get the x, y, and z elements of a 4-D vector\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a 4-D vector\n    // \n    inline Vector4 & setX( float x );\n\n    // Set the y element of a 4-D vector\n    // \n    inline Vector4 & setY( float y );\n\n    // Set the z element of a 4-D vector\n    // \n    inline Vector4 & setZ( float z );\n\n    // Set the w element of a 4-D vector\n    // \n    inline Vector4 & setW( float w );\n\n    // Set the x element of a 4-D vector (scalar data contained in vector data type)\n    // \n    inline Vector4 & setX( floatInVec x );\n\n    // Set the y element of a 4-D vector (scalar data contained in vector data type)\n    // \n    inline Vector4 & setY( floatInVec y );\n\n    // Set the z element of a 4-D vector (scalar data contained in vector data type)\n    // \n    inline Vector4 & setZ( floatInVec z );\n\n    // Set the w element of a 4-D vector (scalar data contained in vector data type)\n    // \n    inline Vector4 & setW( floatInVec w );\n\n    // Get the x element of a 4-D vector\n    // \n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a 4-D vector\n    // \n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a 4-D vector\n    // \n    inline const floatInVec getZ( ) const;\n\n    // Get the w element of a 4-D vector\n    // \n    inline const floatInVec getW( ) const;\n\n    // Set an x, y, z, or w element of a 4-D vector by index\n    // \n    inline Vector4 & setElem( int idx, float value );\n\n    // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type)\n    // \n    inline Vector4 & setElem( int idx, floatInVec value );\n\n    // Get an x, y, z, or w element of a 4-D vector by index\n    // \n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline const floatInVec operator []( int idx ) const;\n\n    // Add two 4-D vectors\n    // \n    inline const Vector4 operator +( Vector4 vec ) const;\n\n    // Subtract a 4-D vector from another 4-D vector\n    // \n    inline const Vector4 operator -( Vector4 vec ) const;\n\n    // Multiply a 4-D vector by a scalar\n    // \n    inline const Vector4 operator *( float scalar ) const;\n\n    // Divide a 4-D vector by a scalar\n    // \n    inline const Vector4 operator /( float scalar ) const;\n\n    // Multiply a 4-D vector by a scalar (scalar data contained in vector data type)\n    // \n    inline const Vector4 operator *( floatInVec scalar ) const;\n\n    // Divide a 4-D vector by a scalar (scalar data contained in vector data type)\n    // \n    inline const Vector4 operator /( floatInVec scalar ) const;\n\n    // Perform compound assignment and addition with a 4-D vector\n    // \n    inline Vector4 & operator +=( Vector4 vec );\n\n    // Perform compound assignment and subtraction by a 4-D vector\n    // \n    inline Vector4 & operator -=( Vector4 vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector4 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector4 & operator /=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    // \n    inline Vector4 & operator *=( floatInVec scalar );\n\n    // Perform compound assignment and division by a scalar (scalar data contained in vector data type)\n    // \n    inline Vector4 & operator /=( floatInVec scalar );\n\n    // Negate all elements of a 4-D vector\n    // \n    inline const Vector4 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector4 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector4 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector4 zAxis( );\n\n    // Construct w axis\n    // \n    static inline const Vector4 wAxis( );\n\n};\n\n// Multiply a 4-D vector by a scalar\n// \ninline const Vector4 operator *( float scalar, Vector4 vec );\n\n// Multiply a 4-D vector by a scalar (scalar data contained in vector data type)\n// \ninline const Vector4 operator *( floatInVec scalar, Vector4 vec );\n\n// Multiply two 4-D vectors per element\n// \ninline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Divide two 4-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Compute the reciprocal of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector4 recipPerElem( Vector4 vec );\n\n// Compute the square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector4 sqrtPerElem( Vector4 vec );\n\n// Compute the reciprocal square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector4 rsqrtPerElem( Vector4 vec );\n\n// Compute the absolute value of a 4-D vector per element\n// \ninline const Vector4 absPerElem( Vector4 vec );\n\n// Copy sign from one 4-D vector to another, per element\n// \ninline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Maximum of two 4-D vectors per element\n// \ninline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Minimum of two 4-D vectors per element\n// \ninline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Maximum element of a 4-D vector\n// \ninline const floatInVec maxElem( Vector4 vec );\n\n// Minimum element of a 4-D vector\n// \ninline const floatInVec minElem( Vector4 vec );\n\n// Compute the sum of all elements of a 4-D vector\n// \ninline const floatInVec sum( Vector4 vec );\n\n// Compute the dot product of two 4-D vectors\n// \ninline const floatInVec dot( Vector4 vec0, Vector4 vec1 );\n\n// Compute the square of the length of a 4-D vector\n// \ninline const floatInVec lengthSqr( Vector4 vec );\n\n// Compute the length of a 4-D vector\n// \ninline const floatInVec length( Vector4 vec );\n\n// Normalize a 4-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector4 normalize( Vector4 vec );\n\n// Outer product of two 4-D vectors\n// \ninline const Matrix4 outer( Vector4 vec0, Vector4 vec1 );\n\n// Linear interpolation between two 4-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 );\n\n// Linear interpolation between two 4-D vectors (scalar data contained in vector data type)\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 lerp( floatInVec t, Vector4 vec0, Vector4 vec1 );\n\n// Spherical linear interpolation between two 4-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 );\n\n// Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type)\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 slerp( floatInVec t, Vector4 unitVec0, Vector4 unitVec1 );\n\n// Conditionally select between two 4-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 );\n\n// Conditionally select between two 4-D vectors (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector4 select( Vector4 vec0, Vector4 vec1, boolInVec select1 );\n\n// Store four 4-D vectors as half-floats\n// \ninline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector4 vec );\n\n// Print a 4-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector4 vec, const char * name );\n\n#endif\n\n// A 3-D point in array-of-structures format\n//\nclass Point3\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Point3( ) { };\n\n    // Construct a 3-D point from x, y, and z elements\n    // \n    inline Point3( float x, float y, float z );\n\n    // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type)\n    // \n    inline Point3( floatInVec x, floatInVec y, floatInVec z );\n\n    // Copy elements from a 3-D vector into a 3-D point\n    // \n    explicit inline Point3( Vector3 vec );\n\n    // Set all elements of a 3-D point to the same scalar value\n    // \n    explicit inline Point3( float scalar );\n\n    // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Point3( floatInVec scalar );\n\n    // Set vector float data in a 3-D point\n    // \n    explicit inline Point3( vec_float4 vf4 );\n\n    // Get vector float data from a 3-D point\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one 3-D point to another\n    // \n    inline Point3 & operator =( Point3 pnt );\n\n    // Set the x element of a 3-D point\n    // \n    inline Point3 & setX( float x );\n\n    // Set the y element of a 3-D point\n    // \n    inline Point3 & setY( float y );\n\n    // Set the z element of a 3-D point\n    // \n    inline Point3 & setZ( float z );\n\n    // Set the x element of a 3-D point (scalar data contained in vector data type)\n    // \n    inline Point3 & setX( floatInVec x );\n\n    // Set the y element of a 3-D point (scalar data contained in vector data type)\n    // \n    inline Point3 & setY( floatInVec y );\n\n    // Set the z element of a 3-D point (scalar data contained in vector data type)\n    // \n    inline Point3 & setZ( floatInVec z );\n\n    // Get the x element of a 3-D point\n    // \n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a 3-D point\n    // \n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a 3-D point\n    // \n    inline const floatInVec getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D point by index\n    // \n    inline Point3 & setElem( int idx, float value );\n\n    // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type)\n    // \n    inline Point3 & setElem( int idx, floatInVec value );\n\n    // Get an x, y, or z element of a 3-D point by index\n    // \n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline const floatInVec operator []( int idx ) const;\n\n    // Subtract a 3-D point from another 3-D point\n    // \n    inline const Vector3 operator -( Point3 pnt ) const;\n\n    // Add a 3-D point to a 3-D vector\n    // \n    inline const Point3 operator +( Vector3 vec ) const;\n\n    // Subtract a 3-D vector from a 3-D point\n    // \n    inline const Point3 operator -( Vector3 vec ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Point3 & operator +=( Vector3 vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Point3 & operator -=( Vector3 vec );\n\n};\n\n// Multiply two 3-D points per element\n// \ninline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Divide two 3-D points per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Compute the reciprocal of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Point3 recipPerElem( Point3 pnt );\n\n// Compute the square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Point3 sqrtPerElem( Point3 pnt );\n\n// Compute the reciprocal square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Point3 rsqrtPerElem( Point3 pnt );\n\n// Compute the absolute value of a 3-D point per element\n// \ninline const Point3 absPerElem( Point3 pnt );\n\n// Copy sign from one 3-D point to another, per element\n// \ninline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Maximum of two 3-D points per element\n// \ninline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Minimum of two 3-D points per element\n// \ninline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Maximum element of a 3-D point\n// \ninline const floatInVec maxElem( Point3 pnt );\n\n// Minimum element of a 3-D point\n// \ninline const floatInVec minElem( Point3 pnt );\n\n// Compute the sum of all elements of a 3-D point\n// \ninline const floatInVec sum( Point3 pnt );\n\n// Apply uniform scale to a 3-D point\n// \ninline const Point3 scale( Point3 pnt, float scaleVal );\n\n// Apply uniform scale to a 3-D point (scalar data contained in vector data type)\n// \ninline const Point3 scale( Point3 pnt, floatInVec scaleVal );\n\n// Apply non-uniform scale to a 3-D point\n// \ninline const Point3 scale( Point3 pnt, Vector3 scaleVec );\n\n// Scalar projection of a 3-D point on a unit-length 3-D vector\n// \ninline const floatInVec projection( Point3 pnt, Vector3 unitVec );\n\n// Compute the square of the distance of a 3-D point from the coordinate-system origin\n// \ninline const floatInVec distSqrFromOrigin( Point3 pnt );\n\n// Compute the distance of a 3-D point from the coordinate-system origin\n// \ninline const floatInVec distFromOrigin( Point3 pnt );\n\n// Compute the square of the distance between two 3-D points\n// \ninline const floatInVec distSqr( Point3 pnt0, Point3 pnt1 );\n\n// Compute the distance between two 3-D points\n// \ninline const floatInVec dist( Point3 pnt0, Point3 pnt1 );\n\n// Linear interpolation between two 3-D points\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 );\n\n// Linear interpolation between two 3-D points (scalar data contained in vector data type)\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Point3 lerp( floatInVec t, Point3 pnt0, Point3 pnt1 );\n\n// Conditionally select between two 3-D points\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 );\n\n// Conditionally select between two 3-D points (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Point3 select( Point3 pnt0, Point3 pnt1, boolInVec select1 );\n\n// Store x, y, and z elements of a 3-D point in the first three words of a quadword.\n// The value of the fourth word (the word with the highest address) remains unchanged\n// \ninline void storeXYZ( Point3 pnt, vec_float4 * quad );\n\n// Load four three-float 3-D points, stored in three quadwords\n// \ninline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads );\n\n// Store four 3-D points in three quadwords\n// \ninline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads );\n\n// Store eight 3-D points as half-floats\n// \ninline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D point\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Point3 pnt );\n\n// Print a 3-D point and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Point3 pnt, const char * name );\n\n#endif\n\n// A quaternion in array-of-structures format\n//\nclass Quat\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Quat( ) { };\n\n    // Construct a quaternion from x, y, z, and w elements\n    // \n    inline Quat( float x, float y, float z, float w );\n\n    // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type)\n    // \n    inline Quat( floatInVec x, floatInVec y, floatInVec z, floatInVec w );\n\n    // Construct a quaternion from a 3-D vector and a scalar\n    // \n    inline Quat( Vector3 xyz, float w );\n\n    // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type)\n    // \n    inline Quat( Vector3 xyz, floatInVec w );\n\n    // Copy elements from a 4-D vector into a quaternion\n    // \n    explicit inline Quat( Vector4 vec );\n\n    // Convert a rotation matrix to a unit-length quaternion\n    // \n    explicit inline Quat( const Matrix3 & rotMat );\n\n    // Set all elements of a quaternion to the same scalar value\n    // \n    explicit inline Quat( float scalar );\n\n    // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Quat( floatInVec scalar );\n\n    // Set vector float data in a quaternion\n    // \n    explicit inline Quat( vec_float4 vf4 );\n\n    // Get vector float data from a quaternion\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one quaternion to another\n    // \n    inline Quat & operator =( Quat quat );\n\n    // Set the x, y, and z elements of a quaternion\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Quat & setXYZ( Vector3 vec );\n\n    // Get the x, y, and z elements of a quaternion\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a quaternion\n    // \n    inline Quat & setX( float x );\n\n    // Set the y element of a quaternion\n    // \n    inline Quat & setY( float y );\n\n    // Set the z element of a quaternion\n    // \n    inline Quat & setZ( float z );\n\n    // Set the w element of a quaternion\n    // \n    inline Quat & setW( float w );\n\n    // Set the x element of a quaternion (scalar data contained in vector data type)\n    // \n    inline Quat & setX( floatInVec x );\n\n    // Set the y element of a quaternion (scalar data contained in vector data type)\n    // \n    inline Quat & setY( floatInVec y );\n\n    // Set the z element of a quaternion (scalar data contained in vector data type)\n    // \n    inline Quat & setZ( floatInVec z );\n\n    // Set the w element of a quaternion (scalar data contained in vector data type)\n    // \n    inline Quat & setW( floatInVec w );\n\n    // Get the x element of a quaternion\n    // \n    inline const floatInVec getX( ) const;\n\n    // Get the y element of a quaternion\n    // \n    inline const floatInVec getY( ) const;\n\n    // Get the z element of a quaternion\n    // \n    inline const floatInVec getZ( ) const;\n\n    // Get the w element of a quaternion\n    // \n    inline const floatInVec getW( ) const;\n\n    // Set an x, y, z, or w element of a quaternion by index\n    // \n    inline Quat & setElem( int idx, float value );\n\n    // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type)\n    // \n    inline Quat & setElem( int idx, floatInVec value );\n\n    // Get an x, y, z, or w element of a quaternion by index\n    // \n    inline const floatInVec getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline const floatInVec operator []( int idx ) const;\n\n    // Add two quaternions\n    // \n    inline const Quat operator +( Quat quat ) const;\n\n    // Subtract a quaternion from another quaternion\n    // \n    inline const Quat operator -( Quat quat ) const;\n\n    // Multiply two quaternions\n    // \n    inline const Quat operator *( Quat quat ) const;\n\n    // Multiply a quaternion by a scalar\n    // \n    inline const Quat operator *( float scalar ) const;\n\n    // Divide a quaternion by a scalar\n    // \n    inline const Quat operator /( float scalar ) const;\n\n    // Multiply a quaternion by a scalar (scalar data contained in vector data type)\n    // \n    inline const Quat operator *( floatInVec scalar ) const;\n\n    // Divide a quaternion by a scalar (scalar data contained in vector data type)\n    // \n    inline const Quat operator /( floatInVec scalar ) const;\n\n    // Perform compound assignment and addition with a quaternion\n    // \n    inline Quat & operator +=( Quat quat );\n\n    // Perform compound assignment and subtraction by a quaternion\n    // \n    inline Quat & operator -=( Quat quat );\n\n    // Perform compound assignment and multiplication by a quaternion\n    // \n    inline Quat & operator *=( Quat quat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Quat & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Quat & operator /=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    // \n    inline Quat & operator *=( floatInVec scalar );\n\n    // Perform compound assignment and division by a scalar (scalar data contained in vector data type)\n    // \n    inline Quat & operator /=( floatInVec scalar );\n\n    // Negate all elements of a quaternion\n    // \n    inline const Quat operator -( ) const;\n\n    // Construct an identity quaternion\n    // \n    static inline const Quat identity( );\n\n    // Construct a quaternion to rotate between two unit-length 3-D vectors\n    // NOTE: \n    // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n    // \n    static inline const Quat rotation( Vector3 unitVec0, Vector3 unitVec1 );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector\n    // \n    static inline const Quat rotation( float radians, Vector3 unitVec );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    // \n    static inline const Quat rotation( floatInVec radians, Vector3 unitVec );\n\n    // Construct a quaternion to rotate around the x axis\n    // \n    static inline const Quat rotationX( float radians );\n\n    // Construct a quaternion to rotate around the y axis\n    // \n    static inline const Quat rotationY( float radians );\n\n    // Construct a quaternion to rotate around the z axis\n    // \n    static inline const Quat rotationZ( float radians );\n\n    // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type)\n    // \n    static inline const Quat rotationX( floatInVec radians );\n\n    // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type)\n    // \n    static inline const Quat rotationY( floatInVec radians );\n\n    // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type)\n    // \n    static inline const Quat rotationZ( floatInVec radians );\n\n};\n\n// Multiply a quaternion by a scalar\n// \ninline const Quat operator *( float scalar, Quat quat );\n\n// Multiply a quaternion by a scalar (scalar data contained in vector data type)\n// \ninline const Quat operator *( floatInVec scalar, Quat quat );\n\n// Compute the conjugate of a quaternion\n// \ninline const Quat conj( Quat quat );\n\n// Use a unit-length quaternion to rotate a 3-D vector\n// \ninline const Vector3 rotate( Quat unitQuat, Vector3 vec );\n\n// Compute the dot product of two quaternions\n// \ninline const floatInVec dot( Quat quat0, Quat quat1 );\n\n// Compute the norm of a quaternion\n// \ninline const floatInVec norm( Quat quat );\n\n// Compute the length of a quaternion\n// \ninline const floatInVec length( Quat quat );\n\n// Normalize a quaternion\n// NOTE: \n// The result is unpredictable when all elements of quat are at or near zero.\n// \ninline const Quat normalize( Quat quat );\n\n// Linear interpolation between two quaternions\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Quat lerp( float t, Quat quat0, Quat quat1 );\n\n// Linear interpolation between two quaternions (scalar data contained in vector data type)\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Quat lerp( floatInVec t, Quat quat0, Quat quat1 );\n\n// Spherical linear interpolation between two quaternions\n// NOTE: \n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n// \ninline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 );\n\n// Spherical linear interpolation between two quaternions (scalar data contained in vector data type)\n// NOTE: \n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n// \ninline const Quat slerp( floatInVec t, Quat unitQuat0, Quat unitQuat1 );\n\n// Spherical quadrangle interpolation\n// \ninline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 );\n\n// Spherical quadrangle interpolation (scalar data contained in vector data type)\n// \ninline const Quat squad( floatInVec t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 );\n\n// Conditionally select between two quaternions\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Quat select( Quat quat0, Quat quat1, bool select1 );\n\n// Conditionally select between two quaternions (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Quat select( Quat quat0, Quat quat1, boolInVec select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a quaternion\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Quat quat );\n\n// Print a quaternion and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Quat quat, const char * name );\n\n#endif\n\n// A 3x3 matrix in array-of-structures format\n//\nclass Matrix3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix3( ) { };\n\n    // Copy a 3x3 matrix\n    // \n    inline Matrix3( const Matrix3 & mat );\n\n    // Construct a 3x3 matrix containing the specified columns\n    // \n    inline Matrix3( Vector3 col0, Vector3 col1, Vector3 col2 );\n\n    // Construct a 3x3 rotation matrix from a unit-length quaternion\n    // \n    explicit inline Matrix3( Quat unitQuat );\n\n    // Set all elements of a 3x3 matrix to the same scalar value\n    // \n    explicit inline Matrix3( float scalar );\n\n    // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Matrix3( floatInVec scalar );\n\n    // Assign one 3x3 matrix to another\n    // \n    inline Matrix3 & operator =( const Matrix3 & mat );\n\n    // Set column 0 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol0( Vector3 col0 );\n\n    // Set column 1 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol1( Vector3 col1 );\n\n    // Set column 2 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol2( Vector3 col2 );\n\n    // Get column 0 of a 3x3 matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x3 matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x3 matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Set the column of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setCol( int col, Vector3 vec );\n\n    // Set the row of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setRow( int row, Vector3 vec );\n\n    // Get the column of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline Matrix3 & setElem( int col, int row, float val );\n\n    // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type)\n    // \n    inline Matrix3 & setElem( int col, int row, floatInVec val );\n\n    // Get the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline const floatInVec getElem( int col, int row ) const;\n\n    // Add two 3x3 matrices\n    // \n    inline const Matrix3 operator +( const Matrix3 & mat ) const;\n\n    // Subtract a 3x3 matrix from another 3x3 matrix\n    // \n    inline const Matrix3 operator -( const Matrix3 & mat ) const;\n\n    // Negate all elements of a 3x3 matrix\n    // \n    inline const Matrix3 operator -( ) const;\n\n    // Multiply a 3x3 matrix by a scalar\n    // \n    inline const Matrix3 operator *( float scalar ) const;\n\n    // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type)\n    // \n    inline const Matrix3 operator *( floatInVec scalar ) const;\n\n    // Multiply a 3x3 matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( Vector3 vec ) const;\n\n    // Multiply two 3x3 matrices\n    // \n    inline const Matrix3 operator *( const Matrix3 & mat ) const;\n\n    // Perform compound assignment and addition with a 3x3 matrix\n    // \n    inline Matrix3 & operator +=( const Matrix3 & mat );\n\n    // Perform compound assignment and subtraction by a 3x3 matrix\n    // \n    inline Matrix3 & operator -=( const Matrix3 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix3 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    // \n    inline Matrix3 & operator *=( floatInVec scalar );\n\n    // Perform compound assignment and multiplication by a 3x3 matrix\n    // \n    inline Matrix3 & operator *=( const Matrix3 & mat );\n\n    // Construct an identity 3x3 matrix\n    // \n    static inline const Matrix3 identity( );\n\n    // Construct a 3x3 matrix to rotate around the x axis\n    // \n    static inline const Matrix3 rotationX( float radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis\n    // \n    static inline const Matrix3 rotationY( float radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis\n    // \n    static inline const Matrix3 rotationZ( float radians );\n\n    // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type)\n    // \n    static inline const Matrix3 rotationX( floatInVec radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type)\n    // \n    static inline const Matrix3 rotationY( floatInVec radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type)\n    // \n    static inline const Matrix3 rotationZ( floatInVec radians );\n\n    // Construct a 3x3 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix3 rotationZYX( Vector3 radiansXYZ );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix3 rotation( float radians, Vector3 unitVec );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    // \n    static inline const Matrix3 rotation( floatInVec radians, Vector3 unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix3 rotation( Quat unitQuat );\n\n    // Construct a 3x3 matrix to perform scaling\n    // \n    static inline const Matrix3 scale( Vector3 scaleVec );\n\n};\n// Multiply a 3x3 matrix by a scalar\n// \ninline const Matrix3 operator *( float scalar, const Matrix3 & mat );\n\n// Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type)\n// \ninline const Matrix3 operator *( floatInVec scalar, const Matrix3 & mat );\n\n// Append (post-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat );\n\n// Multiply two 3x3 matrices per element\n// \ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );\n\n// Compute the absolute value of a 3x3 matrix per element\n// \ninline const Matrix3 absPerElem( const Matrix3 & mat );\n\n// Transpose of a 3x3 matrix\n// \ninline const Matrix3 transpose( const Matrix3 & mat );\n\n// Compute the inverse of a 3x3 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix3 inverse( const Matrix3 & mat );\n\n// Determinant of a 3x3 matrix\n// \ninline const floatInVec determinant( const Matrix3 & mat );\n\n// Conditionally select between two 3x3 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 );\n\n// Conditionally select between two 3x3 matrices (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, boolInVec select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x3 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat );\n\n// Print a 3x3 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat, const char * name );\n\n#endif\n\n// A 4x4 matrix in array-of-structures format\n//\nclass Matrix4\n{\n    Vector4 mCol0;\n    Vector4 mCol1;\n    Vector4 mCol2;\n    Vector4 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix4( ) { };\n\n    // Copy a 4x4 matrix\n    // \n    inline Matrix4( const Matrix4 & mat );\n\n    // Construct a 4x4 matrix containing the specified columns\n    // \n    inline Matrix4( Vector4 col0, Vector4 col1, Vector4 col2, Vector4 col3 );\n\n    // Construct a 4x4 matrix from a 3x4 transformation matrix\n    // \n    explicit inline Matrix4( const Transform3 & mat );\n\n    // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Matrix4( const Matrix3 & mat, Vector3 translateVec );\n\n    // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Matrix4( Quat unitQuat, Vector3 translateVec );\n\n    // Set all elements of a 4x4 matrix to the same scalar value\n    // \n    explicit inline Matrix4( float scalar );\n\n    // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Matrix4( floatInVec scalar );\n\n    // Assign one 4x4 matrix to another\n    // \n    inline Matrix4 & operator =( const Matrix4 & mat );\n\n    // Set the upper-left 3x3 submatrix\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 4x4 matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setTranslation( Vector3 translateVec );\n\n    // Get the translation component of a 4x4 matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol0( Vector4 col0 );\n\n    // Set column 1 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol1( Vector4 col1 );\n\n    // Set column 2 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol2( Vector4 col2 );\n\n    // Set column 3 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol3( Vector4 col3 );\n\n    // Get column 0 of a 4x4 matrix\n    // \n    inline const Vector4 getCol0( ) const;\n\n    // Get column 1 of a 4x4 matrix\n    // \n    inline const Vector4 getCol1( ) const;\n\n    // Get column 2 of a 4x4 matrix\n    // \n    inline const Vector4 getCol2( ) const;\n\n    // Get column 3 of a 4x4 matrix\n    // \n    inline const Vector4 getCol3( ) const;\n\n    // Set the column of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setCol( int col, Vector4 vec );\n\n    // Set the row of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setRow( int row, Vector4 vec );\n\n    // Get the column of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getCol( int col ) const;\n\n    // Get the row of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector4 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector4 operator []( int col ) const;\n\n    // Set the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline Matrix4 & setElem( int col, int row, float val );\n\n    // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type)\n    // \n    inline Matrix4 & setElem( int col, int row, floatInVec val );\n\n    // Get the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline const floatInVec getElem( int col, int row ) const;\n\n    // Add two 4x4 matrices\n    // \n    inline const Matrix4 operator +( const Matrix4 & mat ) const;\n\n    // Subtract a 4x4 matrix from another 4x4 matrix\n    // \n    inline const Matrix4 operator -( const Matrix4 & mat ) const;\n\n    // Negate all elements of a 4x4 matrix\n    // \n    inline const Matrix4 operator -( ) const;\n\n    // Multiply a 4x4 matrix by a scalar\n    // \n    inline const Matrix4 operator *( float scalar ) const;\n\n    // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type)\n    // \n    inline const Matrix4 operator *( floatInVec scalar ) const;\n\n    // Multiply a 4x4 matrix by a 4-D vector\n    // \n    inline const Vector4 operator *( Vector4 vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D vector\n    // \n    inline const Vector4 operator *( Vector3 vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D point\n    // \n    inline const Vector4 operator *( Point3 pnt ) const;\n\n    // Multiply two 4x4 matrices\n    // \n    inline const Matrix4 operator *( const Matrix4 & mat ) const;\n\n    // Multiply a 4x4 matrix by a 3x4 transformation matrix\n    // \n    inline const Matrix4 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and addition with a 4x4 matrix\n    // \n    inline Matrix4 & operator +=( const Matrix4 & mat );\n\n    // Perform compound assignment and subtraction by a 4x4 matrix\n    // \n    inline Matrix4 & operator -=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix4 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type)\n    // \n    inline Matrix4 & operator *=( floatInVec scalar );\n\n    // Perform compound assignment and multiplication by a 4x4 matrix\n    // \n    inline Matrix4 & operator *=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Matrix4 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 4x4 matrix\n    // \n    static inline const Matrix4 identity( );\n\n    // Construct a 4x4 matrix to rotate around the x axis\n    // \n    static inline const Matrix4 rotationX( float radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis\n    // \n    static inline const Matrix4 rotationY( float radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis\n    // \n    static inline const Matrix4 rotationZ( float radians );\n\n    // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type)\n    // \n    static inline const Matrix4 rotationX( floatInVec radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type)\n    // \n    static inline const Matrix4 rotationY( floatInVec radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type)\n    // \n    static inline const Matrix4 rotationZ( floatInVec radians );\n\n    // Construct a 4x4 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix4 rotationZYX( Vector3 radiansXYZ );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix4 rotation( float radians, Vector3 unitVec );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    // \n    static inline const Matrix4 rotation( floatInVec radians, Vector3 unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix4 rotation( Quat unitQuat );\n\n    // Construct a 4x4 matrix to perform scaling\n    // \n    static inline const Matrix4 scale( Vector3 scaleVec );\n\n    // Construct a 4x4 matrix to perform translation\n    // \n    static inline const Matrix4 translation( Vector3 translateVec );\n\n    // Construct viewing matrix based on eye position, position looked at, and up direction\n    // \n    static inline const Matrix4 lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec );\n\n    // Construct a perspective projection matrix\n    // \n    static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar );\n\n    // Construct a perspective projection matrix based on frustum\n    // \n    static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar );\n\n    // Construct an orthographic projection matrix\n    // \n    static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar );\n\n};\n// Multiply a 4x4 matrix by a scalar\n// \ninline const Matrix4 operator *( float scalar, const Matrix4 & mat );\n\n// Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type)\n// \ninline const Matrix4 operator *( floatInVec scalar, const Matrix4 & mat );\n\n// Append (post-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat );\n\n// Multiply two 4x4 matrices per element\n// \ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );\n\n// Compute the absolute value of a 4x4 matrix per element\n// \ninline const Matrix4 absPerElem( const Matrix4 & mat );\n\n// Transpose of a 4x4 matrix\n// \ninline const Matrix4 transpose( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 inverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 affineInverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n// \ninline const Matrix4 orthoInverse( const Matrix4 & mat );\n\n// Determinant of a 4x4 matrix\n// \ninline const floatInVec determinant( const Matrix4 & mat );\n\n// Conditionally select between two 4x4 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 );\n\n// Conditionally select between two 4x4 matrices (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, boolInVec select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4x4 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat );\n\n// Print a 4x4 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat, const char * name );\n\n#endif\n\n// A 3x4 transformation matrix in array-of-structures format\n//\nclass Transform3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n    Vector3 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Transform3( ) { };\n\n    // Copy a 3x4 transformation matrix\n    // \n    inline Transform3( const Transform3 & tfrm );\n\n    // Construct a 3x4 transformation matrix containing the specified columns\n    // \n    inline Transform3( Vector3 col0, Vector3 col1, Vector3 col2, Vector3 col3 );\n\n    // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Transform3( const Matrix3 & tfrm, Vector3 translateVec );\n\n    // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Transform3( Quat unitQuat, Vector3 translateVec );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value\n    // \n    explicit inline Transform3( float scalar );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type)\n    // \n    explicit inline Transform3( floatInVec scalar );\n\n    // Assign one 3x4 transformation matrix to another\n    // \n    inline Transform3 & operator =( const Transform3 & tfrm );\n\n    // Set the upper-left 3x3 submatrix\n    // \n    inline Transform3 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // \n    inline Transform3 & setTranslation( Vector3 translateVec );\n\n    // Get the translation component of a 3x4 transformation matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol0( Vector3 col0 );\n\n    // Set column 1 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol1( Vector3 col1 );\n\n    // Set column 2 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol2( Vector3 col2 );\n\n    // Set column 3 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol3( Vector3 col3 );\n\n    // Get column 0 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Get column 3 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol3( ) const;\n\n    // Set the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setCol( int col, Vector3 vec );\n\n    // Set the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setRow( int row, Vector4 vec );\n\n    // Get the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline Transform3 & setElem( int col, int row, float val );\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type)\n    // \n    inline Transform3 & setElem( int col, int row, floatInVec val );\n\n    // Get the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline const floatInVec getElem( int col, int row ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( Vector3 vec ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D point\n    // \n    inline const Point3 operator *( Point3 pnt ) const;\n\n    // Multiply two 3x4 transformation matrices\n    // \n    inline const Transform3 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Transform3 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 3x4 transformation matrix\n    // \n    static inline const Transform3 identity( );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis\n    // \n    static inline const Transform3 rotationX( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis\n    // \n    static inline const Transform3 rotationY( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis\n    // \n    static inline const Transform3 rotationZ( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type)\n    // \n    static inline const Transform3 rotationX( floatInVec radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type)\n    // \n    static inline const Transform3 rotationY( floatInVec radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type)\n    // \n    static inline const Transform3 rotationZ( floatInVec radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n    // \n    static inline const Transform3 rotationZYX( Vector3 radiansXYZ );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Transform3 rotation( float radians, Vector3 unitVec );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type)\n    // \n    static inline const Transform3 rotation( floatInVec radians, Vector3 unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Transform3 rotation( Quat unitQuat );\n\n    // Construct a 3x4 transformation matrix to perform scaling\n    // \n    static inline const Transform3 scale( Vector3 scaleVec );\n\n    // Construct a 3x4 transformation matrix to perform translation\n    // \n    static inline const Transform3 translation( Vector3 translateVec );\n\n};\n// Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm );\n\n// Multiply two 3x4 transformation matrices per element\n// \ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );\n\n// Compute the absolute value of a 3x4 transformation matrix per element\n// \ninline const Transform3 absPerElem( const Transform3 & tfrm );\n\n// Inverse of a 3x4 transformation matrix\n// NOTE: \n// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n// \ninline const Transform3 inverse( const Transform3 & tfrm );\n\n// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n// \ninline const Transform3 orthoInverse( const Transform3 & tfrm );\n\n// Conditionally select between two 3x4 transformation matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// However, the transfer of select1 to a VMX register may use more processing time than a branch.\n// Use the boolInVec version for better performance.\n// \ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 );\n\n// Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type)\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, boolInVec select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x4 transformation matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm );\n\n// Print a 3x4 transformation matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm, const char * name );\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/ppu/cpp/vectormath_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_CPP_PPU_H\n#define _VECTORMATH_SOA_CPP_PPU_H\n\n#include <math.h>\n#include <altivec.h>\n#include \"vectormath_aos.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\nnamespace Vectormath {\n\nnamespace Soa {\n\n//-----------------------------------------------------------------------------\n// Forward Declarations\n//\n\nclass Vector3;\nclass Vector4;\nclass Point3;\nclass Quat;\nclass Matrix3;\nclass Matrix4;\nclass Transform3;\n\n// A set of four 3-D vectors in structure-of-arrays format\n//\nclass Vector3\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector3( ) { };\n\n    // Copy a 3-D vector\n    // \n    inline Vector3( const Vector3 & vec );\n\n    // Construct a 3-D vector from x, y, and z elements\n    // \n    inline Vector3( vec_float4 x, vec_float4 y, vec_float4 z );\n\n    // Copy elements from a 3-D point into a 3-D vector\n    // \n    explicit inline Vector3( const Point3 & pnt );\n\n    // Set all elements of a 3-D vector to the same scalar value\n    // \n    explicit inline Vector3( vec_float4 scalar );\n\n    // Replicate an AoS 3-D vector\n    // \n    inline Vector3( Aos::Vector3 vec );\n\n    // Insert four AoS 3-D vectors\n    // \n    inline Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 );\n\n    // Extract four AoS 3-D vectors\n    // \n    inline void get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const;\n\n    // Assign one 3-D vector to another\n    // \n    inline Vector3 & operator =( const Vector3 & vec );\n\n    // Set the x element of a 3-D vector\n    // \n    inline Vector3 & setX( vec_float4 x );\n\n    // Set the y element of a 3-D vector\n    // \n    inline Vector3 & setY( vec_float4 y );\n\n    // Set the z element of a 3-D vector\n    // \n    inline Vector3 & setZ( vec_float4 z );\n\n    // Get the x element of a 3-D vector\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a 3-D vector\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a 3-D vector\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D vector by index\n    // \n    inline Vector3 & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, or z element of a 3-D vector by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Add two 3-D vectors\n    // \n    inline const Vector3 operator +( const Vector3 & vec ) const;\n\n    // Subtract a 3-D vector from another 3-D vector\n    // \n    inline const Vector3 operator -( const Vector3 & vec ) const;\n\n    // Add a 3-D vector to a 3-D point\n    // \n    inline const Point3 operator +( const Point3 & pnt ) const;\n\n    // Multiply a 3-D vector by a scalar\n    // \n    inline const Vector3 operator *( vec_float4 scalar ) const;\n\n    // Divide a 3-D vector by a scalar\n    // \n    inline const Vector3 operator /( vec_float4 scalar ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Vector3 & operator +=( const Vector3 & vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Vector3 & operator -=( const Vector3 & vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector3 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector3 & operator /=( vec_float4 scalar );\n\n    // Negate all elements of a 3-D vector\n    // \n    inline const Vector3 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector3 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector3 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector3 zAxis( );\n\n};\n\n// Multiply a 3-D vector by a scalar\n// \ninline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec );\n\n// Multiply two 3-D vectors per element\n// \ninline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Divide two 3-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Compute the reciprocal of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector3 recipPerElem( const Vector3 & vec );\n\n// Compute the square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector3 sqrtPerElem( const Vector3 & vec );\n\n// Compute the reciprocal square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector3 rsqrtPerElem( const Vector3 & vec );\n\n// Compute the absolute value of a 3-D vector per element\n// \ninline const Vector3 absPerElem( const Vector3 & vec );\n\n// Copy sign from one 3-D vector to another, per element\n// \ninline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Maximum of two 3-D vectors per element\n// \ninline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Minimum of two 3-D vectors per element\n// \ninline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Maximum element of a 3-D vector\n// \ninline vec_float4 maxElem( const Vector3 & vec );\n\n// Minimum element of a 3-D vector\n// \ninline vec_float4 minElem( const Vector3 & vec );\n\n// Compute the sum of all elements of a 3-D vector\n// \ninline vec_float4 sum( const Vector3 & vec );\n\n// Compute the dot product of two 3-D vectors\n// \ninline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Compute the square of the length of a 3-D vector\n// \ninline vec_float4 lengthSqr( const Vector3 & vec );\n\n// Compute the length of a 3-D vector\n// \ninline vec_float4 length( const Vector3 & vec );\n\n// Normalize a 3-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector3 normalize( const Vector3 & vec );\n\n// Compute cross product of two 3-D vectors\n// \ninline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Outer product of two 3-D vectors\n// \ninline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Pre-multiply a row vector by a 3x3 matrix\n// \ninline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat );\n\n// Cross-product matrix of a 3-D vector\n// \ninline const Matrix3 crossMatrix( const Vector3 & vec );\n\n// Create cross-product matrix and multiply\n// NOTE: \n// Faster than separately creating a cross-product matrix and multiplying.\n// \ninline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat );\n\n// Linear interpolation between two 3-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 );\n\n// Spherical linear interpolation between two 3-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 );\n\n// Conditionally select between two 3-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 );\n\n// Load four three-float 3-D vectors, stored in three quadwords\n// \ninline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads );\n\n// Store four slots of an SoA 3-D vector in three quadwords\n// \ninline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads );\n\n// Store eight slots of two SoA 3-D vectors as half-floats\n// \ninline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector3 & vec );\n\n// Print a 3-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector3 & vec, const char * name );\n\n#endif\n\n// A set of four 4-D vectors in structure-of-arrays format\n//\nclass Vector4\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n    vec_float4 mW;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector4( ) { };\n\n    // Copy a 4-D vector\n    // \n    inline Vector4( const Vector4 & vec );\n\n    // Construct a 4-D vector from x, y, z, and w elements\n    // \n    inline Vector4( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar\n    // \n    inline Vector4( const Vector3 & xyz, vec_float4 w );\n\n    // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n    // \n    explicit inline Vector4( const Vector3 & vec );\n\n    // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n    // \n    explicit inline Vector4( const Point3 & pnt );\n\n    // Copy elements from a quaternion into a 4-D vector\n    // \n    explicit inline Vector4( const Quat & quat );\n\n    // Set all elements of a 4-D vector to the same scalar value\n    // \n    explicit inline Vector4( vec_float4 scalar );\n\n    // Replicate an AoS 4-D vector\n    // \n    inline Vector4( Aos::Vector4 vec );\n\n    // Insert four AoS 4-D vectors\n    // \n    inline Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 );\n\n    // Extract four AoS 4-D vectors\n    // \n    inline void get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const;\n\n    // Assign one 4-D vector to another\n    // \n    inline Vector4 & operator =( const Vector4 & vec );\n\n    // Set the x, y, and z elements of a 4-D vector\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Vector4 & setXYZ( const Vector3 & vec );\n\n    // Get the x, y, and z elements of a 4-D vector\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a 4-D vector\n    // \n    inline Vector4 & setX( vec_float4 x );\n\n    // Set the y element of a 4-D vector\n    // \n    inline Vector4 & setY( vec_float4 y );\n\n    // Set the z element of a 4-D vector\n    // \n    inline Vector4 & setZ( vec_float4 z );\n\n    // Set the w element of a 4-D vector\n    // \n    inline Vector4 & setW( vec_float4 w );\n\n    // Get the x element of a 4-D vector\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a 4-D vector\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a 4-D vector\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Get the w element of a 4-D vector\n    // \n    inline vec_float4 getW( ) const;\n\n    // Set an x, y, z, or w element of a 4-D vector by index\n    // \n    inline Vector4 & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, z, or w element of a 4-D vector by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Add two 4-D vectors\n    // \n    inline const Vector4 operator +( const Vector4 & vec ) const;\n\n    // Subtract a 4-D vector from another 4-D vector\n    // \n    inline const Vector4 operator -( const Vector4 & vec ) const;\n\n    // Multiply a 4-D vector by a scalar\n    // \n    inline const Vector4 operator *( vec_float4 scalar ) const;\n\n    // Divide a 4-D vector by a scalar\n    // \n    inline const Vector4 operator /( vec_float4 scalar ) const;\n\n    // Perform compound assignment and addition with a 4-D vector\n    // \n    inline Vector4 & operator +=( const Vector4 & vec );\n\n    // Perform compound assignment and subtraction by a 4-D vector\n    // \n    inline Vector4 & operator -=( const Vector4 & vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector4 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector4 & operator /=( vec_float4 scalar );\n\n    // Negate all elements of a 4-D vector\n    // \n    inline const Vector4 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector4 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector4 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector4 zAxis( );\n\n    // Construct w axis\n    // \n    static inline const Vector4 wAxis( );\n\n};\n\n// Multiply a 4-D vector by a scalar\n// \ninline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec );\n\n// Multiply two 4-D vectors per element\n// \ninline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Divide two 4-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Compute the reciprocal of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector4 recipPerElem( const Vector4 & vec );\n\n// Compute the square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector4 sqrtPerElem( const Vector4 & vec );\n\n// Compute the reciprocal square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector4 rsqrtPerElem( const Vector4 & vec );\n\n// Compute the absolute value of a 4-D vector per element\n// \ninline const Vector4 absPerElem( const Vector4 & vec );\n\n// Copy sign from one 4-D vector to another, per element\n// \ninline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Maximum of two 4-D vectors per element\n// \ninline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Minimum of two 4-D vectors per element\n// \ninline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Maximum element of a 4-D vector\n// \ninline vec_float4 maxElem( const Vector4 & vec );\n\n// Minimum element of a 4-D vector\n// \ninline vec_float4 minElem( const Vector4 & vec );\n\n// Compute the sum of all elements of a 4-D vector\n// \ninline vec_float4 sum( const Vector4 & vec );\n\n// Compute the dot product of two 4-D vectors\n// \ninline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Compute the square of the length of a 4-D vector\n// \ninline vec_float4 lengthSqr( const Vector4 & vec );\n\n// Compute the length of a 4-D vector\n// \ninline vec_float4 length( const Vector4 & vec );\n\n// Normalize a 4-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector4 normalize( const Vector4 & vec );\n\n// Outer product of two 4-D vectors\n// \ninline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Linear interpolation between two 4-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 );\n\n// Spherical linear interpolation between two 4-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 );\n\n// Conditionally select between two 4-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 );\n\n// Store four slots of an SoA 4-D vector as half-floats\n// \ninline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector4 & vec );\n\n// Print a 4-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector4 & vec, const char * name );\n\n#endif\n\n// A set of four 3-D points in structure-of-arrays format\n//\nclass Point3\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Point3( ) { };\n\n    // Copy a 3-D point\n    // \n    inline Point3( const Point3 & pnt );\n\n    // Construct a 3-D point from x, y, and z elements\n    // \n    inline Point3( vec_float4 x, vec_float4 y, vec_float4 z );\n\n    // Copy elements from a 3-D vector into a 3-D point\n    // \n    explicit inline Point3( const Vector3 & vec );\n\n    // Set all elements of a 3-D point to the same scalar value\n    // \n    explicit inline Point3( vec_float4 scalar );\n\n    // Replicate an AoS 3-D point\n    // \n    inline Point3( Aos::Point3 pnt );\n\n    // Insert four AoS 3-D points\n    // \n    inline Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 );\n\n    // Extract four AoS 3-D points\n    // \n    inline void get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const;\n\n    // Assign one 3-D point to another\n    // \n    inline Point3 & operator =( const Point3 & pnt );\n\n    // Set the x element of a 3-D point\n    // \n    inline Point3 & setX( vec_float4 x );\n\n    // Set the y element of a 3-D point\n    // \n    inline Point3 & setY( vec_float4 y );\n\n    // Set the z element of a 3-D point\n    // \n    inline Point3 & setZ( vec_float4 z );\n\n    // Get the x element of a 3-D point\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a 3-D point\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a 3-D point\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D point by index\n    // \n    inline Point3 & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, or z element of a 3-D point by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Subtract a 3-D point from another 3-D point\n    // \n    inline const Vector3 operator -( const Point3 & pnt ) const;\n\n    // Add a 3-D point to a 3-D vector\n    // \n    inline const Point3 operator +( const Vector3 & vec ) const;\n\n    // Subtract a 3-D vector from a 3-D point\n    // \n    inline const Point3 operator -( const Vector3 & vec ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Point3 & operator +=( const Vector3 & vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Point3 & operator -=( const Vector3 & vec );\n\n};\n\n// Multiply two 3-D points per element\n// \ninline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Divide two 3-D points per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Compute the reciprocal of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Point3 recipPerElem( const Point3 & pnt );\n\n// Compute the square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Point3 sqrtPerElem( const Point3 & pnt );\n\n// Compute the reciprocal square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Point3 rsqrtPerElem( const Point3 & pnt );\n\n// Compute the absolute value of a 3-D point per element\n// \ninline const Point3 absPerElem( const Point3 & pnt );\n\n// Copy sign from one 3-D point to another, per element\n// \ninline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Maximum of two 3-D points per element\n// \ninline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Minimum of two 3-D points per element\n// \ninline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Maximum element of a 3-D point\n// \ninline vec_float4 maxElem( const Point3 & pnt );\n\n// Minimum element of a 3-D point\n// \ninline vec_float4 minElem( const Point3 & pnt );\n\n// Compute the sum of all elements of a 3-D point\n// \ninline vec_float4 sum( const Point3 & pnt );\n\n// Apply uniform scale to a 3-D point\n// \ninline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal );\n\n// Apply non-uniform scale to a 3-D point\n// \ninline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec );\n\n// Scalar projection of a 3-D point on a unit-length 3-D vector\n// \ninline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec );\n\n// Compute the square of the distance of a 3-D point from the coordinate-system origin\n// \ninline vec_float4 distSqrFromOrigin( const Point3 & pnt );\n\n// Compute the distance of a 3-D point from the coordinate-system origin\n// \ninline vec_float4 distFromOrigin( const Point3 & pnt );\n\n// Compute the square of the distance between two 3-D points\n// \ninline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Compute the distance between two 3-D points\n// \ninline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Linear interpolation between two 3-D points\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 );\n\n// Conditionally select between two 3-D points\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 );\n\n// Load four three-float 3-D points, stored in three quadwords\n// \ninline void loadXYZArray( Point3 & pnt, const vec_float4 * threeQuads );\n\n// Store four slots of an SoA 3-D point in three quadwords\n// \ninline void storeXYZArray( const Point3 & pnt, vec_float4 * threeQuads );\n\n// Store eight slots of two SoA 3-D points as half-floats\n// \ninline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D point\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Point3 & pnt );\n\n// Print a 3-D point and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Point3 & pnt, const char * name );\n\n#endif\n\n// A set of four quaternions in structure-of-arrays format\n//\nclass Quat\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n    vec_float4 mW;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Quat( ) { };\n\n    // Copy a quaternion\n    // \n    inline Quat( const Quat & quat );\n\n    // Construct a quaternion from x, y, z, and w elements\n    // \n    inline Quat( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n    // Construct a quaternion from a 3-D vector and a scalar\n    // \n    inline Quat( const Vector3 & xyz, vec_float4 w );\n\n    // Copy elements from a 4-D vector into a quaternion\n    // \n    explicit inline Quat( const Vector4 & vec );\n\n    // Convert a rotation matrix to a unit-length quaternion\n    // \n    explicit inline Quat( const Matrix3 & rotMat );\n\n    // Set all elements of a quaternion to the same scalar value\n    // \n    explicit inline Quat( vec_float4 scalar );\n\n    // Replicate an AoS quaternion\n    // \n    inline Quat( Aos::Quat quat );\n\n    // Insert four AoS quaternions\n    // \n    inline Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 );\n\n    // Extract four AoS quaternions\n    // \n    inline void get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const;\n\n    // Assign one quaternion to another\n    // \n    inline Quat & operator =( const Quat & quat );\n\n    // Set the x, y, and z elements of a quaternion\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Quat & setXYZ( const Vector3 & vec );\n\n    // Get the x, y, and z elements of a quaternion\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a quaternion\n    // \n    inline Quat & setX( vec_float4 x );\n\n    // Set the y element of a quaternion\n    // \n    inline Quat & setY( vec_float4 y );\n\n    // Set the z element of a quaternion\n    // \n    inline Quat & setZ( vec_float4 z );\n\n    // Set the w element of a quaternion\n    // \n    inline Quat & setW( vec_float4 w );\n\n    // Get the x element of a quaternion\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a quaternion\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a quaternion\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Get the w element of a quaternion\n    // \n    inline vec_float4 getW( ) const;\n\n    // Set an x, y, z, or w element of a quaternion by index\n    // \n    inline Quat & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, z, or w element of a quaternion by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Add two quaternions\n    // \n    inline const Quat operator +( const Quat & quat ) const;\n\n    // Subtract a quaternion from another quaternion\n    // \n    inline const Quat operator -( const Quat & quat ) const;\n\n    // Multiply two quaternions\n    // \n    inline const Quat operator *( const Quat & quat ) const;\n\n    // Multiply a quaternion by a scalar\n    // \n    inline const Quat operator *( vec_float4 scalar ) const;\n\n    // Divide a quaternion by a scalar\n    // \n    inline const Quat operator /( vec_float4 scalar ) const;\n\n    // Perform compound assignment and addition with a quaternion\n    // \n    inline Quat & operator +=( const Quat & quat );\n\n    // Perform compound assignment and subtraction by a quaternion\n    // \n    inline Quat & operator -=( const Quat & quat );\n\n    // Perform compound assignment and multiplication by a quaternion\n    // \n    inline Quat & operator *=( const Quat & quat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Quat & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Quat & operator /=( vec_float4 scalar );\n\n    // Negate all elements of a quaternion\n    // \n    inline const Quat operator -( ) const;\n\n    // Construct an identity quaternion\n    // \n    static inline const Quat identity( );\n\n    // Construct a quaternion to rotate between two unit-length 3-D vectors\n    // NOTE: \n    // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n    // \n    static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector\n    // \n    static inline const Quat rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a quaternion to rotate around the x axis\n    // \n    static inline const Quat rotationX( vec_float4 radians );\n\n    // Construct a quaternion to rotate around the y axis\n    // \n    static inline const Quat rotationY( vec_float4 radians );\n\n    // Construct a quaternion to rotate around the z axis\n    // \n    static inline const Quat rotationZ( vec_float4 radians );\n\n};\n\n// Multiply a quaternion by a scalar\n// \ninline const Quat operator *( vec_float4 scalar, const Quat & quat );\n\n// Compute the conjugate of a quaternion\n// \ninline const Quat conj( const Quat & quat );\n\n// Use a unit-length quaternion to rotate a 3-D vector\n// \ninline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec );\n\n// Compute the dot product of two quaternions\n// \ninline vec_float4 dot( const Quat & quat0, const Quat & quat1 );\n\n// Compute the norm of a quaternion\n// \ninline vec_float4 norm( const Quat & quat );\n\n// Compute the length of a quaternion\n// \ninline vec_float4 length( const Quat & quat );\n\n// Normalize a quaternion\n// NOTE: \n// The result is unpredictable when all elements of quat are at or near zero.\n// \ninline const Quat normalize( const Quat & quat );\n\n// Linear interpolation between two quaternions\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 );\n\n// Spherical linear interpolation between two quaternions\n// NOTE: \n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n// \ninline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 );\n\n// Spherical quadrangle interpolation\n// \ninline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 );\n\n// Conditionally select between two quaternions\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a quaternion\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Quat & quat );\n\n// Print a quaternion and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Quat & quat, const char * name );\n\n#endif\n\n// A set of four 3x3 matrices in structure-of-arrays format\n//\nclass Matrix3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix3( ) { };\n\n    // Copy a 3x3 matrix\n    // \n    inline Matrix3( const Matrix3 & mat );\n\n    // Construct a 3x3 matrix containing the specified columns\n    // \n    inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 );\n\n    // Construct a 3x3 rotation matrix from a unit-length quaternion\n    // \n    explicit inline Matrix3( const Quat & unitQuat );\n\n    // Set all elements of a 3x3 matrix to the same scalar value\n    // \n    explicit inline Matrix3( vec_float4 scalar );\n\n    // Replicate an AoS 3x3 matrix\n    // \n    inline Matrix3( const Aos::Matrix3 & mat );\n\n    // Insert four AoS 3x3 matrices\n    // \n    inline Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 );\n\n    // Extract four AoS 3x3 matrices\n    // \n    inline void get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const;\n\n    // Assign one 3x3 matrix to another\n    // \n    inline Matrix3 & operator =( const Matrix3 & mat );\n\n    // Set column 0 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol0( const Vector3 & col0 );\n\n    // Set column 1 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol1( const Vector3 & col1 );\n\n    // Set column 2 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol2( const Vector3 & col2 );\n\n    // Get column 0 of a 3x3 matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x3 matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x3 matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Set the column of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setCol( int col, const Vector3 & vec );\n\n    // Set the row of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setRow( int row, const Vector3 & vec );\n\n    // Get the column of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline Matrix3 & setElem( int col, int row, vec_float4 val );\n\n    // Get the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline vec_float4 getElem( int col, int row ) const;\n\n    // Add two 3x3 matrices\n    // \n    inline const Matrix3 operator +( const Matrix3 & mat ) const;\n\n    // Subtract a 3x3 matrix from another 3x3 matrix\n    // \n    inline const Matrix3 operator -( const Matrix3 & mat ) const;\n\n    // Negate all elements of a 3x3 matrix\n    // \n    inline const Matrix3 operator -( ) const;\n\n    // Multiply a 3x3 matrix by a scalar\n    // \n    inline const Matrix3 operator *( vec_float4 scalar ) const;\n\n    // Multiply a 3x3 matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( const Vector3 & vec ) const;\n\n    // Multiply two 3x3 matrices\n    // \n    inline const Matrix3 operator *( const Matrix3 & mat ) const;\n\n    // Perform compound assignment and addition with a 3x3 matrix\n    // \n    inline Matrix3 & operator +=( const Matrix3 & mat );\n\n    // Perform compound assignment and subtraction by a 3x3 matrix\n    // \n    inline Matrix3 & operator -=( const Matrix3 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix3 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and multiplication by a 3x3 matrix\n    // \n    inline Matrix3 & operator *=( const Matrix3 & mat );\n\n    // Construct an identity 3x3 matrix\n    // \n    static inline const Matrix3 identity( );\n\n    // Construct a 3x3 matrix to rotate around the x axis\n    // \n    static inline const Matrix3 rotationX( vec_float4 radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis\n    // \n    static inline const Matrix3 rotationY( vec_float4 radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis\n    // \n    static inline const Matrix3 rotationZ( vec_float4 radians );\n\n    // Construct a 3x3 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix3 rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix3 rotation( const Quat & unitQuat );\n\n    // Construct a 3x3 matrix to perform scaling\n    // \n    static inline const Matrix3 scale( const Vector3 & scaleVec );\n\n};\n// Multiply a 3x3 matrix by a scalar\n// \ninline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat );\n\n// Append (post-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat );\n\n// Multiply two 3x3 matrices per element\n// \ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );\n\n// Compute the absolute value of a 3x3 matrix per element\n// \ninline const Matrix3 absPerElem( const Matrix3 & mat );\n\n// Transpose of a 3x3 matrix\n// \ninline const Matrix3 transpose( const Matrix3 & mat );\n\n// Compute the inverse of a 3x3 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix3 inverse( const Matrix3 & mat );\n\n// Determinant of a 3x3 matrix\n// \ninline vec_float4 determinant( const Matrix3 & mat );\n\n// Conditionally select between two 3x3 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x3 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat );\n\n// Print a 3x3 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat, const char * name );\n\n#endif\n\n// A set of four 4x4 matrices in structure-of-arrays format\n//\nclass Matrix4\n{\n    Vector4 mCol0;\n    Vector4 mCol1;\n    Vector4 mCol2;\n    Vector4 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix4( ) { };\n\n    // Copy a 4x4 matrix\n    // \n    inline Matrix4( const Matrix4 & mat );\n\n    // Construct a 4x4 matrix containing the specified columns\n    // \n    inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 );\n\n    // Construct a 4x4 matrix from a 3x4 transformation matrix\n    // \n    explicit inline Matrix4( const Transform3 & mat );\n\n    // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec );\n\n    // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec );\n\n    // Set all elements of a 4x4 matrix to the same scalar value\n    // \n    explicit inline Matrix4( vec_float4 scalar );\n\n    // Replicate an AoS 4x4 matrix\n    // \n    inline Matrix4( const Aos::Matrix4 & mat );\n\n    // Insert four AoS 4x4 matrices\n    // \n    inline Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 );\n\n    // Extract four AoS 4x4 matrices\n    // \n    inline void get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const;\n\n    // Assign one 4x4 matrix to another\n    // \n    inline Matrix4 & operator =( const Matrix4 & mat );\n\n    // Set the upper-left 3x3 submatrix\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 4x4 matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setTranslation( const Vector3 & translateVec );\n\n    // Get the translation component of a 4x4 matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol0( const Vector4 & col0 );\n\n    // Set column 1 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol1( const Vector4 & col1 );\n\n    // Set column 2 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol2( const Vector4 & col2 );\n\n    // Set column 3 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol3( const Vector4 & col3 );\n\n    // Get column 0 of a 4x4 matrix\n    // \n    inline const Vector4 getCol0( ) const;\n\n    // Get column 1 of a 4x4 matrix\n    // \n    inline const Vector4 getCol1( ) const;\n\n    // Get column 2 of a 4x4 matrix\n    // \n    inline const Vector4 getCol2( ) const;\n\n    // Get column 3 of a 4x4 matrix\n    // \n    inline const Vector4 getCol3( ) const;\n\n    // Set the column of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setCol( int col, const Vector4 & vec );\n\n    // Set the row of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setRow( int row, const Vector4 & vec );\n\n    // Get the column of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getCol( int col ) const;\n\n    // Get the row of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector4 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector4 operator []( int col ) const;\n\n    // Set the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline Matrix4 & setElem( int col, int row, vec_float4 val );\n\n    // Get the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline vec_float4 getElem( int col, int row ) const;\n\n    // Add two 4x4 matrices\n    // \n    inline const Matrix4 operator +( const Matrix4 & mat ) const;\n\n    // Subtract a 4x4 matrix from another 4x4 matrix\n    // \n    inline const Matrix4 operator -( const Matrix4 & mat ) const;\n\n    // Negate all elements of a 4x4 matrix\n    // \n    inline const Matrix4 operator -( ) const;\n\n    // Multiply a 4x4 matrix by a scalar\n    // \n    inline const Matrix4 operator *( vec_float4 scalar ) const;\n\n    // Multiply a 4x4 matrix by a 4-D vector\n    // \n    inline const Vector4 operator *( const Vector4 & vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D vector\n    // \n    inline const Vector4 operator *( const Vector3 & vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D point\n    // \n    inline const Vector4 operator *( const Point3 & pnt ) const;\n\n    // Multiply two 4x4 matrices\n    // \n    inline const Matrix4 operator *( const Matrix4 & mat ) const;\n\n    // Multiply a 4x4 matrix by a 3x4 transformation matrix\n    // \n    inline const Matrix4 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and addition with a 4x4 matrix\n    // \n    inline Matrix4 & operator +=( const Matrix4 & mat );\n\n    // Perform compound assignment and subtraction by a 4x4 matrix\n    // \n    inline Matrix4 & operator -=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix4 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and multiplication by a 4x4 matrix\n    // \n    inline Matrix4 & operator *=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Matrix4 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 4x4 matrix\n    // \n    static inline const Matrix4 identity( );\n\n    // Construct a 4x4 matrix to rotate around the x axis\n    // \n    static inline const Matrix4 rotationX( vec_float4 radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis\n    // \n    static inline const Matrix4 rotationY( vec_float4 radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis\n    // \n    static inline const Matrix4 rotationZ( vec_float4 radians );\n\n    // Construct a 4x4 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix4 rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix4 rotation( const Quat & unitQuat );\n\n    // Construct a 4x4 matrix to perform scaling\n    // \n    static inline const Matrix4 scale( const Vector3 & scaleVec );\n\n    // Construct a 4x4 matrix to perform translation\n    // \n    static inline const Matrix4 translation( const Vector3 & translateVec );\n\n    // Construct viewing matrix based on eye position, position looked at, and up direction\n    // \n    static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec );\n\n    // Construct a perspective projection matrix\n    // \n    static inline const Matrix4 perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar );\n\n    // Construct a perspective projection matrix based on frustum\n    // \n    static inline const Matrix4 frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n    // Construct an orthographic projection matrix\n    // \n    static inline const Matrix4 orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n};\n// Multiply a 4x4 matrix by a scalar\n// \ninline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat );\n\n// Append (post-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat );\n\n// Multiply two 4x4 matrices per element\n// \ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );\n\n// Compute the absolute value of a 4x4 matrix per element\n// \ninline const Matrix4 absPerElem( const Matrix4 & mat );\n\n// Transpose of a 4x4 matrix\n// \ninline const Matrix4 transpose( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 inverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 affineInverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n// \ninline const Matrix4 orthoInverse( const Matrix4 & mat );\n\n// Determinant of a 4x4 matrix\n// \ninline vec_float4 determinant( const Matrix4 & mat );\n\n// Conditionally select between two 4x4 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4x4 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat );\n\n// Print a 4x4 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat, const char * name );\n\n#endif\n\n// A set of four 3x4 transformation matrices in structure-of-arrays format\n//\nclass Transform3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n    Vector3 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Transform3( ) { };\n\n    // Copy a 3x4 transformation matrix\n    // \n    inline Transform3( const Transform3 & tfrm );\n\n    // Construct a 3x4 transformation matrix containing the specified columns\n    // \n    inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 );\n\n    // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec );\n\n    // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Transform3( const Quat & unitQuat, const Vector3 & translateVec );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value\n    // \n    explicit inline Transform3( vec_float4 scalar );\n\n    // Replicate an AoS 3x4 transformation matrix\n    // \n    inline Transform3( const Aos::Transform3 & tfrm );\n\n    // Insert four AoS 3x4 transformation matrices\n    // \n    inline Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 );\n\n    // Extract four AoS 3x4 transformation matrices\n    // \n    inline void get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const;\n\n    // Assign one 3x4 transformation matrix to another\n    // \n    inline Transform3 & operator =( const Transform3 & tfrm );\n\n    // Set the upper-left 3x3 submatrix\n    // \n    inline Transform3 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // \n    inline Transform3 & setTranslation( const Vector3 & translateVec );\n\n    // Get the translation component of a 3x4 transformation matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol0( const Vector3 & col0 );\n\n    // Set column 1 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol1( const Vector3 & col1 );\n\n    // Set column 2 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol2( const Vector3 & col2 );\n\n    // Set column 3 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol3( const Vector3 & col3 );\n\n    // Get column 0 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Get column 3 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol3( ) const;\n\n    // Set the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setCol( int col, const Vector3 & vec );\n\n    // Set the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setRow( int row, const Vector4 & vec );\n\n    // Get the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline Transform3 & setElem( int col, int row, vec_float4 val );\n\n    // Get the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline vec_float4 getElem( int col, int row ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( const Vector3 & vec ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D point\n    // \n    inline const Point3 operator *( const Point3 & pnt ) const;\n\n    // Multiply two 3x4 transformation matrices\n    // \n    inline const Transform3 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Transform3 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 3x4 transformation matrix\n    // \n    static inline const Transform3 identity( );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis\n    // \n    static inline const Transform3 rotationX( vec_float4 radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis\n    // \n    static inline const Transform3 rotationY( vec_float4 radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis\n    // \n    static inline const Transform3 rotationZ( vec_float4 radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n    // \n    static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Transform3 rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Transform3 rotation( const Quat & unitQuat );\n\n    // Construct a 3x4 transformation matrix to perform scaling\n    // \n    static inline const Transform3 scale( const Vector3 & scaleVec );\n\n    // Construct a 3x4 transformation matrix to perform translation\n    // \n    static inline const Transform3 translation( const Vector3 & translateVec );\n\n};\n// Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm );\n\n// Multiply two 3x4 transformation matrices per element\n// \ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );\n\n// Compute the absolute value of a 3x4 transformation matrix per element\n// \ninline const Transform3 absPerElem( const Transform3 & tfrm );\n\n// Inverse of a 3x4 transformation matrix\n// NOTE: \n// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n// \ninline const Transform3 inverse( const Transform3 & tfrm );\n\n// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n// \ninline const Transform3 orthoInverse( const Transform3 & tfrm );\n\n// Conditionally select between two 3x4 transformation matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x4 transformation matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm );\n\n// Print a 3x4 transformation matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm, const char * name );\n\n#endif\n\n} // namespace Soa\n} // namespace Vectormath\n\n#include \"vec_soa.h\"\n#include \"quat_soa.h\"\n#include \"mat_soa.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_C_H\n#define _VECTORMATH_MAT_AOS_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( &result->col0, &mat->col0 );\n    vmathV3Copy( &result->col1, &mat->col1 );\n    vmathV3Copy( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar )\n{\n    vmathV3MakeFromScalar( &result->col0, scalar );\n    vmathV3MakeFromScalar( &result->col1, scalar );\n    vmathV3MakeFromScalar( &result->col2, scalar );\n}\n\nstatic inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat )\n{\n    float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2;\n    qx = unitQuat->x;\n    qy = unitQuat->y;\n    qz = unitQuat->z;\n    qw = unitQuat->w;\n    qx2 = ( qx + qx );\n    qy2 = ( qy + qy );\n    qz2 = ( qz + qz );\n    qxqx2 = ( qx * qx2 );\n    qxqy2 = ( qx * qy2 );\n    qxqz2 = ( qx * qz2 );\n    qxqw2 = ( qw * qx2 );\n    qyqy2 = ( qy * qy2 );\n    qyqz2 = ( qy * qz2 );\n    qyqw2 = ( qw * qy2 );\n    qzqz2 = ( qz * qz2 );\n    qzqw2 = ( qw * qz2 );\n    vmathV3MakeFromElems( &result->col0, ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) );\n    vmathV3MakeFromElems( &result->col1, ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) );\n    vmathV3MakeFromElems( &result->col2, ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) );\n}\n\nstatic inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n    vmathV3Copy( &result->col1, _col1 );\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *_col0 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *_col1 )\n{\n    vmathV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec )\n{\n    vmathV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec )\n{\n    vmathV3SetElem( &result->col0, row, vmathV3GetElem( vec, 0 ) );\n    vmathV3SetElem( &result->col1, row, vmathV3GetElem( vec, 1 ) );\n    vmathV3SetElem( &result->col2, row, vmathV3GetElem( vec, 2 ) );\n}\n\nstatic inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val )\n{\n    VmathVector3 tmpV3_0;\n    vmathM3GetCol( &tmpV3_0, result, col );\n    vmathV3SetElem( &tmpV3_0, row, val );\n    vmathM3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row )\n{\n    VmathVector3 tmpV3_0;\n    vmathM3GetCol( &tmpV3_0, mat, col );\n    return vmathV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col )\n{\n    vmathV3Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row )\n{\n    vmathV3MakeFromElems( result, vmathV3GetElem( &mat->col0, row ), vmathV3GetElem( &mat->col1, row ), vmathV3GetElem( &mat->col2, row ) );\n}\n\nstatic inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    VmathMatrix3 tmpResult;\n    vmathV3MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x );\n    vmathV3MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y );\n    vmathV3MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z );\n    vmathM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    VmathVector3 tmp0, tmp1, tmp2;\n    float detinv;\n    vmathV3Cross( &tmp0, &mat->col1, &mat->col2 );\n    vmathV3Cross( &tmp1, &mat->col2, &mat->col0 );\n    vmathV3Cross( &tmp2, &mat->col0, &mat->col1 );\n    detinv = ( 1.0f / vmathV3Dot( &mat->col2, &tmp2 ) );\n    vmathV3MakeFromElems( &result->col0, ( tmp0.x * detinv ), ( tmp1.x * detinv ), ( tmp2.x * detinv ) );\n    vmathV3MakeFromElems( &result->col1, ( tmp0.y * detinv ), ( tmp1.y * detinv ), ( tmp2.y * detinv ) );\n    vmathV3MakeFromElems( &result->col2, ( tmp0.z * detinv ), ( tmp1.z * detinv ), ( tmp2.z * detinv ) );\n}\n\nstatic inline float vmathM3Determinant( const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3Cross( &tmpV3_0, &mat->col0, &mat->col1 );\n    return vmathV3Dot( &mat->col2, &tmpV3_0 );\n}\n\nstatic inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3Add( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3Sub( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Neg( &result->col0, &mat->col0 );\n    vmathV3Neg( &result->col1, &mat->col1 );\n    vmathV3Neg( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3AbsPerElem( &result->col0, &mat->col0 );\n    vmathV3AbsPerElem( &result->col1, &mat->col1 );\n    vmathV3AbsPerElem( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar )\n{\n    vmathV3ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathV3ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathV3ScalarMul( &result->col2, &mat->col2, scalar );\n}\n\nstatic inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec )\n{\n    float tmpX, tmpY, tmpZ;\n    tmpX = ( ( ( mat->col0.x * vec->x ) + ( mat->col1.x * vec->y ) ) + ( mat->col2.x * vec->z ) );\n    tmpY = ( ( ( mat->col0.y * vec->x ) + ( mat->col1.y * vec->y ) ) + ( mat->col2.y * vec->z ) );\n    tmpZ = ( ( ( mat->col0.z * vec->x ) + ( mat->col1.z * vec->y ) ) + ( mat->col2.z * vec->z ) );\n    vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    VmathMatrix3 tmpResult;\n    vmathM3MulV3( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathM3MulV3( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathM3MulV3( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3MakeIdentity( VmathMatrix3 *result )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeFromElems( &result->col1, 0.0f, c, s );\n    vmathV3MakeFromElems( &result->col2, 0.0f, -s, c );\n}\n\nstatic inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV3MakeFromElems( &result->col0, c, 0.0f, -s );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeFromElems( &result->col2, s, 0.0f, c );\n}\n\nstatic inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV3MakeFromElems( &result->col0, c, s, 0.0f );\n    vmathV3MakeFromElems( &result->col1, -s, c, 0.0f );\n    vmathV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ )\n{\n    float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sX = sinf( radiansXYZ->x );\n    cX = cosf( radiansXYZ->x );\n    sY = sinf( radiansXYZ->y );\n    cY = cosf( radiansXYZ->y );\n    sZ = sinf( radiansXYZ->z );\n    cZ = cosf( radiansXYZ->z );\n    tmp0 = ( cZ * sY );\n    tmp1 = ( sZ * sY );\n    vmathV3MakeFromElems( &result->col0, ( cZ * cY ), ( sZ * cY ), -sY );\n    vmathV3MakeFromElems( &result->col1, ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) );\n    vmathV3MakeFromElems( &result->col2, ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) );\n}\n\nstatic inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec )\n{\n    float x, y, z, s, c, oneMinusC, xy, yz, zx;\n    s = sinf( radians );\n    c = cosf( radians );\n    x = unitVec->x;\n    y = unitVec->y;\n    z = unitVec->z;\n    xy = ( x * y );\n    yz = ( y * z );\n    zx = ( z * x );\n    oneMinusC = ( 1.0f - c );\n    vmathV3MakeFromElems( &result->col0, ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) );\n    vmathV3MakeFromElems( &result->col1, ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) );\n    vmathV3MakeFromElems( &result->col2, ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) );\n}\n\nstatic inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat )\n{\n    vmathM3MakeFromQ( result, unitQuat );\n}\n\nstatic inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec )\n{\n    vmathV3MakeFromElems( &result->col0, scaleVec->x, 0.0f, 0.0f );\n    vmathV3MakeFromElems( &result->col1, 0.0f, scaleVec->y, 0.0f );\n    vmathV3MakeFromElems( &result->col2, 0.0f, 0.0f, scaleVec->z );\n}\n\nstatic inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec )\n{\n    vmathV3ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) );\n    vmathV3ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) );\n    vmathV3ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) );\n}\n\nstatic inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat )\n{\n    vmathV3MulPerElem( &result->col0, &mat->col0, scaleVec );\n    vmathV3MulPerElem( &result->col1, &mat->col1, scaleVec );\n    vmathV3MulPerElem( &result->col2, &mat->col2, scaleVec );\n}\n\nstatic inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 )\n{\n    vmathV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM3Print( const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathM3GetRow( &tmpV3_0, mat, 0 );\n    vmathV3Print( &tmpV3_0 );\n    vmathM3GetRow( &tmpV3_1, mat, 1 );\n    vmathV3Print( &tmpV3_1 );\n    vmathM3GetRow( &tmpV3_2, mat, 2 );\n    vmathV3Print( &tmpV3_2 );\n}\n\nstatic inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathM3Print( mat );\n}\n\n#endif\n\nstatic inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( &result->col0, &mat->col0 );\n    vmathV4Copy( &result->col1, &mat->col1 );\n    vmathV4Copy( &result->col2, &mat->col2 );\n    vmathV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar )\n{\n    vmathV4MakeFromScalar( &result->col0, scalar );\n    vmathV4MakeFromScalar( &result->col1, scalar );\n    vmathV4MakeFromScalar( &result->col2, scalar );\n    vmathV4MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat )\n{\n    vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, &mat->col3, 1.0f );\n}\n\nstatic inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *_col0, const VmathVector4 *_col1, const VmathVector4 *_col2, const VmathVector4 *_col3 )\n{\n    vmathV4Copy( &result->col0, _col0 );\n    vmathV4Copy( &result->col1, _col1 );\n    vmathV4Copy( &result->col2, _col2 );\n    vmathV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec )\n{\n    vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec )\n{\n    VmathMatrix3 mat;\n    vmathM3MakeFromQ( &mat, unitQuat );\n    vmathV4MakeFromV3Scalar( &result->col0, &mat.col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat.col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat.col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *_col0 )\n{\n    vmathV4Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *_col1 )\n{\n    vmathV4Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *_col2 )\n{\n    vmathV4Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *_col3 )\n{\n    vmathV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec )\n{\n    vmathV4Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec )\n{\n    vmathV4SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) );\n    vmathV4SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) );\n    vmathV4SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) );\n    vmathV4SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val )\n{\n    VmathVector4 tmpV3_0;\n    vmathM4GetCol( &tmpV3_0, result, col );\n    vmathV4SetElem( &tmpV3_0, row, val );\n    vmathM4SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row )\n{\n    VmathVector4 tmpV4_0;\n    vmathM4GetCol( &tmpV4_0, mat, col );\n    return vmathV4GetElem( &tmpV4_0, row );\n}\n\nstatic inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col3 );\n}\n\nstatic inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col )\n{\n    vmathV4Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row )\n{\n    vmathV4MakeFromElems( result, vmathV4GetElem( &mat->col0, row ), vmathV4GetElem( &mat->col1, row ), vmathV4GetElem( &mat->col2, row ), vmathV4GetElem( &mat->col3, row ) );\n}\n\nstatic inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathMatrix4 tmpResult;\n    vmathV4MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x, mat->col3.x );\n    vmathV4MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y, mat->col3.y );\n    vmathV4MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z, mat->col3.z );\n    vmathV4MakeFromElems( &tmpResult.col3, mat->col0.w, mat->col1.w, mat->col2.w, mat->col3.w );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathVector4 res0, res1, res2, res3;\n    float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv;\n    mA = mat->col0.x;\n    mB = mat->col0.y;\n    mC = mat->col0.z;\n    mD = mat->col0.w;\n    mE = mat->col1.x;\n    mF = mat->col1.y;\n    mG = mat->col1.z;\n    mH = mat->col1.w;\n    mI = mat->col2.x;\n    mJ = mat->col2.y;\n    mK = mat->col2.z;\n    mL = mat->col2.w;\n    mM = mat->col3.x;\n    mN = mat->col3.y;\n    mO = mat->col3.z;\n    mP = mat->col3.w;\n    tmp0 = ( ( mK * mD ) - ( mC * mL ) );\n    tmp1 = ( ( mO * mH ) - ( mG * mP ) );\n    tmp2 = ( ( mB * mK ) - ( mJ * mC ) );\n    tmp3 = ( ( mF * mO ) - ( mN * mG ) );\n    tmp4 = ( ( mJ * mD ) - ( mB * mL ) );\n    tmp5 = ( ( mN * mH ) - ( mF * mP ) );\n    vmathV4SetX( &res0, ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) );\n    vmathV4SetY( &res0, ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) );\n    vmathV4SetZ( &res0, ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) );\n    vmathV4SetW( &res0, ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) );\n    detInv = ( 1.0f / ( ( ( ( mA * res0.x ) + ( mE * res0.y ) ) + ( mI * res0.z ) ) + ( mM * res0.w ) ) );\n    vmathV4SetX( &res1, ( mI * tmp1 ) );\n    vmathV4SetY( &res1, ( mM * tmp0 ) );\n    vmathV4SetZ( &res1, ( mA * tmp1 ) );\n    vmathV4SetW( &res1, ( mE * tmp0 ) );\n    vmathV4SetX( &res3, ( mI * tmp3 ) );\n    vmathV4SetY( &res3, ( mM * tmp2 ) );\n    vmathV4SetZ( &res3, ( mA * tmp3 ) );\n    vmathV4SetW( &res3, ( mE * tmp2 ) );\n    vmathV4SetX( &res2, ( mI * tmp5 ) );\n    vmathV4SetY( &res2, ( mM * tmp4 ) );\n    vmathV4SetZ( &res2, ( mA * tmp5 ) );\n    vmathV4SetW( &res2, ( mE * tmp4 ) );\n    tmp0 = ( ( mI * mB ) - ( mA * mJ ) );\n    tmp1 = ( ( mM * mF ) - ( mE * mN ) );\n    tmp2 = ( ( mI * mD ) - ( mA * mL ) );\n    tmp3 = ( ( mM * mH ) - ( mE * mP ) );\n    tmp4 = ( ( mI * mC ) - ( mA * mK ) );\n    tmp5 = ( ( mM * mG ) - ( mE * mO ) );\n    vmathV4SetX( &res2, ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.x ) );\n    vmathV4SetY( &res2, ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.y ) );\n    vmathV4SetZ( &res2, ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.z ) );\n    vmathV4SetW( &res2, ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.w ) );\n    vmathV4SetX( &res3, ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.x ) );\n    vmathV4SetY( &res3, ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.y ) );\n    vmathV4SetZ( &res3, ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.z ) );\n    vmathV4SetW( &res3, ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.w ) );\n    vmathV4SetX( &res1, ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.x ) );\n    vmathV4SetY( &res1, ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.y ) );\n    vmathV4SetZ( &res1, ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.z ) );\n    vmathV4SetW( &res1, ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.w ) );\n    vmathV4ScalarMul( &result->col0, &res0, detInv );\n    vmathV4ScalarMul( &result->col1, &res1, detInv );\n    vmathV4ScalarMul( &result->col2, &res2, detInv );\n    vmathV4ScalarMul( &result->col3, &res3, detInv );\n}\n\nstatic inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathTransform3 affineMat, tmpT3_0;\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathT3Inverse( &tmpT3_0, &affineMat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathTransform3 affineMat, tmpT3_0;\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathT3OrthoInverse( &tmpT3_0, &affineMat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline float vmathM4Determinant( const VmathMatrix4 *mat )\n{\n    float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    mA = mat->col0.x;\n    mB = mat->col0.y;\n    mC = mat->col0.z;\n    mD = mat->col0.w;\n    mE = mat->col1.x;\n    mF = mat->col1.y;\n    mG = mat->col1.z;\n    mH = mat->col1.w;\n    mI = mat->col2.x;\n    mJ = mat->col2.y;\n    mK = mat->col2.z;\n    mL = mat->col2.w;\n    mM = mat->col3.x;\n    mN = mat->col3.y;\n    mO = mat->col3.z;\n    mP = mat->col3.w;\n    tmp0 = ( ( mK * mD ) - ( mC * mL ) );\n    tmp1 = ( ( mO * mH ) - ( mG * mP ) );\n    tmp2 = ( ( mB * mK ) - ( mJ * mC ) );\n    tmp3 = ( ( mF * mO ) - ( mN * mG ) );\n    tmp4 = ( ( mJ * mD ) - ( mB * mL ) );\n    tmp5 = ( ( mN * mH ) - ( mF * mP ) );\n    dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) );\n    dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) );\n    dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) );\n    dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) );\n    return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) );\n}\n\nstatic inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4Add( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4Add( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4Sub( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4Sub( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Neg( &result->col0, &mat->col0 );\n    vmathV4Neg( &result->col1, &mat->col1 );\n    vmathV4Neg( &result->col2, &mat->col2 );\n    vmathV4Neg( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4AbsPerElem( &result->col0, &mat->col0 );\n    vmathV4AbsPerElem( &result->col1, &mat->col1 );\n    vmathV4AbsPerElem( &result->col2, &mat->col2 );\n    vmathV4AbsPerElem( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar )\n{\n    vmathV4ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathV4ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathV4ScalarMul( &result->col2, &mat->col2, scalar );\n    vmathV4ScalarMul( &result->col3, &mat->col3, scalar );\n}\n\nstatic inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec )\n{\n    float tmpX, tmpY, tmpZ, tmpW;\n    tmpX = ( ( ( ( mat->col0.x * vec->x ) + ( mat->col1.x * vec->y ) ) + ( mat->col2.x * vec->z ) ) + ( mat->col3.x * vec->w ) );\n    tmpY = ( ( ( ( mat->col0.y * vec->x ) + ( mat->col1.y * vec->y ) ) + ( mat->col2.y * vec->z ) ) + ( mat->col3.y * vec->w ) );\n    tmpZ = ( ( ( ( mat->col0.z * vec->x ) + ( mat->col1.z * vec->y ) ) + ( mat->col2.z * vec->z ) ) + ( mat->col3.z * vec->w ) );\n    tmpW = ( ( ( ( mat->col0.w * vec->x ) + ( mat->col1.w * vec->y ) ) + ( mat->col2.w * vec->z ) ) + ( mat->col3.w * vec->w ) );\n    vmathV4MakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );\n}\n\nstatic inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec )\n{\n    result->x = ( ( ( mat->col0.x * vec->x ) + ( mat->col1.x * vec->y ) ) + ( mat->col2.x * vec->z ) );\n    result->y = ( ( ( mat->col0.y * vec->x ) + ( mat->col1.y * vec->y ) ) + ( mat->col2.y * vec->z ) );\n    result->z = ( ( ( mat->col0.z * vec->x ) + ( mat->col1.z * vec->y ) ) + ( mat->col2.z * vec->z ) );\n    result->w = ( ( ( mat->col0.w * vec->x ) + ( mat->col1.w * vec->y ) ) + ( mat->col2.w * vec->z ) );\n}\n\nstatic inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt )\n{\n    result->x = ( ( ( ( mat->col0.x * pnt->x ) + ( mat->col1.x * pnt->y ) ) + ( mat->col2.x * pnt->z ) ) + mat->col3.x );\n    result->y = ( ( ( ( mat->col0.y * pnt->x ) + ( mat->col1.y * pnt->y ) ) + ( mat->col2.y * pnt->z ) ) + mat->col3.y );\n    result->z = ( ( ( ( mat->col0.z * pnt->x ) + ( mat->col1.z * pnt->y ) ) + ( mat->col2.z * pnt->z ) ) + mat->col3.z );\n    result->w = ( ( ( ( mat->col0.w * pnt->x ) + ( mat->col1.w * pnt->y ) ) + ( mat->col2.w * pnt->z ) ) + mat->col3.w );\n}\n\nstatic inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    VmathMatrix4 tmpResult;\n    vmathM4MulV4( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathM4MulV4( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathM4MulV4( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathM4MulV4( &tmpResult.col3, mat0, &mat1->col3 );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm1 )\n{\n    VmathMatrix4 tmpResult;\n    VmathPoint3 tmpP3_0;\n    vmathM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 );\n    vmathM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 );\n    vmathM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 );\n    vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathM4MulP3( &tmpResult.col3, mat, &tmpP3_0 );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4MakeIdentity( VmathMatrix4 *result )\n{\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 )\n{\n    vmathV4SetXYZ( &result->col0, &mat3->col0 );\n    vmathV4SetXYZ( &result->col1, &mat3->col1 );\n    vmathV4SetXYZ( &result->col2, &mat3->col2 );\n}\n\nstatic inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat )\n{\n    vmathV4GetXYZ( &result->col0, &mat->col0 );\n    vmathV4GetXYZ( &result->col1, &mat->col1 );\n    vmathV4GetXYZ( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec )\n{\n    vmathV4SetXYZ( &result->col3, translateVec );\n}\n\nstatic inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat )\n{\n    vmathV4GetXYZ( result, &mat->col3 );\n}\n\nstatic inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeFromElems( &result->col1, 0.0f, c, s, 0.0f );\n    vmathV4MakeFromElems( &result->col2, 0.0f, -s, c, 0.0f );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV4MakeFromElems( &result->col0, c, 0.0f, -s, 0.0f );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeFromElems( &result->col2, s, 0.0f, c, 0.0f );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV4MakeFromElems( &result->col0, c, s, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col1, -s, c, 0.0f, 0.0f );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ )\n{\n    float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sX = sinf( radiansXYZ->x );\n    cX = cosf( radiansXYZ->x );\n    sY = sinf( radiansXYZ->y );\n    cY = cosf( radiansXYZ->y );\n    sZ = sinf( radiansXYZ->z );\n    cZ = cosf( radiansXYZ->z );\n    tmp0 = ( cZ * sY );\n    tmp1 = ( sZ * sY );\n    vmathV4MakeFromElems( &result->col0, ( cZ * cY ), ( sZ * cY ), -sY, 0.0f );\n    vmathV4MakeFromElems( &result->col1, ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f );\n    vmathV4MakeFromElems( &result->col2, ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec )\n{\n    float x, y, z, s, c, oneMinusC, xy, yz, zx;\n    s = sinf( radians );\n    c = cosf( radians );\n    x = unitVec->x;\n    y = unitVec->y;\n    z = unitVec->z;\n    xy = ( x * y );\n    yz = ( y * z );\n    zx = ( z * x );\n    oneMinusC = ( 1.0f - c );\n    vmathV4MakeFromElems( &result->col0, ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f );\n    vmathV4MakeFromElems( &result->col1, ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f );\n    vmathV4MakeFromElems( &result->col2, ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat )\n{\n    VmathTransform3 tmpT3_0;\n    vmathT3MakeRotationQ( &tmpT3_0, unitQuat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec )\n{\n    vmathV4MakeFromElems( &result->col0, scaleVec->x, 0.0f, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col1, 0.0f, scaleVec->y, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col2, 0.0f, 0.0f, scaleVec->z, 0.0f );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec )\n{\n    vmathV4ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) );\n    vmathV4ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) );\n    vmathV4ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) );\n    vmathV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat )\n{\n    VmathVector4 scale4;\n    vmathV4MakeFromV3Scalar( &scale4, scaleVec, 1.0f );\n    vmathV4MulPerElem( &result->col0, &mat->col0, &scale4 );\n    vmathV4MulPerElem( &result->col1, &mat->col1, &scale4 );\n    vmathV4MulPerElem( &result->col2, &mat->col2, &scale4 );\n    vmathV4MulPerElem( &result->col3, &mat->col3, &scale4 );\n}\n\nstatic inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec )\n{\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec )\n{\n    VmathMatrix4 m4EyeFrame;\n    VmathVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1;\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathV3Normalize( &v3Y, upVec );\n    vmathP3Sub( &tmpV3_0, eyePos, lookAtPos );\n    vmathV3Normalize( &v3Z, &tmpV3_0 );\n    vmathV3Cross( &tmpV3_1, &v3Y, &v3Z );\n    vmathV3Normalize( &v3X, &tmpV3_1 );\n    vmathV3Cross( &v3Y, &v3Z, &v3X );\n    vmathV4MakeFromV3( &tmpV4_0, &v3X );\n    vmathV4MakeFromV3( &tmpV4_1, &v3Y );\n    vmathV4MakeFromV3( &tmpV4_2, &v3Z );\n    vmathV4MakeFromP3( &tmpV4_3, eyePos );\n    vmathM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 );\n    vmathM4OrthoInverse( result, &m4EyeFrame );\n}\n\nstatic inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) );\n    rangeInv = ( 1.0f / ( zNear - zFar ) );\n    vmathV4MakeFromElems( &result->col0, ( f / aspect ), 0.0f, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col1, 0.0f, f, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col2, 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f );\n    vmathV4MakeFromElems( &result->col3, 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f );\n}\n\nstatic inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2;\n    sum_rl = ( right + left );\n    sum_tb = ( top + bottom );\n    sum_nf = ( zNear + zFar );\n    inv_rl = ( 1.0f / ( right - left ) );\n    inv_tb = ( 1.0f / ( top - bottom ) );\n    inv_nf = ( 1.0f / ( zNear - zFar ) );\n    n2 = ( zNear + zNear );\n    vmathV4MakeFromElems( &result->col0, ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col1, 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col2, ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f );\n    vmathV4MakeFromElems( &result->col3, 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f );\n}\n\nstatic inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf;\n    sum_rl = ( right + left );\n    sum_tb = ( top + bottom );\n    sum_nf = ( zNear + zFar );\n    inv_rl = ( 1.0f / ( right - left ) );\n    inv_tb = ( 1.0f / ( top - bottom ) );\n    inv_nf = ( 1.0f / ( zNear - zFar ) );\n    vmathV4MakeFromElems( &result->col0, ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col1, 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f );\n    vmathV4MakeFromElems( &result->col2, 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f );\n    vmathV4MakeFromElems( &result->col3, ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f );\n}\n\nstatic inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 )\n{\n    vmathV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n    vmathV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM4Print( const VmathMatrix4 *mat )\n{\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathM4GetRow( &tmpV4_0, mat, 0 );\n    vmathV4Print( &tmpV4_0 );\n    vmathM4GetRow( &tmpV4_1, mat, 1 );\n    vmathV4Print( &tmpV4_1 );\n    vmathM4GetRow( &tmpV4_2, mat, 2 );\n    vmathV4Print( &tmpV4_2 );\n    vmathM4GetRow( &tmpV4_3, mat, 3 );\n    vmathV4Print( &tmpV4_3 );\n}\n\nstatic inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathM4Print( mat );\n}\n\n#endif\n\nstatic inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( &result->col0, &tfrm->col0 );\n    vmathV3Copy( &result->col1, &tfrm->col1 );\n    vmathV3Copy( &result->col2, &tfrm->col2 );\n    vmathV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar )\n{\n    vmathV3MakeFromScalar( &result->col0, scalar );\n    vmathV3MakeFromScalar( &result->col1, scalar );\n    vmathV3MakeFromScalar( &result->col2, scalar );\n    vmathV3MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2, const VmathVector3 *_col3 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n    vmathV3Copy( &result->col1, _col1 );\n    vmathV3Copy( &result->col2, _col2 );\n    vmathV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec )\n{\n    vmathT3SetUpper3x3( result, tfrm );\n    vmathT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec )\n{\n    VmathMatrix3 tmpM3_0;\n    vmathM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathT3SetUpper3x3( result, &tmpM3_0 );\n    vmathT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *_col0 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *_col1 )\n{\n    vmathV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *_col3 )\n{\n    vmathV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec )\n{\n    vmathV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec )\n{\n    vmathV3SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) );\n    vmathV3SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) );\n    vmathV3SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) );\n    vmathV3SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val )\n{\n    VmathVector3 tmpV3_0;\n    vmathT3GetCol( &tmpV3_0, result, col );\n    vmathV3SetElem( &tmpV3_0, row, val );\n    vmathT3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row )\n{\n    VmathVector3 tmpV3_0;\n    vmathT3GetCol( &tmpV3_0, tfrm, col );\n    return vmathV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col0 );\n}\n\nstatic inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col1 );\n}\n\nstatic inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col2 );\n}\n\nstatic inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col )\n{\n    vmathV3Copy( result, (&tfrm->col0 + col) );\n}\n\nstatic inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row )\n{\n    vmathV4MakeFromElems( result, vmathV3GetElem( &tfrm->col0, row ), vmathV3GetElem( &tfrm->col1, row ), vmathV3GetElem( &tfrm->col2, row ), vmathV3GetElem( &tfrm->col3, row ) );\n}\n\nstatic inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    VmathVector3 tmp0, tmp1, tmp2, inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5;\n    float detinv;\n    vmathV3Cross( &tmp0, &tfrm->col1, &tfrm->col2 );\n    vmathV3Cross( &tmp1, &tfrm->col2, &tfrm->col0 );\n    vmathV3Cross( &tmp2, &tfrm->col0, &tfrm->col1 );\n    detinv = ( 1.0f / vmathV3Dot( &tfrm->col2, &tmp2 ) );\n    vmathV3MakeFromElems( &inv0, ( tmp0.x * detinv ), ( tmp1.x * detinv ), ( tmp2.x * detinv ) );\n    vmathV3MakeFromElems( &inv1, ( tmp0.y * detinv ), ( tmp1.y * detinv ), ( tmp2.y * detinv ) );\n    vmathV3MakeFromElems( &inv2, ( tmp0.z * detinv ), ( tmp1.z * detinv ), ( tmp2.z * detinv ) );\n    vmathV3Copy( &result->col0, &inv0 );\n    vmathV3Copy( &result->col1, &inv1 );\n    vmathV3Copy( &result->col2, &inv2 );\n    vmathV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x );\n    vmathV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y );\n    vmathV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z );\n    vmathV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 );\n    vmathV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 );\n    vmathV3Neg( &tmpV3_5, &tmpV3_4 );\n    vmathV3Copy( &result->col3, &tmpV3_5 );\n}\n\nstatic inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    VmathVector3 inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5;\n    vmathV3MakeFromElems( &inv0, tfrm->col0.x, tfrm->col1.x, tfrm->col2.x );\n    vmathV3MakeFromElems( &inv1, tfrm->col0.y, tfrm->col1.y, tfrm->col2.y );\n    vmathV3MakeFromElems( &inv2, tfrm->col0.z, tfrm->col1.z, tfrm->col2.z );\n    vmathV3Copy( &result->col0, &inv0 );\n    vmathV3Copy( &result->col1, &inv1 );\n    vmathV3Copy( &result->col2, &inv2 );\n    vmathV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x );\n    vmathV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y );\n    vmathV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z );\n    vmathV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 );\n    vmathV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 );\n    vmathV3Neg( &tmpV3_5, &tmpV3_4 );\n    vmathV3Copy( &result->col3, &tmpV3_5 );\n}\n\nstatic inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3AbsPerElem( &result->col0, &tfrm->col0 );\n    vmathV3AbsPerElem( &result->col1, &tfrm->col1 );\n    vmathV3AbsPerElem( &result->col2, &tfrm->col2 );\n    vmathV3AbsPerElem( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec )\n{\n    float tmpX, tmpY, tmpZ;\n    tmpX = ( ( ( tfrm->col0.x * vec->x ) + ( tfrm->col1.x * vec->y ) ) + ( tfrm->col2.x * vec->z ) );\n    tmpY = ( ( ( tfrm->col0.y * vec->x ) + ( tfrm->col1.y * vec->y ) ) + ( tfrm->col2.y * vec->z ) );\n    tmpZ = ( ( ( tfrm->col0.z * vec->x ) + ( tfrm->col1.z * vec->y ) ) + ( tfrm->col2.z * vec->z ) );\n    vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt )\n{\n    float tmpX, tmpY, tmpZ;\n    tmpX = ( ( ( ( tfrm->col0.x * pnt->x ) + ( tfrm->col1.x * pnt->y ) ) + ( tfrm->col2.x * pnt->z ) ) + tfrm->col3.x );\n    tmpY = ( ( ( ( tfrm->col0.y * pnt->x ) + ( tfrm->col1.y * pnt->y ) ) + ( tfrm->col2.y * pnt->z ) ) + tfrm->col3.y );\n    tmpZ = ( ( ( ( tfrm->col0.z * pnt->x ) + ( tfrm->col1.z * pnt->y ) ) + ( tfrm->col2.z * pnt->z ) ) + tfrm->col3.z );\n    vmathP3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 )\n{\n    VmathTransform3 tmpResult;\n    VmathPoint3 tmpP3_0, tmpP3_1;\n    vmathT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 );\n    vmathT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 );\n    vmathT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 );\n    vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 );\n    vmathV3MakeFromP3( &tmpResult.col3, &tmpP3_1 );\n    vmathT3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 )\n{\n    vmathV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 );\n    vmathV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 );\n    vmathV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 );\n    vmathV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 );\n}\n\nstatic inline void vmathT3MakeIdentity( VmathTransform3 *result )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *tfrm )\n{\n    vmathV3Copy( &result->col0, &tfrm->col0 );\n    vmathV3Copy( &result->col1, &tfrm->col1 );\n    vmathV3Copy( &result->col2, &tfrm->col2 );\n}\n\nstatic inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm )\n{\n    vmathM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 );\n}\n\nstatic inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec )\n{\n    vmathV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeFromElems( &result->col1, 0.0f, c, s );\n    vmathV3MakeFromElems( &result->col2, 0.0f, -s, c );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV3MakeFromElems( &result->col0, c, 0.0f, -s );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeFromElems( &result->col2, s, 0.0f, c );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    vmathV3MakeFromElems( &result->col0, c, s, 0.0f );\n    vmathV3MakeFromElems( &result->col1, -s, c, 0.0f );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ )\n{\n    float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sX = sinf( radiansXYZ->x );\n    cX = cosf( radiansXYZ->x );\n    sY = sinf( radiansXYZ->y );\n    cY = cosf( radiansXYZ->y );\n    sZ = sinf( radiansXYZ->z );\n    cZ = cosf( radiansXYZ->z );\n    tmp0 = ( cZ * sY );\n    tmp1 = ( sZ * sY );\n    vmathV3MakeFromElems( &result->col0, ( cZ * cY ), ( sZ * cY ), -sY );\n    vmathV3MakeFromElems( &result->col1, ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) );\n    vmathV3MakeFromElems( &result->col2, ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec )\n{\n    VmathMatrix3 tmpM3_0;\n    VmathVector3 tmpV3_0;\n    vmathM3MakeRotationAxis( &tmpM3_0, radians, unitVec );\n    vmathV3MakeFromScalar( &tmpV3_0, 0.0f );\n    vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat )\n{\n    VmathMatrix3 tmpM3_0;\n    VmathVector3 tmpV3_0;\n    vmathM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathV3MakeFromScalar( &tmpV3_0, 0.0f );\n    vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec )\n{\n    vmathV3MakeFromElems( &result->col0, scaleVec->x, 0.0f, 0.0f );\n    vmathV3MakeFromElems( &result->col1, 0.0f, scaleVec->y, 0.0f );\n    vmathV3MakeFromElems( &result->col2, 0.0f, 0.0f, scaleVec->z );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec )\n{\n    vmathV3ScalarMul( &result->col0, &tfrm->col0, vmathV3GetX( scaleVec ) );\n    vmathV3ScalarMul( &result->col1, &tfrm->col1, vmathV3GetY( scaleVec ) );\n    vmathV3ScalarMul( &result->col2, &tfrm->col2, vmathV3GetZ( scaleVec ) );\n    vmathV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm )\n{\n    vmathV3MulPerElem( &result->col0, &tfrm->col0, scaleVec );\n    vmathV3MulPerElem( &result->col1, &tfrm->col1, scaleVec );\n    vmathV3MulPerElem( &result->col2, &tfrm->col2, scaleVec );\n    vmathV3MulPerElem( &result->col3, &tfrm->col3, scaleVec );\n}\n\nstatic inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 )\n{\n    vmathV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 );\n    vmathV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 );\n    vmathV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 );\n    vmathV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathT3Print( const VmathTransform3 *tfrm )\n{\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2;\n    vmathT3GetRow( &tmpV4_0, tfrm, 0 );\n    vmathV4Print( &tmpV4_0 );\n    vmathT3GetRow( &tmpV4_1, tfrm, 1 );\n    vmathV4Print( &tmpV4_1 );\n    vmathT3GetRow( &tmpV4_2, tfrm, 2 );\n    vmathV4Print( &tmpV4_2 );\n}\n\nstatic inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathT3Print( tfrm );\n}\n\n#endif\n\nstatic inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *tfrm )\n{\n    float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw;\n    int negTrace, ZgtX, ZgtY, YgtX;\n    int largestXorY, largestYorZ, largestZorX;\n\n    xx = tfrm->col0.x;\n    yx = tfrm->col0.y;\n    zx = tfrm->col0.z;\n    xy = tfrm->col1.x;\n    yy = tfrm->col1.y;\n    zy = tfrm->col1.z;\n    xz = tfrm->col2.x;\n    yz = tfrm->col2.y;\n    zz = tfrm->col2.z;\n\n    trace = ( ( xx + yy ) + zz );\n\n    negTrace = ( trace < 0.0f );\n    ZgtX = zz > xx;\n    ZgtY = zz > yy;\n    YgtX = yy > xx;\n    largestXorY = ( !ZgtX || !ZgtY ) && negTrace;\n    largestYorZ = ( YgtX || ZgtX ) && negTrace;\n    largestZorX = ( ZgtY || !YgtX ) && negTrace;\n    \n    if ( largestXorY )\n    {\n        zz = -zz;\n        xy = -xy;\n    }\n    if ( largestYorZ )\n    {\n        xx = -xx;\n        yz = -yz;\n    }\n    if ( largestZorX )\n    {\n        yy = -yy;\n        zx = -zx;\n    }\n\n    radicand = ( ( ( xx + yy ) + zz ) + 1.0f );\n    scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) );\n\n    tmpx = ( ( zy - yz ) * scale );\n    tmpy = ( ( xz - zx ) * scale );\n    tmpz = ( ( yx - xy ) * scale );\n    tmpw = ( radicand * scale );\n    qx = tmpx;\n    qy = tmpy;\n    qz = tmpz;\n    qw = tmpw;\n\n    if ( largestXorY )\n    {\n        qx = tmpw;\n        qy = tmpz;\n        qz = tmpy;\n        qw = tmpx;\n    }\n    if ( largestYorZ )\n    {\n        tmpx = qx;\n        tmpz = qz;\n        qx = qy;\n        qy = tmpx;\n        qz = qw;\n        qw = tmpz;\n    }\n\n    result->x = qx;\n    result->y = qy;\n    result->z = qz;\n    result->w = qw;\n}\n\nstatic inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *tfrm0, const VmathVector3 *tfrm1 )\n{\n    vmathV3ScalarMul( &result->col0, tfrm0, vmathV3GetX( tfrm1 ) );\n    vmathV3ScalarMul( &result->col1, tfrm0, vmathV3GetY( tfrm1 ) );\n    vmathV3ScalarMul( &result->col2, tfrm0, vmathV3GetZ( tfrm1 ) );\n}\n\nstatic inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *tfrm0, const VmathVector4 *tfrm1 )\n{\n    vmathV4ScalarMul( &result->col0, tfrm0, vmathV4GetX( tfrm1 ) );\n    vmathV4ScalarMul( &result->col1, tfrm0, vmathV4GetY( tfrm1 ) );\n    vmathV4ScalarMul( &result->col2, tfrm0, vmathV4GetZ( tfrm1 ) );\n    vmathV4ScalarMul( &result->col3, tfrm0, vmathV4GetW( tfrm1 ) );\n}\n\nstatic inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat )\n{\n    float tmpX, tmpY, tmpZ;\n    tmpX = ( ( ( vec->x * mat->col0.x ) + ( vec->y * mat->col0.y ) ) + ( vec->z * mat->col0.z ) );\n    tmpY = ( ( ( vec->x * mat->col1.x ) + ( vec->y * mat->col1.y ) ) + ( vec->z * mat->col1.z ) );\n    tmpZ = ( ( ( vec->x * mat->col2.x ) + ( vec->y * mat->col2.y ) ) + ( vec->z * mat->col2.z ) );\n    vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec )\n{\n    vmathV3MakeFromElems( &result->col0, 0.0f, vec->z, -vec->y );\n    vmathV3MakeFromElems( &result->col1, -vec->z, 0.0f, vec->x );\n    vmathV3MakeFromElems( &result->col2, vec->y, -vec->x, 0.0f );\n}\n\nstatic inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathV3Cross( &tmpV3_0, vec, &mat->col0 );\n    vmathV3Cross( &tmpV3_1, vec, &mat->col1 );\n    vmathV3Cross( &tmpV3_2, vec, &mat->col2 );\n    vmathM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 );\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/mat_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_V_C_H\n#define _VECTORMATH_MAT_AOS_V_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2 )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromCols(&result, &_col0, &_col1, &_col2);\n    return result;\n}\n\nstatic inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 _col0 )\n{\n    vmathM3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 _col1 )\n{\n    vmathM3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 _col2 )\n{\n    vmathM3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec )\n{\n    vmathM3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec )\n{\n    vmathM3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val )\n{\n    vmathM3SetElem(result, col, row, val);\n}\n\nstatic inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row )\n{\n    return vmathM3GetElem(&mat, col, row);\n}\n\nstatic inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col )\n{\n    VmathVector3 result;\n    vmathM3GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row )\n{\n    VmathVector3 result;\n    vmathM3GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline float vmathM3Determinant_V( VmathMatrix3 mat )\n{\n    return vmathM3Determinant(&mat);\n}\n\nstatic inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar )\n{\n    VmathMatrix3 result;\n    vmathM3ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathM3MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeIdentity_V( )\n{\n    VmathMatrix3 result;\n    vmathM3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationX_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationY_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathMatrix3 result;\n    vmathM3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec )\n{\n    VmathMatrix3 result;\n    vmathM3AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 )\n{\n    VmathMatrix3 result;\n    vmathM3Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM3Print_V( VmathMatrix3 mat )\n{\n    vmathM3Print(&mat);\n}\n\nstatic inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name )\n{\n    vmathM3Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromT3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 _col0, VmathVector4 _col1, VmathVector4 _col2, VmathVector4 _col3 )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromM3V3(&result, &mat, &translateVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 _col0 )\n{\n    vmathM4SetCol0(result, &_col0);\n}\n\nstatic inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 _col1 )\n{\n    vmathM4SetCol1(result, &_col1);\n}\n\nstatic inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 _col2 )\n{\n    vmathM4SetCol2(result, &_col2);\n}\n\nstatic inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 _col3 )\n{\n    vmathM4SetCol3(result, &_col3);\n}\n\nstatic inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec )\n{\n    vmathM4SetCol(result, col, &vec);\n}\n\nstatic inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec )\n{\n    vmathM4SetRow(result, row, &vec);\n}\n\nstatic inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val )\n{\n    vmathM4SetElem(result, col, row, val);\n}\n\nstatic inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row )\n{\n    return vmathM4GetElem(&mat, col, row);\n}\n\nstatic inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col )\n{\n    VmathVector4 result;\n    vmathM4GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row )\n{\n    VmathVector4 result;\n    vmathM4GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4AffineInverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4OrthoInverse(&result, &mat);\n    return result;\n}\n\nstatic inline float vmathM4Determinant_V( VmathMatrix4 mat )\n{\n    return vmathM4Determinant(&mat);\n}\n\nstatic inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar )\n{\n    VmathMatrix4 result;\n    vmathM4ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathM4MulV4(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec )\n{\n    VmathVector4 result;\n    vmathM4MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt )\n{\n    VmathVector4 result;\n    vmathM4MulP3(&result, &mat, &pnt);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm1 )\n{\n    VmathMatrix4 result;\n    vmathM4MulT3(&result, &mat, &tfrm1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeIdentity_V( )\n{\n    VmathMatrix4 result;\n    vmathM4MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 )\n{\n    vmathM4SetUpper3x3(result, &mat3);\n}\n\nstatic inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat )\n{\n    VmathMatrix3 result;\n    vmathM4GetUpper3x3(&result, &mat);\n    return result;\n}\n\nstatic inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec )\n{\n    vmathM4SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat )\n{\n    VmathVector3 result;\n    vmathM4GetTranslation(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationX_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationY_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec )\n{\n    VmathMatrix4 result;\n    vmathM4AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 )\n{\n    VmathMatrix4 result;\n    vmathM4Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM4Print_V( VmathMatrix4 mat )\n{\n    vmathM4Print(&mat);\n}\n\nstatic inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name )\n{\n    vmathM4Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2, VmathVector3 _col3 )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromM3V3(&result, &tfrm, &translateVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 _col0 )\n{\n    vmathT3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 _col1 )\n{\n    vmathT3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 _col2 )\n{\n    vmathT3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 _col3 )\n{\n    vmathT3SetCol3(result, &_col3);\n}\n\nstatic inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec )\n{\n    vmathT3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec )\n{\n    vmathT3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val )\n{\n    vmathT3SetElem(result, col, row, val);\n}\n\nstatic inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row )\n{\n    return vmathT3GetElem(&tfrm, col, row);\n}\n\nstatic inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol0(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol1(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol2(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col )\n{\n    VmathVector3 result;\n    vmathT3GetCol(&result, &tfrm, col);\n    return result;\n}\n\nstatic inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row )\n{\n    VmathVector4 result;\n    vmathT3GetRow(&result, &tfrm, row);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3Inverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3OrthoInverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3AbsPerElem(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathT3MulV3(&result, &tfrm, &vec);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathT3MulP3(&result, &tfrm, &pnt);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 )\n{\n    VmathTransform3 result;\n    vmathT3Mul(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 )\n{\n    VmathTransform3 result;\n    vmathT3MulPerElem(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeIdentity_V( )\n{\n    VmathTransform3 result;\n    vmathT3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 tfrm )\n{\n    vmathT3SetUpper3x3(result, &tfrm);\n}\n\nstatic inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm )\n{\n    VmathMatrix3 result;\n    vmathT3GetUpper3x3(&result, &tfrm);\n    return result;\n}\n\nstatic inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec )\n{\n    vmathT3SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetTranslation(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationX_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationY_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationZ_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec )\n{\n    VmathTransform3 result;\n    vmathT3AppendScale(&result, &tfrm, &scaleVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3PrependScale(&result, &scaleVec, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 )\n{\n    VmathTransform3 result;\n    vmathT3Select(&result, &tfrm0, &tfrm1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathT3Print_V( VmathTransform3 tfrm )\n{\n    vmathT3Print(&tfrm);\n}\n\nstatic inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name )\n{\n    vmathT3Prints(&tfrm, name);\n}\n\n#endif\n\nstatic inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 tfrm )\n{\n    VmathQuat result;\n    vmathQMakeFromM3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3Outer_V( VmathVector3 tfrm0, VmathVector3 tfrm1 )\n{\n    VmathMatrix3 result;\n    vmathV3Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathV4Outer_V( VmathVector4 tfrm0, VmathVector4 tfrm1 )\n{\n    VmathMatrix4 result;\n    vmathV4Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathV3RowMul(&result, &vec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec )\n{\n    VmathMatrix3 result;\n    vmathV3CrossMatrix(&result, &vec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathV3CrossMatrixMul(&result, &vec, &mat);\n    return result;\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_C_H\n#define _VECTORMATH_QUAT_AOS_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat )\n{\n    result->x = quat->x;\n    result->y = quat->y;\n    result->z = quat->z;\n    result->w = quat->w;\n}\n\nstatic inline void vmathQMakeFromElems( VmathQuat *result, float _x, float _y, float _z, float _w )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n    result->w = _w;\n}\n\nstatic inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float _w )\n{\n    vmathQSetXYZ( result, xyz );\n    vmathQSetW( result, _w );\n}\n\nstatic inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = vec->w;\n}\n\nstatic inline void vmathQMakeFromScalar( VmathQuat *result, float scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n    result->w = scalar;\n}\n\nstatic inline void vmathQMakeIdentity( VmathQuat *result )\n{\n    vmathQMakeFromElems( result, 0.0f, 0.0f, 0.0f, 1.0f );\n}\n\nstatic inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    VmathQuat tmpQ_0, tmpQ_1;\n    vmathQSub( &tmpQ_0, quat1, quat0 );\n    vmathQScalarMul( &tmpQ_1, &tmpQ_0, t );\n    vmathQAdd( result, quat0, &tmpQ_1 );\n}\n\nstatic inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 )\n{\n    VmathQuat start, tmpQ_0, tmpQ_1;\n    float recipSinAngle, scale0, scale1, cosAngle, angle;\n    cosAngle = vmathQDot( unitQuat0, unitQuat1 );\n    if ( cosAngle < 0.0f ) {\n        cosAngle = -cosAngle;\n        vmathQNeg( &start, unitQuat0 );\n    } else {\n        vmathQCopy( &start, unitQuat0 );\n    }\n    if ( cosAngle < _VECTORMATH_SLERP_TOL ) {\n        angle = acosf( cosAngle );\n        recipSinAngle = ( 1.0f / sinf( angle ) );\n        scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );\n        scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );\n    } else {\n        scale0 = ( 1.0f - t );\n        scale1 = t;\n    }\n    vmathQScalarMul( &tmpQ_0, &start, scale0 );\n    vmathQScalarMul( &tmpQ_1, unitQuat1, scale1 );\n    vmathQAdd( result, &tmpQ_0, &tmpQ_1 );\n}\n\nstatic inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 )\n{\n    VmathQuat tmp0, tmp1;\n    vmathQSlerp( &tmp0, t, unitQuat0, unitQuat3 );\n    vmathQSlerp( &tmp1, t, unitQuat1, unitQuat2 );\n    vmathQSlerp( result, ( ( 2.0f * t ) * ( 1.0f - t ) ), &tmp0, &tmp1 );\n}\n\nstatic inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat )\n{\n    vmathV3MakeFromElems( result, quat->x, quat->y, quat->z );\n}\n\nstatic inline void vmathQSetX( VmathQuat *result, float _x )\n{\n    result->x = _x;\n}\n\nstatic inline float vmathQGetX( const VmathQuat *quat )\n{\n    return quat->x;\n}\n\nstatic inline void vmathQSetY( VmathQuat *result, float _y )\n{\n    result->y = _y;\n}\n\nstatic inline float vmathQGetY( const VmathQuat *quat )\n{\n    return quat->y;\n}\n\nstatic inline void vmathQSetZ( VmathQuat *result, float _z )\n{\n    result->z = _z;\n}\n\nstatic inline float vmathQGetZ( const VmathQuat *quat )\n{\n    return quat->z;\n}\n\nstatic inline void vmathQSetW( VmathQuat *result, float _w )\n{\n    result->w = _w;\n}\n\nstatic inline float vmathQGetW( const VmathQuat *quat )\n{\n    return quat->w;\n}\n\nstatic inline void vmathQSetElem( VmathQuat *result, int idx, float value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline float vmathQGetElem( const VmathQuat *quat, int idx )\n{\n    return *(&quat->x + idx);\n}\n\nstatic inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    result->x = ( quat0->x + quat1->x );\n    result->y = ( quat0->y + quat1->y );\n    result->z = ( quat0->z + quat1->z );\n    result->w = ( quat0->w + quat1->w );\n}\n\nstatic inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    result->x = ( quat0->x - quat1->x );\n    result->y = ( quat0->y - quat1->y );\n    result->z = ( quat0->z - quat1->z );\n    result->w = ( quat0->w - quat1->w );\n}\n\nstatic inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar )\n{\n    result->x = ( quat->x * scalar );\n    result->y = ( quat->y * scalar );\n    result->z = ( quat->z * scalar );\n    result->w = ( quat->w * scalar );\n}\n\nstatic inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar )\n{\n    result->x = ( quat->x / scalar );\n    result->y = ( quat->y / scalar );\n    result->z = ( quat->z / scalar );\n    result->w = ( quat->w / scalar );\n}\n\nstatic inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat )\n{\n    result->x = -quat->x;\n    result->y = -quat->y;\n    result->z = -quat->z;\n    result->w = -quat->w;\n}\n\nstatic inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    float result;\n    result = ( quat0->x * quat1->x );\n    result = ( result + ( quat0->y * quat1->y ) );\n    result = ( result + ( quat0->z * quat1->z ) );\n    result = ( result + ( quat0->w * quat1->w ) );\n    return result;\n}\n\nstatic inline float vmathQNorm( const VmathQuat *quat )\n{\n    float result;\n    result = ( quat->x * quat->x );\n    result = ( result + ( quat->y * quat->y ) );\n    result = ( result + ( quat->z * quat->z ) );\n    result = ( result + ( quat->w * quat->w ) );\n    return result;\n}\n\nstatic inline float vmathQLength( const VmathQuat *quat )\n{\n    return sqrtf( vmathQNorm( quat ) );\n}\n\nstatic inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat )\n{\n    float lenSqr, lenInv;\n    lenSqr = vmathQNorm( quat );\n    lenInv = ( 1.0f / sqrtf( lenSqr ) );\n    result->x = ( quat->x * lenInv );\n    result->y = ( quat->y * lenInv );\n    result->z = ( quat->z * lenInv );\n    result->w = ( quat->w * lenInv );\n}\n\nstatic inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    float cosHalfAngleX2, recipCosHalfAngleX2;\n    cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + vmathV3Dot( unitVec0, unitVec1 ) ) ) );\n    recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 );\n    vmathV3Cross( &tmpV3_0, unitVec0, unitVec1 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 );\n    vmathQMakeFromV3Scalar( result, &tmpV3_1, ( cosHalfAngleX2 * 0.5f ) );\n}\n\nstatic inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec )\n{\n    VmathVector3 tmpV3_0;\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    vmathV3ScalarMul( &tmpV3_0, unitVec, s );\n    vmathQMakeFromV3Scalar( result, &tmpV3_0, c );\n}\n\nstatic inline void vmathQMakeRotationX( VmathQuat *result, float radians )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    vmathQMakeFromElems( result, s, 0.0f, 0.0f, c );\n}\n\nstatic inline void vmathQMakeRotationY( VmathQuat *result, float radians )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    vmathQMakeFromElems( result, 0.0f, s, 0.0f, c );\n}\n\nstatic inline void vmathQMakeRotationZ( VmathQuat *result, float radians )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    vmathQMakeFromElems( result, 0.0f, 0.0f, s, c );\n}\n\nstatic inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    float tmpX, tmpY, tmpZ, tmpW;\n    tmpX = ( ( ( ( quat0->w * quat1->x ) + ( quat0->x * quat1->w ) ) + ( quat0->y * quat1->z ) ) - ( quat0->z * quat1->y ) );\n    tmpY = ( ( ( ( quat0->w * quat1->y ) + ( quat0->y * quat1->w ) ) + ( quat0->z * quat1->x ) ) - ( quat0->x * quat1->z ) );\n    tmpZ = ( ( ( ( quat0->w * quat1->z ) + ( quat0->z * quat1->w ) ) + ( quat0->x * quat1->y ) ) - ( quat0->y * quat1->x ) );\n    tmpW = ( ( ( ( quat0->w * quat1->w ) - ( quat0->x * quat1->x ) ) - ( quat0->y * quat1->y ) ) - ( quat0->z * quat1->z ) );\n    vmathQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );\n}\n\nstatic inline void vmathQRotate( VmathVector3 *result, const VmathQuat *quat, const VmathVector3 *vec )\n{\n    float tmpX, tmpY, tmpZ, tmpW;\n    tmpX = ( ( ( quat->w * vec->x ) + ( quat->y * vec->z ) ) - ( quat->z * vec->y ) );\n    tmpY = ( ( ( quat->w * vec->y ) + ( quat->z * vec->x ) ) - ( quat->x * vec->z ) );\n    tmpZ = ( ( ( quat->w * vec->z ) + ( quat->x * vec->y ) ) - ( quat->y * vec->x ) );\n    tmpW = ( ( ( quat->x * vec->x ) + ( quat->y * vec->y ) ) + ( quat->z * vec->z ) );\n    result->x = ( ( ( ( tmpW * quat->x ) + ( tmpX * quat->w ) ) - ( tmpY * quat->z ) ) + ( tmpZ * quat->y ) );\n    result->y = ( ( ( ( tmpW * quat->y ) + ( tmpY * quat->w ) ) - ( tmpZ * quat->x ) ) + ( tmpX * quat->z ) );\n    result->z = ( ( ( ( tmpW * quat->z ) + ( tmpZ * quat->w ) ) - ( tmpX * quat->y ) ) + ( tmpY * quat->x ) );\n}\n\nstatic inline void vmathQConj( VmathQuat *result, const VmathQuat *quat )\n{\n    vmathQMakeFromElems( result, -quat->x, -quat->y, -quat->z, quat->w );\n}\n\nstatic inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 )\n{\n    result->x = ( select1 )? quat1->x : quat0->x;\n    result->y = ( select1 )? quat1->y : quat0->y;\n    result->z = ( select1 )? quat1->z : quat0->z;\n    result->w = ( select1 )? quat1->w : quat0->w;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathQPrint( const VmathQuat *quat )\n{\n    printf( \"( %f %f %f %f )\\n\", quat->x, quat->y, quat->z, quat->w );\n}\n\nstatic inline void vmathQPrints( const VmathQuat *quat, const char *name )\n{\n    printf( \"%s: ( %f %f %f %f )\\n\", name, quat->x, quat->y, quat->z, quat->w );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/quat_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_V_C_H\n#define _VECTORMATH_QUAT_AOS_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathQuat vmathQMakeFromElems_V( float _x, float _y, float _z, float _w )\n{\n    VmathQuat result;\n    vmathQMakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float _w )\n{\n    VmathQuat result;\n    vmathQMakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec )\n{\n    VmathQuat result;\n    vmathQMakeFromV4(&result, &vec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromScalar_V( float scalar )\n{\n    VmathQuat result;\n    vmathQMakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeIdentity_V( )\n{\n    VmathQuat result;\n    vmathQMakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQLerp(&result, t, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 )\n{\n    VmathQuat result;\n    vmathQSlerp(&result, t, &unitQuat0, &unitQuat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 )\n{\n    VmathQuat result;\n    vmathQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3);\n    return result;\n}\n\nstatic inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec )\n{\n    vmathQSetXYZ(result, &vec);\n}\n\nstatic inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat )\n{\n    VmathVector3 result;\n    vmathQGetXYZ(&result, &quat);\n    return result;\n}\n\nstatic inline void vmathQSetX_V( VmathQuat *result, float _x )\n{\n    vmathQSetX(result, _x);\n}\n\nstatic inline float vmathQGetX_V( VmathQuat quat )\n{\n    return vmathQGetX(&quat);\n}\n\nstatic inline void vmathQSetY_V( VmathQuat *result, float _y )\n{\n    vmathQSetY(result, _y);\n}\n\nstatic inline float vmathQGetY_V( VmathQuat quat )\n{\n    return vmathQGetY(&quat);\n}\n\nstatic inline void vmathQSetZ_V( VmathQuat *result, float _z )\n{\n    vmathQSetZ(result, _z);\n}\n\nstatic inline float vmathQGetZ_V( VmathQuat quat )\n{\n    return vmathQGetZ(&quat);\n}\n\nstatic inline void vmathQSetW_V( VmathQuat *result, float _w )\n{\n    vmathQSetW(result, _w);\n}\n\nstatic inline float vmathQGetW_V( VmathQuat quat )\n{\n    return vmathQGetW(&quat);\n}\n\nstatic inline void vmathQSetElem_V( VmathQuat *result, int idx, float value )\n{\n    vmathQSetElem(result, idx, value);\n}\n\nstatic inline float vmathQGetElem_V( VmathQuat quat, int idx )\n{\n    return vmathQGetElem(&quat, idx);\n}\n\nstatic inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQAdd(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQSub(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar )\n{\n    VmathQuat result;\n    vmathQScalarMul(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar )\n{\n    VmathQuat result;\n    vmathQScalarDiv(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQNeg_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQNeg(&result, &quat);\n    return result;\n}\n\nstatic inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    return vmathQDot(&quat0, &quat1);\n}\n\nstatic inline float vmathQNorm_V( VmathQuat quat )\n{\n    return vmathQNorm(&quat);\n}\n\nstatic inline float vmathQLength_V( VmathQuat quat )\n{\n    return vmathQLength(&quat);\n}\n\nstatic inline VmathQuat vmathQNormalize_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQNormalize(&result, &quat);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 )\n{\n    VmathQuat result;\n    vmathQMakeRotationArc(&result, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathQuat result;\n    vmathQMakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationX_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationY_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationZ_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQMul(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathQRotate_V( VmathQuat quat, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathQRotate(&result, &quat, &vec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQConj_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQConj(&result, &quat);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 )\n{\n    VmathQuat result;\n    vmathQSelect(&result, &quat0, &quat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathQPrint_V( VmathQuat quat )\n{\n    vmathQPrint(&quat);\n}\n\nstatic inline void vmathQPrints_V( VmathQuat quat, const char *name )\n{\n    vmathQPrints(&quat, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_C_H\n#define _VECTORMATH_VEC_AOS_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathV3MakeFromElems( VmathVector3 *result, float _x, float _y, float _z )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n}\n\nstatic inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n}\n\nstatic inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n}\n\nstatic inline void vmathV3MakeXAxis( VmathVector3 *result )\n{\n    vmathV3MakeFromElems( result, 1.0f, 0.0f, 0.0f );\n}\n\nstatic inline void vmathV3MakeYAxis( VmathVector3 *result )\n{\n    vmathV3MakeFromElems( result, 0.0f, 1.0f, 0.0f );\n}\n\nstatic inline void vmathV3MakeZAxis( VmathVector3 *result )\n{\n    vmathV3MakeFromElems( result, 0.0f, 0.0f, 1.0f );\n}\n\nstatic inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    vmathV3Sub( &tmpV3_0, vec1, vec0 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathV3Add( result, vec0, &tmpV3_1 );\n}\n\nstatic inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    float recipSinAngle, scale0, scale1, cosAngle, angle;\n    cosAngle = vmathV3Dot( unitVec0, unitVec1 );\n    if ( cosAngle < _VECTORMATH_SLERP_TOL ) {\n        angle = acosf( cosAngle );\n        recipSinAngle = ( 1.0f / sinf( angle ) );\n        scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );\n        scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );\n    } else {\n        scale0 = ( 1.0f - t );\n        scale1 = t;\n    }\n    vmathV3ScalarMul( &tmpV3_0, unitVec0, scale0 );\n    vmathV3ScalarMul( &tmpV3_1, unitVec1, scale1 );\n    vmathV3Add( result, &tmpV3_0, &tmpV3_1 );\n}\n\nstatic inline void vmathV3SetX( VmathVector3 *result, float _x )\n{\n    result->x = _x;\n}\n\nstatic inline float vmathV3GetX( const VmathVector3 *vec )\n{\n    return vec->x;\n}\n\nstatic inline void vmathV3SetY( VmathVector3 *result, float _y )\n{\n    result->y = _y;\n}\n\nstatic inline float vmathV3GetY( const VmathVector3 *vec )\n{\n    return vec->y;\n}\n\nstatic inline void vmathV3SetZ( VmathVector3 *result, float _z )\n{\n    result->z = _z;\n}\n\nstatic inline float vmathV3GetZ( const VmathVector3 *vec )\n{\n    return vec->z;\n}\n\nstatic inline void vmathV3SetElem( VmathVector3 *result, int idx, float value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline float vmathV3GetElem( const VmathVector3 *vec, int idx )\n{\n    return *(&vec->x + idx);\n}\n\nstatic inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = ( vec0->x + vec1->x );\n    result->y = ( vec0->y + vec1->y );\n    result->z = ( vec0->z + vec1->z );\n}\n\nstatic inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = ( vec0->x - vec1->x );\n    result->y = ( vec0->y - vec1->y );\n    result->z = ( vec0->z - vec1->z );\n}\n\nstatic inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt1 )\n{\n    result->x = ( vec->x + pnt1->x );\n    result->y = ( vec->y + pnt1->y );\n    result->z = ( vec->z + pnt1->z );\n}\n\nstatic inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar )\n{\n    result->x = ( vec->x * scalar );\n    result->y = ( vec->y * scalar );\n    result->z = ( vec->z * scalar );\n}\n\nstatic inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar )\n{\n    result->x = ( vec->x / scalar );\n    result->y = ( vec->y / scalar );\n    result->z = ( vec->z / scalar );\n}\n\nstatic inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->x = -vec->x;\n    result->y = -vec->y;\n    result->z = -vec->z;\n}\n\nstatic inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = ( vec0->x * vec1->x );\n    result->y = ( vec0->y * vec1->y );\n    result->z = ( vec0->z * vec1->z );\n}\n\nstatic inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = ( vec0->x / vec1->x );\n    result->y = ( vec0->y / vec1->y );\n    result->z = ( vec0->z / vec1->z );\n}\n\nstatic inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->x = ( 1.0f / vec->x );\n    result->y = ( 1.0f / vec->y );\n    result->z = ( 1.0f / vec->z );\n}\n\nstatic inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->x = sqrtf( vec->x );\n    result->y = sqrtf( vec->y );\n    result->z = sqrtf( vec->z );\n}\n\nstatic inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->x = ( 1.0f / sqrtf( vec->x ) );\n    result->y = ( 1.0f / sqrtf( vec->y ) );\n    result->z = ( 1.0f / sqrtf( vec->z ) );\n}\n\nstatic inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->x = fabsf( vec->x );\n    result->y = fabsf( vec->y );\n    result->z = fabsf( vec->z );\n}\n\nstatic inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = ( vec1->x < 0.0f )? -fabsf( vec0->x ) : fabsf( vec0->x );\n    result->y = ( vec1->y < 0.0f )? -fabsf( vec0->y ) : fabsf( vec0->y );\n    result->z = ( vec1->z < 0.0f )? -fabsf( vec0->z ) : fabsf( vec0->z );\n}\n\nstatic inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = (vec0->x > vec1->x)? vec0->x : vec1->x;\n    result->y = (vec0->y > vec1->y)? vec0->y : vec1->y;\n    result->z = (vec0->z > vec1->z)? vec0->z : vec1->z;\n}\n\nstatic inline float vmathV3MaxElem( const VmathVector3 *vec )\n{\n    float result;\n    result = (vec->x > vec->y)? vec->x : vec->y;\n    result = (vec->z > result)? vec->z : result;\n    return result;\n}\n\nstatic inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->x = (vec0->x < vec1->x)? vec0->x : vec1->x;\n    result->y = (vec0->y < vec1->y)? vec0->y : vec1->y;\n    result->z = (vec0->z < vec1->z)? vec0->z : vec1->z;\n}\n\nstatic inline float vmathV3MinElem( const VmathVector3 *vec )\n{\n    float result;\n    result = (vec->x < vec->y)? vec->x : vec->y;\n    result = (vec->z < result)? vec->z : result;\n    return result;\n}\n\nstatic inline float vmathV3Sum( const VmathVector3 *vec )\n{\n    float result;\n    result = ( vec->x + vec->y );\n    result = ( result + vec->z );\n    return result;\n}\n\nstatic inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    float result;\n    result = ( vec0->x * vec1->x );\n    result = ( result + ( vec0->y * vec1->y ) );\n    result = ( result + ( vec0->z * vec1->z ) );\n    return result;\n}\n\nstatic inline float vmathV3LengthSqr( const VmathVector3 *vec )\n{\n    float result;\n    result = ( vec->x * vec->x );\n    result = ( result + ( vec->y * vec->y ) );\n    result = ( result + ( vec->z * vec->z ) );\n    return result;\n}\n\nstatic inline float vmathV3Length( const VmathVector3 *vec )\n{\n    return sqrtf( vmathV3LengthSqr( vec ) );\n}\n\nstatic inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec )\n{\n    float lenSqr, lenInv;\n    lenSqr = vmathV3LengthSqr( vec );\n    lenInv = ( 1.0f / sqrtf( lenSqr ) );\n    result->x = ( vec->x * lenInv );\n    result->y = ( vec->y * lenInv );\n    result->z = ( vec->z * lenInv );\n}\n\nstatic inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    float tmpX, tmpY, tmpZ;\n    tmpX = ( ( vec0->y * vec1->z ) - ( vec0->z * vec1->y ) );\n    tmpY = ( ( vec0->z * vec1->x ) - ( vec0->x * vec1->z ) );\n    tmpZ = ( ( vec0->x * vec1->y ) - ( vec0->y * vec1->x ) );\n    vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 )\n{\n    result->x = ( select1 )? vec1->x : vec0->x;\n    result->y = ( select1 )? vec1->y : vec0->y;\n    result->z = ( select1 )? vec1->z : vec0->z;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV3Print( const VmathVector3 *vec )\n{\n    printf( \"( %f %f %f )\\n\", vec->x, vec->y, vec->z );\n}\n\nstatic inline void vmathV3Prints( const VmathVector3 *vec, const char *name )\n{\n    printf( \"%s: ( %f %f %f )\\n\", name, vec->x, vec->y, vec->z );\n}\n\n#endif\n\nstatic inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = vec->w;\n}\n\nstatic inline void vmathV4MakeFromElems( VmathVector4 *result, float _x, float _y, float _z, float _w )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n    result->w = _w;\n}\n\nstatic inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float _w )\n{\n    vmathV4SetXYZ( result, xyz );\n    vmathV4SetW( result, _w );\n}\n\nstatic inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = 0.0f;\n}\n\nstatic inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n    result->w = 1.0f;\n}\n\nstatic inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat )\n{\n    result->x = quat->x;\n    result->y = quat->y;\n    result->z = quat->z;\n    result->w = quat->w;\n}\n\nstatic inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n    result->w = scalar;\n}\n\nstatic inline void vmathV4MakeXAxis( VmathVector4 *result )\n{\n    vmathV4MakeFromElems( result, 1.0f, 0.0f, 0.0f, 0.0f );\n}\n\nstatic inline void vmathV4MakeYAxis( VmathVector4 *result )\n{\n    vmathV4MakeFromElems( result, 0.0f, 1.0f, 0.0f, 0.0f );\n}\n\nstatic inline void vmathV4MakeZAxis( VmathVector4 *result )\n{\n    vmathV4MakeFromElems( result, 0.0f, 0.0f, 1.0f, 0.0f );\n}\n\nstatic inline void vmathV4MakeWAxis( VmathVector4 *result )\n{\n    vmathV4MakeFromElems( result, 0.0f, 0.0f, 0.0f, 1.0f );\n}\n\nstatic inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    VmathVector4 tmpV4_0, tmpV4_1;\n    vmathV4Sub( &tmpV4_0, vec1, vec0 );\n    vmathV4ScalarMul( &tmpV4_1, &tmpV4_0, t );\n    vmathV4Add( result, vec0, &tmpV4_1 );\n}\n\nstatic inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 )\n{\n    VmathVector4 tmpV4_0, tmpV4_1;\n    float recipSinAngle, scale0, scale1, cosAngle, angle;\n    cosAngle = vmathV4Dot( unitVec0, unitVec1 );\n    if ( cosAngle < _VECTORMATH_SLERP_TOL ) {\n        angle = acosf( cosAngle );\n        recipSinAngle = ( 1.0f / sinf( angle ) );\n        scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );\n        scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );\n    } else {\n        scale0 = ( 1.0f - t );\n        scale1 = t;\n    }\n    vmathV4ScalarMul( &tmpV4_0, unitVec0, scale0 );\n    vmathV4ScalarMul( &tmpV4_1, unitVec1, scale1 );\n    vmathV4Add( result, &tmpV4_0, &tmpV4_1 );\n}\n\nstatic inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec )\n{\n    vmathV3MakeFromElems( result, vec->x, vec->y, vec->z );\n}\n\nstatic inline void vmathV4SetX( VmathVector4 *result, float _x )\n{\n    result->x = _x;\n}\n\nstatic inline float vmathV4GetX( const VmathVector4 *vec )\n{\n    return vec->x;\n}\n\nstatic inline void vmathV4SetY( VmathVector4 *result, float _y )\n{\n    result->y = _y;\n}\n\nstatic inline float vmathV4GetY( const VmathVector4 *vec )\n{\n    return vec->y;\n}\n\nstatic inline void vmathV4SetZ( VmathVector4 *result, float _z )\n{\n    result->z = _z;\n}\n\nstatic inline float vmathV4GetZ( const VmathVector4 *vec )\n{\n    return vec->z;\n}\n\nstatic inline void vmathV4SetW( VmathVector4 *result, float _w )\n{\n    result->w = _w;\n}\n\nstatic inline float vmathV4GetW( const VmathVector4 *vec )\n{\n    return vec->w;\n}\n\nstatic inline void vmathV4SetElem( VmathVector4 *result, int idx, float value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline float vmathV4GetElem( const VmathVector4 *vec, int idx )\n{\n    return *(&vec->x + idx);\n}\n\nstatic inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = ( vec0->x + vec1->x );\n    result->y = ( vec0->y + vec1->y );\n    result->z = ( vec0->z + vec1->z );\n    result->w = ( vec0->w + vec1->w );\n}\n\nstatic inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = ( vec0->x - vec1->x );\n    result->y = ( vec0->y - vec1->y );\n    result->z = ( vec0->z - vec1->z );\n    result->w = ( vec0->w - vec1->w );\n}\n\nstatic inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar )\n{\n    result->x = ( vec->x * scalar );\n    result->y = ( vec->y * scalar );\n    result->z = ( vec->z * scalar );\n    result->w = ( vec->w * scalar );\n}\n\nstatic inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar )\n{\n    result->x = ( vec->x / scalar );\n    result->y = ( vec->y / scalar );\n    result->z = ( vec->z / scalar );\n    result->w = ( vec->w / scalar );\n}\n\nstatic inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->x = -vec->x;\n    result->y = -vec->y;\n    result->z = -vec->z;\n    result->w = -vec->w;\n}\n\nstatic inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = ( vec0->x * vec1->x );\n    result->y = ( vec0->y * vec1->y );\n    result->z = ( vec0->z * vec1->z );\n    result->w = ( vec0->w * vec1->w );\n}\n\nstatic inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = ( vec0->x / vec1->x );\n    result->y = ( vec0->y / vec1->y );\n    result->z = ( vec0->z / vec1->z );\n    result->w = ( vec0->w / vec1->w );\n}\n\nstatic inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->x = ( 1.0f / vec->x );\n    result->y = ( 1.0f / vec->y );\n    result->z = ( 1.0f / vec->z );\n    result->w = ( 1.0f / vec->w );\n}\n\nstatic inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->x = sqrtf( vec->x );\n    result->y = sqrtf( vec->y );\n    result->z = sqrtf( vec->z );\n    result->w = sqrtf( vec->w );\n}\n\nstatic inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->x = ( 1.0f / sqrtf( vec->x ) );\n    result->y = ( 1.0f / sqrtf( vec->y ) );\n    result->z = ( 1.0f / sqrtf( vec->z ) );\n    result->w = ( 1.0f / sqrtf( vec->w ) );\n}\n\nstatic inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->x = fabsf( vec->x );\n    result->y = fabsf( vec->y );\n    result->z = fabsf( vec->z );\n    result->w = fabsf( vec->w );\n}\n\nstatic inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = ( vec1->x < 0.0f )? -fabsf( vec0->x ) : fabsf( vec0->x );\n    result->y = ( vec1->y < 0.0f )? -fabsf( vec0->y ) : fabsf( vec0->y );\n    result->z = ( vec1->z < 0.0f )? -fabsf( vec0->z ) : fabsf( vec0->z );\n    result->w = ( vec1->w < 0.0f )? -fabsf( vec0->w ) : fabsf( vec0->w );\n}\n\nstatic inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = (vec0->x > vec1->x)? vec0->x : vec1->x;\n    result->y = (vec0->y > vec1->y)? vec0->y : vec1->y;\n    result->z = (vec0->z > vec1->z)? vec0->z : vec1->z;\n    result->w = (vec0->w > vec1->w)? vec0->w : vec1->w;\n}\n\nstatic inline float vmathV4MaxElem( const VmathVector4 *vec )\n{\n    float result;\n    result = (vec->x > vec->y)? vec->x : vec->y;\n    result = (vec->z > result)? vec->z : result;\n    result = (vec->w > result)? vec->w : result;\n    return result;\n}\n\nstatic inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->x = (vec0->x < vec1->x)? vec0->x : vec1->x;\n    result->y = (vec0->y < vec1->y)? vec0->y : vec1->y;\n    result->z = (vec0->z < vec1->z)? vec0->z : vec1->z;\n    result->w = (vec0->w < vec1->w)? vec0->w : vec1->w;\n}\n\nstatic inline float vmathV4MinElem( const VmathVector4 *vec )\n{\n    float result;\n    result = (vec->x < vec->y)? vec->x : vec->y;\n    result = (vec->z < result)? vec->z : result;\n    result = (vec->w < result)? vec->w : result;\n    return result;\n}\n\nstatic inline float vmathV4Sum( const VmathVector4 *vec )\n{\n    float result;\n    result = ( vec->x + vec->y );\n    result = ( result + vec->z );\n    result = ( result + vec->w );\n    return result;\n}\n\nstatic inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    float result;\n    result = ( vec0->x * vec1->x );\n    result = ( result + ( vec0->y * vec1->y ) );\n    result = ( result + ( vec0->z * vec1->z ) );\n    result = ( result + ( vec0->w * vec1->w ) );\n    return result;\n}\n\nstatic inline float vmathV4LengthSqr( const VmathVector4 *vec )\n{\n    float result;\n    result = ( vec->x * vec->x );\n    result = ( result + ( vec->y * vec->y ) );\n    result = ( result + ( vec->z * vec->z ) );\n    result = ( result + ( vec->w * vec->w ) );\n    return result;\n}\n\nstatic inline float vmathV4Length( const VmathVector4 *vec )\n{\n    return sqrtf( vmathV4LengthSqr( vec ) );\n}\n\nstatic inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec )\n{\n    float lenSqr, lenInv;\n    lenSqr = vmathV4LengthSqr( vec );\n    lenInv = ( 1.0f / sqrtf( lenSqr ) );\n    result->x = ( vec->x * lenInv );\n    result->y = ( vec->y * lenInv );\n    result->z = ( vec->z * lenInv );\n    result->w = ( vec->w * lenInv );\n}\n\nstatic inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 )\n{\n    result->x = ( select1 )? vec1->x : vec0->x;\n    result->y = ( select1 )? vec1->y : vec0->y;\n    result->z = ( select1 )? vec1->z : vec0->z;\n    result->w = ( select1 )? vec1->w : vec0->w;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV4Print( const VmathVector4 *vec )\n{\n    printf( \"( %f %f %f %f )\\n\", vec->x, vec->y, vec->z, vec->w );\n}\n\nstatic inline void vmathV4Prints( const VmathVector4 *vec, const char *name )\n{\n    printf( \"%s: ( %f %f %f %f )\\n\", name, vec->x, vec->y, vec->z, vec->w );\n}\n\n#endif\n\nstatic inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n}\n\nstatic inline void vmathP3MakeFromElems( VmathPoint3 *result, float _x, float _y, float _z )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n}\n\nstatic inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n}\n\nstatic inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathP3AddV3( result, pnt0, &tmpV3_1 );\n}\n\nstatic inline void vmathP3SetX( VmathPoint3 *result, float _x )\n{\n    result->x = _x;\n}\n\nstatic inline float vmathP3GetX( const VmathPoint3 *pnt )\n{\n    return pnt->x;\n}\n\nstatic inline void vmathP3SetY( VmathPoint3 *result, float _y )\n{\n    result->y = _y;\n}\n\nstatic inline float vmathP3GetY( const VmathPoint3 *pnt )\n{\n    return pnt->y;\n}\n\nstatic inline void vmathP3SetZ( VmathPoint3 *result, float _z )\n{\n    result->z = _z;\n}\n\nstatic inline float vmathP3GetZ( const VmathPoint3 *pnt )\n{\n    return pnt->z;\n}\n\nstatic inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx )\n{\n    return *(&pnt->x + idx);\n}\n\nstatic inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->x = ( pnt0->x - pnt1->x );\n    result->y = ( pnt0->y - pnt1->y );\n    result->z = ( pnt0->z - pnt1->z );\n}\n\nstatic inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 )\n{\n    result->x = ( pnt->x + vec1->x );\n    result->y = ( pnt->y + vec1->y );\n    result->z = ( pnt->z + vec1->z );\n}\n\nstatic inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 )\n{\n    result->x = ( pnt->x - vec1->x );\n    result->y = ( pnt->y - vec1->y );\n    result->z = ( pnt->z - vec1->z );\n}\n\nstatic inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->x = ( pnt0->x * pnt1->x );\n    result->y = ( pnt0->y * pnt1->y );\n    result->z = ( pnt0->z * pnt1->z );\n}\n\nstatic inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->x = ( pnt0->x / pnt1->x );\n    result->y = ( pnt0->y / pnt1->y );\n    result->z = ( pnt0->z / pnt1->z );\n}\n\nstatic inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->x = ( 1.0f / pnt->x );\n    result->y = ( 1.0f / pnt->y );\n    result->z = ( 1.0f / pnt->z );\n}\n\nstatic inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->x = sqrtf( pnt->x );\n    result->y = sqrtf( pnt->y );\n    result->z = sqrtf( pnt->z );\n}\n\nstatic inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->x = ( 1.0f / sqrtf( pnt->x ) );\n    result->y = ( 1.0f / sqrtf( pnt->y ) );\n    result->z = ( 1.0f / sqrtf( pnt->z ) );\n}\n\nstatic inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->x = fabsf( pnt->x );\n    result->y = fabsf( pnt->y );\n    result->z = fabsf( pnt->z );\n}\n\nstatic inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->x = ( pnt1->x < 0.0f )? -fabsf( pnt0->x ) : fabsf( pnt0->x );\n    result->y = ( pnt1->y < 0.0f )? -fabsf( pnt0->y ) : fabsf( pnt0->y );\n    result->z = ( pnt1->z < 0.0f )? -fabsf( pnt0->z ) : fabsf( pnt0->z );\n}\n\nstatic inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->x = (pnt0->x > pnt1->x)? pnt0->x : pnt1->x;\n    result->y = (pnt0->y > pnt1->y)? pnt0->y : pnt1->y;\n    result->z = (pnt0->z > pnt1->z)? pnt0->z : pnt1->z;\n}\n\nstatic inline float vmathP3MaxElem( const VmathPoint3 *pnt )\n{\n    float result;\n    result = (pnt->x > pnt->y)? pnt->x : pnt->y;\n    result = (pnt->z > result)? pnt->z : result;\n    return result;\n}\n\nstatic inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->x = (pnt0->x < pnt1->x)? pnt0->x : pnt1->x;\n    result->y = (pnt0->y < pnt1->y)? pnt0->y : pnt1->y;\n    result->z = (pnt0->z < pnt1->z)? pnt0->z : pnt1->z;\n}\n\nstatic inline float vmathP3MinElem( const VmathPoint3 *pnt )\n{\n    float result;\n    result = (pnt->x < pnt->y)? pnt->x : pnt->y;\n    result = (pnt->z < result)? pnt->z : result;\n    return result;\n}\n\nstatic inline float vmathP3Sum( const VmathPoint3 *pnt )\n{\n    float result;\n    result = ( pnt->x + pnt->y );\n    result = ( result + pnt->z );\n    return result;\n}\n\nstatic inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal )\n{\n    VmathPoint3 tmpP3_0;\n    vmathP3MakeFromScalar( &tmpP3_0, scaleVal );\n    vmathP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec )\n{\n    VmathPoint3 tmpP3_0;\n    vmathP3MakeFromV3( &tmpP3_0, scaleVec );\n    vmathP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec )\n{\n    float result;\n    result = ( pnt->x * unitVec->x );\n    result = ( result + ( pnt->y * unitVec->y ) );\n    result = ( result + ( pnt->z * unitVec->z ) );\n    return result;\n}\n\nstatic inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathV3Length( &tmpV3_0 );\n}\n\nstatic inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathV3Length( &tmpV3_0 );\n}\n\nstatic inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 )\n{\n    result->x = ( select1 )? pnt1->x : pnt0->x;\n    result->y = ( select1 )? pnt1->y : pnt0->y;\n    result->z = ( select1 )? pnt1->z : pnt0->z;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathP3Print( const VmathPoint3 *pnt )\n{\n    printf( \"( %f %f %f )\\n\", pnt->x, pnt->y, pnt->z );\n}\n\nstatic inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name )\n{\n    printf( \"%s: ( %f %f %f )\\n\", name, pnt->x, pnt->y, pnt->z );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/vec_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_V_C_H\n#define _VECTORMATH_VEC_AOS_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathVector3 vmathV3MakeFromElems_V( float _x, float _y, float _z )\n{\n    VmathVector3 result;\n    vmathV3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt )\n{\n    VmathVector3 result;\n    vmathV3MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFromScalar_V( float scalar )\n{\n    VmathVector3 result;\n    vmathV3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeXAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeYAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeZAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 )\n{\n    VmathVector3 result;\n    vmathV3Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline void vmathV3SetX_V( VmathVector3 *result, float _x )\n{\n    vmathV3SetX(result, _x);\n}\n\nstatic inline float vmathV3GetX_V( VmathVector3 vec )\n{\n    return vmathV3GetX(&vec);\n}\n\nstatic inline void vmathV3SetY_V( VmathVector3 *result, float _y )\n{\n    vmathV3SetY(result, _y);\n}\n\nstatic inline float vmathV3GetY_V( VmathVector3 vec )\n{\n    return vmathV3GetY(&vec);\n}\n\nstatic inline void vmathV3SetZ_V( VmathVector3 *result, float _z )\n{\n    vmathV3SetZ(result, _z);\n}\n\nstatic inline float vmathV3GetZ_V( VmathVector3 vec )\n{\n    return vmathV3GetZ(&vec);\n}\n\nstatic inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value )\n{\n    vmathV3SetElem(result, idx, value);\n}\n\nstatic inline float vmathV3GetElem_V( VmathVector3 vec, int idx )\n{\n    return vmathV3GetElem(&vec, idx);\n}\n\nstatic inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathV3AddP3(&result, &vec, &pnt1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar )\n{\n    VmathVector3 result;\n    vmathV3ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar )\n{\n    VmathVector3 result;\n    vmathV3ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Neg_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV3MaxElem_V( VmathVector3 vec )\n{\n    return vmathV3MaxElem(&vec);\n}\n\nstatic inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV3MinElem_V( VmathVector3 vec )\n{\n    return vmathV3MinElem(&vec);\n}\n\nstatic inline float vmathV3Sum_V( VmathVector3 vec )\n{\n    return vmathV3Sum(&vec);\n}\n\nstatic inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    return vmathV3Dot(&vec0, &vec1);\n}\n\nstatic inline float vmathV3LengthSqr_V( VmathVector3 vec )\n{\n    return vmathV3LengthSqr(&vec);\n}\n\nstatic inline float vmathV3Length_V( VmathVector3 vec )\n{\n    return vmathV3Length(&vec);\n}\n\nstatic inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Cross(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 )\n{\n    VmathVector3 result;\n    vmathV3Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV3Print_V( VmathVector3 vec )\n{\n    vmathV3Print(&vec);\n}\n\nstatic inline void vmathV3Prints_V( VmathVector3 vec, const char *name )\n{\n    vmathV3Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathVector4 vmathV4MakeFromElems_V( float _x, float _y, float _z, float _w )\n{\n    VmathVector4 result;\n    vmathV4MakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float _w )\n{\n    VmathVector4 result;\n    vmathV4MakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec )\n{\n    VmathVector4 result;\n    vmathV4MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt )\n{\n    VmathVector4 result;\n    vmathV4MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat )\n{\n    VmathVector4 result;\n    vmathV4MakeFromQ(&result, &quat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromScalar_V( float scalar )\n{\n    VmathVector4 result;\n    vmathV4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeXAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeYAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeZAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeWAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeWAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 )\n{\n    VmathVector4 result;\n    vmathV4Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec )\n{\n    vmathV4SetXYZ(result, &vec);\n}\n\nstatic inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec )\n{\n    VmathVector3 result;\n    vmathV4GetXYZ(&result, &vec);\n    return result;\n}\n\nstatic inline void vmathV4SetX_V( VmathVector4 *result, float _x )\n{\n    vmathV4SetX(result, _x);\n}\n\nstatic inline float vmathV4GetX_V( VmathVector4 vec )\n{\n    return vmathV4GetX(&vec);\n}\n\nstatic inline void vmathV4SetY_V( VmathVector4 *result, float _y )\n{\n    vmathV4SetY(result, _y);\n}\n\nstatic inline float vmathV4GetY_V( VmathVector4 vec )\n{\n    return vmathV4GetY(&vec);\n}\n\nstatic inline void vmathV4SetZ_V( VmathVector4 *result, float _z )\n{\n    vmathV4SetZ(result, _z);\n}\n\nstatic inline float vmathV4GetZ_V( VmathVector4 vec )\n{\n    return vmathV4GetZ(&vec);\n}\n\nstatic inline void vmathV4SetW_V( VmathVector4 *result, float _w )\n{\n    vmathV4SetW(result, _w);\n}\n\nstatic inline float vmathV4GetW_V( VmathVector4 vec )\n{\n    return vmathV4GetW(&vec);\n}\n\nstatic inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value )\n{\n    vmathV4SetElem(result, idx, value);\n}\n\nstatic inline float vmathV4GetElem_V( VmathVector4 vec, int idx )\n{\n    return vmathV4GetElem(&vec, idx);\n}\n\nstatic inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar )\n{\n    VmathVector4 result;\n    vmathV4ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar )\n{\n    VmathVector4 result;\n    vmathV4ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Neg_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV4MaxElem_V( VmathVector4 vec )\n{\n    return vmathV4MaxElem(&vec);\n}\n\nstatic inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV4MinElem_V( VmathVector4 vec )\n{\n    return vmathV4MinElem(&vec);\n}\n\nstatic inline float vmathV4Sum_V( VmathVector4 vec )\n{\n    return vmathV4Sum(&vec);\n}\n\nstatic inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    return vmathV4Dot(&vec0, &vec1);\n}\n\nstatic inline float vmathV4LengthSqr_V( VmathVector4 vec )\n{\n    return vmathV4LengthSqr(&vec);\n}\n\nstatic inline float vmathV4Length_V( VmathVector4 vec )\n{\n    return vmathV4Length(&vec);\n}\n\nstatic inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 )\n{\n    VmathVector4 result;\n    vmathV4Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV4Print_V( VmathVector4 vec )\n{\n    vmathV4Print(&vec);\n}\n\nstatic inline void vmathV4Prints_V( VmathVector4 vec, const char *name )\n{\n    vmathV4Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathPoint3 vmathP3MakeFromElems_V( float _x, float _y, float _z )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3Lerp(&result, t, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline void vmathP3SetX_V( VmathPoint3 *result, float _x )\n{\n    vmathP3SetX(result, _x);\n}\n\nstatic inline float vmathP3GetX_V( VmathPoint3 pnt )\n{\n    return vmathP3GetX(&pnt);\n}\n\nstatic inline void vmathP3SetY_V( VmathPoint3 *result, float _y )\n{\n    vmathP3SetY(result, _y);\n}\n\nstatic inline float vmathP3GetY_V( VmathPoint3 pnt )\n{\n    return vmathP3GetY(&pnt);\n}\n\nstatic inline void vmathP3SetZ_V( VmathPoint3 *result, float _z )\n{\n    vmathP3SetZ(result, _z);\n}\n\nstatic inline float vmathP3GetZ_V( VmathPoint3 pnt )\n{\n    return vmathP3GetZ(&pnt);\n}\n\nstatic inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value )\n{\n    vmathP3SetElem(result, idx, value);\n}\n\nstatic inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx )\n{\n    return vmathP3GetElem(&pnt, idx);\n}\n\nstatic inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathVector3 result;\n    vmathP3Sub(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec1 )\n{\n    VmathPoint3 result;\n    vmathP3AddV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec1 )\n{\n    VmathPoint3 result;\n    vmathP3SubV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MulPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3DivPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3RecipPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3SqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3RsqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3AbsPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3CopySignPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MaxPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline float vmathP3MaxElem_V( VmathPoint3 pnt )\n{\n    return vmathP3MaxElem(&pnt);\n}\n\nstatic inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MinPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline float vmathP3MinElem_V( VmathPoint3 pnt )\n{\n    return vmathP3MinElem(&pnt);\n}\n\nstatic inline float vmathP3Sum_V( VmathPoint3 pnt )\n{\n    return vmathP3Sum(&pnt);\n}\n\nstatic inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal )\n{\n    VmathPoint3 result;\n    vmathP3Scale(&result, &pnt, scaleVal);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec )\n{\n    VmathPoint3 result;\n    vmathP3NonUniformScale(&result, &pnt, &scaleVec);\n    return result;\n}\n\nstatic inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec )\n{\n    return vmathP3Projection(&pnt, &unitVec);\n}\n\nstatic inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt )\n{\n    return vmathP3DistSqrFromOrigin(&pnt);\n}\n\nstatic inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt )\n{\n    return vmathP3DistFromOrigin(&pnt);\n}\n\nstatic inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    return vmathP3DistSqr(&pnt0, &pnt1);\n}\n\nstatic inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    return vmathP3Dist(&pnt0, &pnt1);\n}\n\nstatic inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 )\n{\n    VmathPoint3 result;\n    vmathP3Select(&result, &pnt0, &pnt1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathP3Print_V( VmathPoint3 pnt )\n{\n    vmathP3Print(&pnt);\n}\n\nstatic inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name )\n{\n    vmathP3Prints(&pnt, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_SCALAR_H\n#define _VECTORMATH_AOS_C_SCALAR_H\n\n#include <math.h>\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_AOS_C_TYPES_H\n#define _VECTORMATH_AOS_C_TYPES_H\n\n/* A 3-D vector in array-of-structures format\n */\ntypedef struct _VmathVector3\n{\n    float x;\n    float y;\n    float z;\n#ifndef __GNUC__\n    float d;\n#endif\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathVector3;\n\n/* A 4-D vector in array-of-structures format\n */\ntypedef struct _VmathVector4\n{\n    float x;\n    float y;\n    float z;\n    float w;\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathVector4;\n\n/* A 3-D point in array-of-structures format\n */\ntypedef struct _VmathPoint3\n{\n    float x;\n    float y;\n    float z;\n#ifndef __GNUC__\n    float d;\n#endif\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathPoint3;\n\n/* A quaternion in array-of-structures format\n */\ntypedef struct _VmathQuat\n{\n    float x;\n    float y;\n    float z;\n    float w;\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathQuat;\n\n/* A 3x3 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n} VmathMatrix3;\n\n/* A 4x4 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix4\n{\n    VmathVector4 col0;\n    VmathVector4 col1;\n    VmathVector4 col2;\n    VmathVector4 col3;\n} VmathMatrix4;\n\n/* A 3x4 transformation matrix in array-of-structures format\n */\ntypedef struct _VmathTransform3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n    VmathVector3 col3;\n} VmathTransform3;\n\n#endif\n\n/*\n * Copy a 3-D vector\n */\nstatic inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline void vmathV3MakeFromElems( VmathVector3 *result, float x, float y, float z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathV3SetX( VmathVector3 *result, float x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathV3SetY( VmathVector3 *result, float y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathV3SetZ( VmathVector3 *result, float z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline float vmathV3GetX( const VmathVector3 *vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline float vmathV3GetY( const VmathVector3 *vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline float vmathV3GetZ( const VmathVector3 *vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathV3SetElem( VmathVector3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline float vmathV3GetElem( const VmathVector3 *vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathV3MakeXAxis( VmathVector3 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathV3MakeYAxis( VmathVector3 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathV3MakeZAxis( VmathVector3 *result );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline float vmathV3MaxElem( const VmathVector3 *vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline float vmathV3MinElem( const VmathVector3 *vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline float vmathV3Sum( const VmathVector3 *vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline float vmathV3LengthSqr( const VmathVector3 *vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline float vmathV3Length( const VmathVector3 *vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n */\nstatic inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n */\nstatic inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Print( const VmathVector3 *vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Prints( const VmathVector3 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 4-D vector\n */\nstatic inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline void vmathV4MakeFromElems( VmathVector4 *result, float x, float y, float z, float w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathV4SetX( VmathVector4 *result, float x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathV4SetY( VmathVector4 *result, float y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathV4SetZ( VmathVector4 *result, float z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathV4SetW( VmathVector4 *result, float w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline float vmathV4GetX( const VmathVector4 *vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline float vmathV4GetY( const VmathVector4 *vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline float vmathV4GetZ( const VmathVector4 *vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline float vmathV4GetW( const VmathVector4 *vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathV4SetElem( VmathVector4 *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline float vmathV4GetElem( const VmathVector4 *vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathV4MakeXAxis( VmathVector4 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathV4MakeYAxis( VmathVector4 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathV4MakeZAxis( VmathVector4 *result );\n\n/*\n * Construct w axis\n */\nstatic inline void vmathV4MakeWAxis( VmathVector4 *result );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline float vmathV4MaxElem( const VmathVector4 *vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline float vmathV4MinElem( const VmathVector4 *vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline float vmathV4Sum( const VmathVector4 *vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline float vmathV4LengthSqr( const VmathVector4 *vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline float vmathV4Length( const VmathVector4 *vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n */\nstatic inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Print( const VmathVector4 *vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Prints( const VmathVector4 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 3-D point\n */\nstatic inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline void vmathP3MakeFromElems( VmathPoint3 *result, float x, float y, float z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathP3SetX( VmathPoint3 *result, float x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathP3SetY( VmathPoint3 *result, float y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathP3SetZ( VmathPoint3 *result, float z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline float vmathP3GetX( const VmathPoint3 *pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline float vmathP3GetY( const VmathPoint3 *pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline float vmathP3GetZ( const VmathPoint3 *pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline float vmathP3MaxElem( const VmathPoint3 *pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline float vmathP3MinElem( const VmathPoint3 *pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline float vmathP3Sum( const VmathPoint3 *pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n */\nstatic inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Print( const VmathPoint3 *pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name );\n\n#endif\n\n/*\n * Copy a quaternion\n */\nstatic inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline void vmathQMakeFromElems( VmathQuat *result, float x, float y, float z, float w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline void vmathQMakeFromScalar( VmathQuat *result, float scalar );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathQSetX( VmathQuat *result, float x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathQSetY( VmathQuat *result, float y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathQSetZ( VmathQuat *result, float z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathQSetW( VmathQuat *result, float w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline float vmathQGetX( const VmathQuat *quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline float vmathQGetY( const VmathQuat *quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline float vmathQGetZ( const VmathQuat *quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline float vmathQGetW( const VmathQuat *quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathQSetElem( VmathQuat *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline float vmathQGetElem( const VmathQuat *quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline void vmathQMakeIdentity( VmathQuat *result );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline void vmathQMakeRotationX( VmathQuat *result, float radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline void vmathQMakeRotationY( VmathQuat *result, float radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline void vmathQMakeRotationZ( VmathQuat *result, float radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline void vmathQConj( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline void vmathQRotate( VmathVector3 *result, const VmathQuat *unitQuat, const VmathVector3 *vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline float vmathQNorm( const VmathQuat *quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline float vmathQLength( const VmathQuat *quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n */\nstatic inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrint( const VmathQuat *quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrints( const VmathQuat *quat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x3 matrix\n */\nstatic inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline void vmathM3MakeIdentity( VmathMatrix3 *result );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline float vmathM3Determinant( const VmathMatrix3 *mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n */\nstatic inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Print( const VmathMatrix3 *mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 4x4 matrix\n */\nstatic inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *col0, const VmathVector4 *col1, const VmathVector4 *col2, const VmathVector4 *col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline void vmathM4MakeIdentity( VmathMatrix4 *result );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline float vmathM4Determinant( const VmathMatrix4 *mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n */\nstatic inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Print( const VmathMatrix4 *mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x4 transformation matrix\n */\nstatic inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2, const VmathVector3 *col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline void vmathT3MakeIdentity( VmathTransform3 *result );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n */\nstatic inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Print( const VmathTransform3 *tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/c/vectormath_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_V_SCALAR_H\n#define _VECTORMATH_AOS_C_V_SCALAR_H\n\n#include <math.h>\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_AOS_C_TYPES_H\n#define _VECTORMATH_AOS_C_TYPES_H\n\n/* A 3-D vector in array-of-structures format\n */\ntypedef struct _VmathVector3\n{\n    float x;\n    float y;\n    float z;\n#ifndef __GNUC__\n    float d;\n#endif\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathVector3;\n\n/* A 4-D vector in array-of-structures format\n */\ntypedef struct _VmathVector4\n{\n    float x;\n    float y;\n    float z;\n    float w;\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathVector4;\n\n/* A 3-D point in array-of-structures format\n */\ntypedef struct _VmathPoint3\n{\n    float x;\n    float y;\n    float z;\n#ifndef __GNUC__\n    float d;\n#endif\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathPoint3;\n\n/* A quaternion in array-of-structures format\n */\ntypedef struct _VmathQuat\n{\n    float x;\n    float y;\n    float z;\n    float w;\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\nVmathQuat;\n\n/* A 3x3 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n} VmathMatrix3;\n\n/* A 4x4 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix4\n{\n    VmathVector4 col0;\n    VmathVector4 col1;\n    VmathVector4 col2;\n    VmathVector4 col3;\n} VmathMatrix4;\n\n/* A 3x4 transformation matrix in array-of-structures format\n */\ntypedef struct _VmathTransform3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n    VmathVector3 col3;\n} VmathTransform3;\n\n#endif\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline VmathVector3 vmathV3MakeFromElems_V( float x, float y, float z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline VmathVector3 vmathV3MakeFromScalar_V( float scalar );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathV3SetX_V( VmathVector3 *result, float x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathV3SetY_V( VmathVector3 *result, float y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathV3SetZ_V( VmathVector3 *result, float z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline float vmathV3GetX_V( VmathVector3 vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline float vmathV3GetY_V( VmathVector3 vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline float vmathV3GetZ_V( VmathVector3 vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline float vmathV3GetElem_V( VmathVector3 vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline VmathVector3 vmathV3Neg_V( VmathVector3 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathVector3 vmathV3MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathVector3 vmathV3MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathVector3 vmathV3MakeZAxis_V( );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline float vmathV3MaxElem_V( VmathVector3 vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline float vmathV3MinElem_V( VmathVector3 vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline float vmathV3Sum_V( VmathVector3 vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline float vmathV3LengthSqr_V( VmathVector3 vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline float vmathV3Length_V( VmathVector3 vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline VmathMatrix3 vmathV3Outer_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n */\nstatic inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Print_V( VmathVector3 vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Prints_V( VmathVector3 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline VmathVector4 vmathV4MakeFromElems_V( float x, float y, float z, float w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline VmathVector4 vmathV4MakeFromScalar_V( float scalar );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathV4SetX_V( VmathVector4 *result, float x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathV4SetY_V( VmathVector4 *result, float y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathV4SetZ_V( VmathVector4 *result, float z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathV4SetW_V( VmathVector4 *result, float w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline float vmathV4GetX_V( VmathVector4 vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline float vmathV4GetY_V( VmathVector4 vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline float vmathV4GetZ_V( VmathVector4 vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline float vmathV4GetW_V( VmathVector4 vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline float vmathV4GetElem_V( VmathVector4 vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline VmathVector4 vmathV4Neg_V( VmathVector4 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathVector4 vmathV4MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathVector4 vmathV4MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathVector4 vmathV4MakeZAxis_V( );\n\n/*\n * Construct w axis\n */\nstatic inline VmathVector4 vmathV4MakeWAxis_V( );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline float vmathV4MaxElem_V( VmathVector4 vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline float vmathV4MinElem_V( VmathVector4 vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline float vmathV4Sum_V( VmathVector4 vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline float vmathV4LengthSqr_V( VmathVector4 vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline float vmathV4Length_V( VmathVector4 vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline VmathMatrix4 vmathV4Outer_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n */\nstatic inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Print_V( VmathVector4 vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Prints_V( VmathVector4 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline VmathPoint3 vmathP3MakeFromElems_V( float x, float y, float z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathP3SetX_V( VmathPoint3 *result, float x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathP3SetY_V( VmathPoint3 *result, float y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathP3SetZ_V( VmathPoint3 *result, float z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline float vmathP3GetX_V( VmathPoint3 pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline float vmathP3GetY_V( VmathPoint3 pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline float vmathP3GetZ_V( VmathPoint3 pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline float vmathP3MaxElem_V( VmathPoint3 pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline float vmathP3MinElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline float vmathP3Sum_V( VmathPoint3 pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n */\nstatic inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Print_V( VmathPoint3 pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name );\n\n#endif\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline VmathQuat vmathQMakeFromElems_V( float x, float y, float z, float w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline VmathQuat vmathQMakeFromScalar_V( float scalar );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathQSetX_V( VmathQuat *result, float x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathQSetY_V( VmathQuat *result, float y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathQSetZ_V( VmathQuat *result, float z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathQSetW_V( VmathQuat *result, float w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline float vmathQGetX_V( VmathQuat quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline float vmathQGetY_V( VmathQuat quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline float vmathQGetZ_V( VmathQuat quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline float vmathQGetW_V( VmathQuat quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathQSetElem_V( VmathQuat *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline float vmathQGetElem_V( VmathQuat quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline VmathQuat vmathQNeg_V( VmathQuat quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline VmathQuat vmathQMakeIdentity_V( );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline VmathQuat vmathQMakeRotationX_V( float radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline VmathQuat vmathQMakeRotationY_V( float radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline VmathQuat vmathQMakeRotationZ_V( float radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline VmathQuat vmathQConj_V( VmathQuat quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline VmathVector3 vmathQRotate_V( VmathQuat unitQuat, VmathVector3 vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline float vmathQNorm_V( VmathQuat quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline float vmathQLength_V( VmathQuat quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline VmathQuat vmathQNormalize_V( VmathQuat quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n */\nstatic inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrint_V( VmathQuat quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrints_V( VmathQuat quat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3MakeIdentity_V( );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationX_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationY_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline float vmathM3Determinant_V( VmathMatrix3 mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Print_V( VmathMatrix3 mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 col0, VmathVector4 col1, VmathVector4 col2, VmathVector4 col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeIdentity_V( );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationX_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationY_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline float vmathM4Determinant_V( VmathMatrix4 mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Print_V( VmathMatrix4 mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2, VmathVector3 col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline VmathTransform3 vmathT3MakeIdentity_V( );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationX_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationY_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationZ_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n */\nstatic inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Print_V( VmathTransform3 tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vectormath_aos.h\"\n#include \"vec_aos_v.h\"\n#include \"quat_aos_v.h\"\n#include \"mat_aos_v.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/cpp/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_CPP_H\n#define _VECTORMATH_MAT_AOS_CPP_H\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Constants\n\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\ninline Matrix3::Matrix3( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n}\n\ninline Matrix3::Matrix3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( const Quat & unitQuat )\n{\n    float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2;\n    qx = unitQuat.getX();\n    qy = unitQuat.getY();\n    qz = unitQuat.getZ();\n    qw = unitQuat.getW();\n    qx2 = ( qx + qx );\n    qy2 = ( qy + qy );\n    qz2 = ( qz + qz );\n    qxqx2 = ( qx * qx2 );\n    qxqy2 = ( qx * qy2 );\n    qxqz2 = ( qx * qz2 );\n    qxqw2 = ( qw * qx2 );\n    qyqy2 = ( qy * qy2 );\n    qyqz2 = ( qy * qz2 );\n    qyqw2 = ( qw * qy2 );\n    qzqz2 = ( qz * qz2 );\n    qzqw2 = ( qw * qz2 );\n    mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) );\n    mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) );\n    mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) );\n}\n\ninline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n}\n\ninline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, float val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline float Matrix3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Matrix3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Matrix3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Matrix3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Matrix3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::getRow( int row ) const\n{\n    return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) );\n}\n\ninline Vector3 & Matrix3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix3 & Matrix3::operator =( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    return *this;\n}\n\ninline const Matrix3 transpose( const Matrix3 & mat )\n{\n    return Matrix3(\n        Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ),\n        Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ),\n        Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() )\n    );\n}\n\ninline const Matrix3 inverse( const Matrix3 & mat )\n{\n    Vector3 tmp0, tmp1, tmp2;\n    float detinv;\n    tmp0 = cross( mat.getCol1(), mat.getCol2() );\n    tmp1 = cross( mat.getCol2(), mat.getCol0() );\n    tmp2 = cross( mat.getCol0(), mat.getCol1() );\n    detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) );\n    return Matrix3(\n        Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ),\n        Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ),\n        Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) )\n    );\n}\n\ninline float determinant( const Matrix3 & mat )\n{\n    return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) );\n}\n\ninline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 )\n    );\n}\n\ninline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator +=( const Matrix3 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::operator -=( const Matrix3 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix3 Matrix3::operator -( ) const\n{\n    return Matrix3(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 )\n    );\n}\n\ninline const Matrix3 absPerElem( const Matrix3 & mat )\n{\n    return Matrix3(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( float scalar ) const\n{\n    return Matrix3(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix3 operator *( float scalar, const Matrix3 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector3 Matrix3::operator *( const Vector3 & vec ) const\n{\n    return Vector3(\n        ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ),\n        ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ),\n        ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( const Matrix3 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 )\n{\n    return Matrix3(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::identity( )\n{\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationX( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3( 0.0f, c, s ),\n        Vector3( 0.0f, -s, c )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationY( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Matrix3(\n        Vector3( c, 0.0f, -s ),\n        Vector3::yAxis( ),\n        Vector3( s, 0.0f, c )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZ( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Matrix3(\n        Vector3( c, s, 0.0f ),\n        Vector3( -s, c, 0.0f ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ )\n{\n    float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sX = sinf( radiansXYZ.getX() );\n    cX = cosf( radiansXYZ.getX() );\n    sY = sinf( radiansXYZ.getY() );\n    cY = cosf( radiansXYZ.getY() );\n    sZ = sinf( radiansXYZ.getZ() );\n    cZ = cosf( radiansXYZ.getZ() );\n    tmp0 = ( cZ * sY );\n    tmp1 = ( sZ * sY );\n    return Matrix3(\n        Vector3( ( cZ * cY ), ( sZ * cY ), -sY ),\n        Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ),\n        Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec )\n{\n    float x, y, z, s, c, oneMinusC, xy, yz, zx;\n    s = sinf( radians );\n    c = cosf( radians );\n    x = unitVec.getX();\n    y = unitVec.getY();\n    z = unitVec.getZ();\n    xy = ( x * y );\n    yz = ( y * z );\n    zx = ( z * x );\n    oneMinusC = ( 1.0f - c );\n    return Matrix3(\n        Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ),\n        Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ),\n        Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( const Quat & unitQuat )\n{\n    return Matrix3( unitQuat );\n}\n\ninline const Matrix3 Matrix3::scale( const Vector3 & scaleVec )\n{\n    return Matrix3(\n        Vector3( scaleVec.getX(), 0.0f, 0.0f ),\n        Vector3( 0.0f, scaleVec.getY(), 0.0f ),\n        Vector3( 0.0f, 0.0f, scaleVec.getZ() )\n    );\n}\n\ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec )\n{\n    return Matrix3(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) )\n    );\n}\n\ninline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat )\n{\n    return Matrix3(\n        mulPerElem( mat.getCol0(), scaleVec ),\n        mulPerElem( mat.getCol1(), scaleVec ),\n        mulPerElem( mat.getCol2(), scaleVec )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix3 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n}\n\ninline void print( const Matrix3 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Matrix4::Matrix4( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n}\n\ninline Matrix4::Matrix4( float scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const Transform3 & mat )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( mat.getCol3(), 1.0f );\n}\n\ninline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec )\n{\n    Matrix3 mat;\n    mat = Matrix3( unitQuat );\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, float val )\n{\n    Vector4 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline float Matrix4::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector4 Matrix4::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector4 Matrix4::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector4 Matrix4::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector4 Matrix4::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector4 Matrix4::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector4 & Matrix4::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix4 & Matrix4::operator =( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n    return *this;\n}\n\ninline const Matrix4 transpose( const Matrix4 & mat )\n{\n    return Matrix4(\n        Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ),\n        Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ),\n        Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ),\n        Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() )\n    );\n}\n\ninline const Matrix4 inverse( const Matrix4 & mat )\n{\n    Vector4 res0, res1, res2, res3;\n    float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv;\n    mA = mat.getCol0().getX();\n    mB = mat.getCol0().getY();\n    mC = mat.getCol0().getZ();\n    mD = mat.getCol0().getW();\n    mE = mat.getCol1().getX();\n    mF = mat.getCol1().getY();\n    mG = mat.getCol1().getZ();\n    mH = mat.getCol1().getW();\n    mI = mat.getCol2().getX();\n    mJ = mat.getCol2().getY();\n    mK = mat.getCol2().getZ();\n    mL = mat.getCol2().getW();\n    mM = mat.getCol3().getX();\n    mN = mat.getCol3().getY();\n    mO = mat.getCol3().getZ();\n    mP = mat.getCol3().getW();\n    tmp0 = ( ( mK * mD ) - ( mC * mL ) );\n    tmp1 = ( ( mO * mH ) - ( mG * mP ) );\n    tmp2 = ( ( mB * mK ) - ( mJ * mC ) );\n    tmp3 = ( ( mF * mO ) - ( mN * mG ) );\n    tmp4 = ( ( mJ * mD ) - ( mB * mL ) );\n    tmp5 = ( ( mN * mH ) - ( mF * mP ) );\n    res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) );\n    res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) );\n    res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) );\n    res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) );\n    detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) );\n    res1.setX( ( mI * tmp1 ) );\n    res1.setY( ( mM * tmp0 ) );\n    res1.setZ( ( mA * tmp1 ) );\n    res1.setW( ( mE * tmp0 ) );\n    res3.setX( ( mI * tmp3 ) );\n    res3.setY( ( mM * tmp2 ) );\n    res3.setZ( ( mA * tmp3 ) );\n    res3.setW( ( mE * tmp2 ) );\n    res2.setX( ( mI * tmp5 ) );\n    res2.setY( ( mM * tmp4 ) );\n    res2.setZ( ( mA * tmp5 ) );\n    res2.setW( ( mE * tmp4 ) );\n    tmp0 = ( ( mI * mB ) - ( mA * mJ ) );\n    tmp1 = ( ( mM * mF ) - ( mE * mN ) );\n    tmp2 = ( ( mI * mD ) - ( mA * mL ) );\n    tmp3 = ( ( mM * mH ) - ( mE * mP ) );\n    tmp4 = ( ( mI * mC ) - ( mA * mK ) );\n    tmp5 = ( ( mM * mG ) - ( mE * mO ) );\n    res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) );\n    res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) );\n    res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) );\n    res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) );\n    res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) );\n    res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) );\n    res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) );\n    res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) );\n    res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) );\n    res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) );\n    res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) );\n    res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) );\n    return Matrix4(\n        ( res0 * detInv ),\n        ( res1 * detInv ),\n        ( res2 * detInv ),\n        ( res3 * detInv )\n    );\n}\n\ninline const Matrix4 affineInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( inverse( affineMat ) );\n}\n\ninline const Matrix4 orthoInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( orthoInverse( affineMat ) );\n}\n\ninline float determinant( const Matrix4 & mat )\n{\n    float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    mA = mat.getCol0().getX();\n    mB = mat.getCol0().getY();\n    mC = mat.getCol0().getZ();\n    mD = mat.getCol0().getW();\n    mE = mat.getCol1().getX();\n    mF = mat.getCol1().getY();\n    mG = mat.getCol1().getZ();\n    mH = mat.getCol1().getW();\n    mI = mat.getCol2().getX();\n    mJ = mat.getCol2().getY();\n    mK = mat.getCol2().getZ();\n    mL = mat.getCol2().getW();\n    mM = mat.getCol3().getX();\n    mN = mat.getCol3().getY();\n    mO = mat.getCol3().getZ();\n    mP = mat.getCol3().getW();\n    tmp0 = ( ( mK * mD ) - ( mC * mL ) );\n    tmp1 = ( ( mO * mH ) - ( mG * mP ) );\n    tmp2 = ( ( mB * mK ) - ( mJ * mC ) );\n    tmp3 = ( ( mF * mO ) - ( mN * mG ) );\n    tmp4 = ( ( mJ * mD ) - ( mB * mL ) );\n    tmp5 = ( ( mN * mH ) - ( mF * mP ) );\n    dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) );\n    dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) );\n    dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) );\n    dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) );\n    return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) );\n}\n\ninline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 ),\n        ( mCol3 + mat.mCol3 )\n    );\n}\n\ninline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 ),\n        ( mCol3 - mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator +=( const Matrix4 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::operator -=( const Matrix4 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator -( ) const\n{\n    return Matrix4(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 ),\n        ( -mCol3 )\n    );\n}\n\ninline const Matrix4 absPerElem( const Matrix4 & mat )\n{\n    return Matrix4(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() ),\n        absPerElem( mat.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( float scalar ) const\n{\n    return Matrix4(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar ),\n        ( mCol3 * scalar )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix4 operator *( float scalar, const Matrix4 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector4 Matrix4::operator *( const Vector4 & vec ) const\n{\n    return Vector4(\n        ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ),\n        ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ),\n        ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ),\n        ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) )\n    );\n}\n\ninline const Vector4 Matrix4::operator *( const Vector3 & vec ) const\n{\n    return Vector4(\n        ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ),\n        ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ),\n        ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ),\n        ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) )\n    );\n}\n\ninline const Vector4 Matrix4::operator *( const Point3 & pnt ) const\n{\n    return Vector4(\n        ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ),\n        ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ),\n        ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ),\n        ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 ),\n        ( *this * mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Matrix4 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const\n{\n    return Matrix4(\n        ( *this * tfrm.getCol0() ),\n        ( *this * tfrm.getCol1() ),\n        ( *this * tfrm.getCol2() ),\n        ( *this * Point3( tfrm.getCol3() ) )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 )\n{\n    return Matrix4(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() ),\n        mulPerElem( mat0.getCol3(), mat1.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::identity( )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 )\n{\n    mCol0.setXYZ( mat3.getCol0() );\n    mCol1.setXYZ( mat3.getCol1() );\n    mCol2.setXYZ( mat3.getCol2() );\n    return *this;\n}\n\ninline const Matrix3 Matrix4::getUpper3x3( ) const\n{\n    return Matrix3(\n        mCol0.getXYZ( ),\n        mCol1.getXYZ( ),\n        mCol2.getXYZ( )\n    );\n}\n\ninline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec )\n{\n    mCol3.setXYZ( translateVec );\n    return *this;\n}\n\ninline const Vector3 Matrix4::getTranslation( ) const\n{\n    return mCol3.getXYZ( );\n}\n\ninline const Matrix4 Matrix4::rotationX( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4( 0.0f, c, s, 0.0f ),\n        Vector4( 0.0f, -s, c, 0.0f ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationY( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Matrix4(\n        Vector4( c, 0.0f, -s, 0.0f ),\n        Vector4::yAxis( ),\n        Vector4( s, 0.0f, c, 0.0f ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZ( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Matrix4(\n        Vector4( c, s, 0.0f, 0.0f ),\n        Vector4( -s, c, 0.0f, 0.0f ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ )\n{\n    float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sX = sinf( radiansXYZ.getX() );\n    cX = cosf( radiansXYZ.getX() );\n    sY = sinf( radiansXYZ.getY() );\n    cY = cosf( radiansXYZ.getY() );\n    sZ = sinf( radiansXYZ.getZ() );\n    cZ = cosf( radiansXYZ.getZ() );\n    tmp0 = ( cZ * sY );\n    tmp1 = ( sZ * sY );\n    return Matrix4(\n        Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ),\n        Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ),\n        Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec )\n{\n    float x, y, z, s, c, oneMinusC, xy, yz, zx;\n    s = sinf( radians );\n    c = cosf( radians );\n    x = unitVec.getX();\n    y = unitVec.getY();\n    z = unitVec.getZ();\n    xy = ( x * y );\n    yz = ( y * z );\n    zx = ( z * x );\n    oneMinusC = ( 1.0f - c );\n    return Matrix4(\n        Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ),\n        Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ),\n        Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( const Quat & unitQuat )\n{\n    return Matrix4( Transform3::rotation( unitQuat ) );\n}\n\ninline const Matrix4 Matrix4::scale( const Vector3 & scaleVec )\n{\n    return Matrix4(\n        Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ),\n        Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ),\n        Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec )\n{\n    return Matrix4(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) ),\n        mat.getCol3()\n    );\n}\n\ninline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat )\n{\n    Vector4 scale4;\n    scale4 = Vector4( scaleVec, 1.0f );\n    return Matrix4(\n        mulPerElem( mat.getCol0(), scale4 ),\n        mulPerElem( mat.getCol1(), scale4 ),\n        mulPerElem( mat.getCol2(), scale4 ),\n        mulPerElem( mat.getCol3(), scale4 )\n    );\n}\n\ninline const Matrix4 Matrix4::translation( const Vector3 & translateVec )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4( translateVec, 1.0f )\n    );\n}\n\ninline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec )\n{\n    Matrix4 m4EyeFrame;\n    Vector3 v3X, v3Y, v3Z;\n    v3Y = normalize( upVec );\n    v3Z = normalize( ( eyePos - lookAtPos ) );\n    v3X = normalize( cross( v3Y, v3Z ) );\n    v3Y = cross( v3Z, v3X );\n    m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) );\n    return orthoInverse( m4EyeFrame );\n}\n\ninline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) );\n    rangeInv = ( 1.0f / ( zNear - zFar ) );\n    return Matrix4(\n        Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ),\n        Vector4( 0.0f, f, 0.0f, 0.0f ),\n        Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ),\n        Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f )\n    );\n}\n\ninline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2;\n    sum_rl = ( right + left );\n    sum_tb = ( top + bottom );\n    sum_nf = ( zNear + zFar );\n    inv_rl = ( 1.0f / ( right - left ) );\n    inv_tb = ( 1.0f / ( top - bottom ) );\n    inv_nf = ( 1.0f / ( zNear - zFar ) );\n    n2 = ( zNear + zNear );\n    return Matrix4(\n        Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ),\n        Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ),\n        Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ),\n        Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f )\n    );\n}\n\ninline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf;\n    sum_rl = ( right + left );\n    sum_tb = ( top + bottom );\n    sum_nf = ( zNear + zFar );\n    inv_rl = ( 1.0f / ( right - left ) );\n    inv_tb = ( 1.0f / ( top - bottom ) );\n    inv_nf = ( 1.0f / ( zNear - zFar ) );\n    return Matrix4(\n        Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ),\n        Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ),\n        Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ),\n        Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix4 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n    print( mat.getRow( 3 ) );\n}\n\ninline void print( const Matrix4 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Transform3::Transform3( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n}\n\ninline Transform3::Transform3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec )\n{\n    this->setUpper3x3( tfrm );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec )\n{\n    this->setUpper3x3( Matrix3( unitQuat ) );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3 & Transform3::setCol0( const Vector3 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol1( const Vector3 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol2( const Vector3 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol3( const Vector3 & _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol( int col, const Vector3 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Transform3 & Transform3::setRow( int row, const Vector4 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, float val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline float Transform3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Transform3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Transform3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Transform3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Transform3::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector3 Transform3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Transform3::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector3 & Transform3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Transform3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Transform3 & Transform3::operator =( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n    return *this;\n}\n\ninline const Transform3 inverse( const Transform3 & tfrm )\n{\n    Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2;\n    float detinv;\n    tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() );\n    tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() );\n    tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() );\n    detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) );\n    inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) );\n    inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) );\n    inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) );\n    return Transform3(\n        inv0,\n        inv1,\n        inv2,\n        Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) )\n    );\n}\n\ninline const Transform3 orthoInverse( const Transform3 & tfrm )\n{\n    Vector3 inv0, inv1, inv2;\n    inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() );\n    inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() );\n    inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() );\n    return Transform3(\n        inv0,\n        inv1,\n        inv2,\n        Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) )\n    );\n}\n\ninline const Transform3 absPerElem( const Transform3 & tfrm )\n{\n    return Transform3(\n        absPerElem( tfrm.getCol0() ),\n        absPerElem( tfrm.getCol1() ),\n        absPerElem( tfrm.getCol2() ),\n        absPerElem( tfrm.getCol3() )\n    );\n}\n\ninline const Vector3 Transform3::operator *( const Vector3 & vec ) const\n{\n    return Vector3(\n        ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ),\n        ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ),\n        ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) )\n    );\n}\n\ninline const Point3 Transform3::operator *( const Point3 & pnt ) const\n{\n    return Point3(\n        ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ),\n        ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ),\n        ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() )\n    );\n}\n\ninline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const\n{\n    return Transform3(\n        ( *this * tfrm.mCol0 ),\n        ( *this * tfrm.mCol1 ),\n        ( *this * tfrm.mCol2 ),\n        Vector3( ( *this * Point3( tfrm.mCol3 ) ) )\n    );\n}\n\ninline Transform3 & Transform3::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 )\n{\n    return Transform3(\n        mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ),\n        mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ),\n        mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ),\n        mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() )\n    );\n}\n\ninline const Transform3 Transform3::identity( )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm )\n{\n    mCol0 = tfrm.getCol0();\n    mCol1 = tfrm.getCol1();\n    mCol2 = tfrm.getCol2();\n    return *this;\n}\n\ninline const Matrix3 Transform3::getUpper3x3( ) const\n{\n    return Matrix3( mCol0, mCol1, mCol2 );\n}\n\ninline Transform3 & Transform3::setTranslation( const Vector3 & translateVec )\n{\n    mCol3 = translateVec;\n    return *this;\n}\n\ninline const Vector3 Transform3::getTranslation( ) const\n{\n    return mCol3;\n}\n\ninline const Transform3 Transform3::rotationX( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3( 0.0f, c, s ),\n        Vector3( 0.0f, -s, c ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationY( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Transform3(\n        Vector3( c, 0.0f, -s ),\n        Vector3::yAxis( ),\n        Vector3( s, 0.0f, c ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZ( float radians )\n{\n    float s, c;\n    s = sinf( radians );\n    c = cosf( radians );\n    return Transform3(\n        Vector3( c, s, 0.0f ),\n        Vector3( -s, c, 0.0f ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ )\n{\n    float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sX = sinf( radiansXYZ.getX() );\n    cX = cosf( radiansXYZ.getX() );\n    sY = sinf( radiansXYZ.getY() );\n    cY = cosf( radiansXYZ.getY() );\n    sZ = sinf( radiansXYZ.getZ() );\n    cZ = cosf( radiansXYZ.getZ() );\n    tmp0 = ( cZ * sY );\n    tmp1 = ( sZ * sY );\n    return Transform3(\n        Vector3( ( cZ * cY ), ( sZ * cY ), -sY ),\n        Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ),\n        Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec )\n{\n    return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::rotation( const Quat & unitQuat )\n{\n    return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::scale( const Vector3 & scaleVec )\n{\n    return Transform3(\n        Vector3( scaleVec.getX(), 0.0f, 0.0f ),\n        Vector3( 0.0f, scaleVec.getY(), 0.0f ),\n        Vector3( 0.0f, 0.0f, scaleVec.getZ() ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec )\n{\n    return Transform3(\n        ( tfrm.getCol0() * scaleVec.getX( ) ),\n        ( tfrm.getCol1() * scaleVec.getY( ) ),\n        ( tfrm.getCol2() * scaleVec.getZ( ) ),\n        tfrm.getCol3()\n    );\n}\n\ninline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm )\n{\n    return Transform3(\n        mulPerElem( tfrm.getCol0(), scaleVec ),\n        mulPerElem( tfrm.getCol1(), scaleVec ),\n        mulPerElem( tfrm.getCol2(), scaleVec ),\n        mulPerElem( tfrm.getCol3(), scaleVec )\n    );\n}\n\ninline const Transform3 Transform3::translation( const Vector3 & translateVec )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        translateVec\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Transform3 & tfrm )\n{\n    print( tfrm.getRow( 0 ) );\n    print( tfrm.getRow( 1 ) );\n    print( tfrm.getRow( 2 ) );\n}\n\ninline void print( const Transform3 & tfrm, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( tfrm );\n}\n\n#endif\n\ninline Quat::Quat( const Matrix3 & tfrm )\n{\n    float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw;\n    int negTrace, ZgtX, ZgtY, YgtX;\n    int largestXorY, largestYorZ, largestZorX;\n\n    xx = tfrm.getCol0().getX();\n    yx = tfrm.getCol0().getY();\n    zx = tfrm.getCol0().getZ();\n    xy = tfrm.getCol1().getX();\n    yy = tfrm.getCol1().getY();\n    zy = tfrm.getCol1().getZ();\n    xz = tfrm.getCol2().getX();\n    yz = tfrm.getCol2().getY();\n    zz = tfrm.getCol2().getZ();\n\n    trace = ( ( xx + yy ) + zz );\n\n    negTrace = ( trace < 0.0f );\n    ZgtX = zz > xx;\n    ZgtY = zz > yy;\n    YgtX = yy > xx;\n    largestXorY = ( !ZgtX || !ZgtY ) && negTrace;\n    largestYorZ = ( YgtX || ZgtX ) && negTrace;\n    largestZorX = ( ZgtY || !YgtX ) && negTrace;\n    \n    if ( largestXorY )\n    {\n        zz = -zz;\n        xy = -xy;\n    }\n    if ( largestYorZ )\n    {\n        xx = -xx;\n        yz = -yz;\n    }\n    if ( largestZorX )\n    {\n        yy = -yy;\n        zx = -zx;\n    }\n\n    radicand = ( ( ( xx + yy ) + zz ) + 1.0f );\n    scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) );\n\n    tmpx = ( ( zy - yz ) * scale );\n    tmpy = ( ( xz - zx ) * scale );\n    tmpz = ( ( yx - xy ) * scale );\n    tmpw = ( radicand * scale );\n    qx = tmpx;\n    qy = tmpy;\n    qz = tmpz;\n    qw = tmpw;\n\n    if ( largestXorY )\n    {\n        qx = tmpw;\n        qy = tmpz;\n        qz = tmpy;\n        qw = tmpx;\n    }\n    if ( largestYorZ )\n    {\n        tmpx = qx;\n        tmpz = qz;\n        qx = qy;\n        qy = tmpx;\n        qz = qw;\n        qw = tmpz;\n    }\n\n    mX = qx;\n    mY = qy;\n    mZ = qz;\n    mW = qw;\n}\n\ninline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 )\n{\n    return Matrix3(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) )\n    );\n}\n\ninline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 )\n{\n    return Matrix4(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) ),\n        ( tfrm0 * tfrm1.getW( ) )\n    );\n}\n\ninline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat )\n{\n    return Vector3(\n        ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ),\n        ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ),\n        ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) )\n    );\n}\n\ninline const Matrix3 crossMatrix( const Vector3 & vec )\n{\n    return Matrix3(\n        Vector3( 0.0f, vec.getZ(), -vec.getY() ),\n        Vector3( -vec.getZ(), 0.0f, vec.getX() ),\n        Vector3( vec.getY(), -vec.getX(), 0.0f )\n    );\n}\n\ninline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat )\n{\n    return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) );\n}\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/cpp/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_CPP_H\n#define _VECTORMATH_QUAT_AOS_CPP_H\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\ninline Quat::Quat( const Quat & quat )\n{\n    mX = quat.mX;\n    mY = quat.mY;\n    mZ = quat.mZ;\n    mW = quat.mW;\n}\n\ninline Quat::Quat( float _x, float _y, float _z, float _w )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n    mW = _w;\n}\n\ninline Quat::Quat( const Vector3 & xyz, float _w )\n{\n    this->setXYZ( xyz );\n    this->setW( _w );\n}\n\ninline Quat::Quat( const Vector4 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    mW = vec.getW();\n}\n\ninline Quat::Quat( float scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n    mW = scalar;\n}\n\ninline const Quat Quat::identity( )\n{\n    return Quat( 0.0f, 0.0f, 0.0f, 1.0f );\n}\n\ninline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 )\n{\n    return ( quat0 + ( ( quat1 - quat0 ) * t ) );\n}\n\ninline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 )\n{\n    Quat start;\n    float recipSinAngle, scale0, scale1, cosAngle, angle;\n    cosAngle = dot( unitQuat0, unitQuat1 );\n    if ( cosAngle < 0.0f ) {\n        cosAngle = -cosAngle;\n        start = ( -unitQuat0 );\n    } else {\n        start = unitQuat0;\n    }\n    if ( cosAngle < _VECTORMATH_SLERP_TOL ) {\n        angle = acosf( cosAngle );\n        recipSinAngle = ( 1.0f / sinf( angle ) );\n        scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );\n        scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );\n    } else {\n        scale0 = ( 1.0f - t );\n        scale1 = t;\n    }\n    return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) );\n}\n\ninline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 )\n{\n    Quat tmp0, tmp1;\n    tmp0 = slerp( t, unitQuat0, unitQuat3 );\n    tmp1 = slerp( t, unitQuat1, unitQuat2 );\n    return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 );\n}\n\ninline Quat & Quat::operator =( const Quat & quat )\n{\n    mX = quat.mX;\n    mY = quat.mY;\n    mZ = quat.mZ;\n    mW = quat.mW;\n    return *this;\n}\n\ninline Quat & Quat::setXYZ( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    return *this;\n}\n\ninline const Vector3 Quat::getXYZ( ) const\n{\n    return Vector3( mX, mY, mZ );\n}\n\ninline Quat & Quat::setX( float _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline float Quat::getX( ) const\n{\n    return mX;\n}\n\ninline Quat & Quat::setY( float _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline float Quat::getY( ) const\n{\n    return mY;\n}\n\ninline Quat & Quat::setZ( float _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline float Quat::getZ( ) const\n{\n    return mZ;\n}\n\ninline Quat & Quat::setW( float _w )\n{\n    mW = _w;\n    return *this;\n}\n\ninline float Quat::getW( ) const\n{\n    return mW;\n}\n\ninline Quat & Quat::setElem( int idx, float value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline float Quat::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline float & Quat::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline float Quat::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Quat Quat::operator +( const Quat & quat ) const\n{\n    return Quat(\n        ( mX + quat.mX ),\n        ( mY + quat.mY ),\n        ( mZ + quat.mZ ),\n        ( mW + quat.mW )\n    );\n}\n\ninline const Quat Quat::operator -( const Quat & quat ) const\n{\n    return Quat(\n        ( mX - quat.mX ),\n        ( mY - quat.mY ),\n        ( mZ - quat.mZ ),\n        ( mW - quat.mW )\n    );\n}\n\ninline const Quat Quat::operator *( float scalar ) const\n{\n    return Quat(\n        ( mX * scalar ),\n        ( mY * scalar ),\n        ( mZ * scalar ),\n        ( mW * scalar )\n    );\n}\n\ninline Quat & Quat::operator +=( const Quat & quat )\n{\n    *this = *this + quat;\n    return *this;\n}\n\ninline Quat & Quat::operator -=( const Quat & quat )\n{\n    *this = *this - quat;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator /( float scalar ) const\n{\n    return Quat(\n        ( mX / scalar ),\n        ( mY / scalar ),\n        ( mZ / scalar ),\n        ( mW / scalar )\n    );\n}\n\ninline Quat & Quat::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator -( ) const\n{\n    return Quat(\n        -mX,\n        -mY,\n        -mZ,\n        -mW\n    );\n}\n\ninline const Quat operator *( float scalar, const Quat & quat )\n{\n    return quat * scalar;\n}\n\ninline float dot( const Quat & quat0, const Quat & quat1 )\n{\n    float result;\n    result = ( quat0.getX() * quat1.getX() );\n    result = ( result + ( quat0.getY() * quat1.getY() ) );\n    result = ( result + ( quat0.getZ() * quat1.getZ() ) );\n    result = ( result + ( quat0.getW() * quat1.getW() ) );\n    return result;\n}\n\ninline float norm( const Quat & quat )\n{\n    float result;\n    result = ( quat.getX() * quat.getX() );\n    result = ( result + ( quat.getY() * quat.getY() ) );\n    result = ( result + ( quat.getZ() * quat.getZ() ) );\n    result = ( result + ( quat.getW() * quat.getW() ) );\n    return result;\n}\n\ninline float length( const Quat & quat )\n{\n    return sqrtf( norm( quat ) );\n}\n\ninline const Quat normalize( const Quat & quat )\n{\n    float lenSqr, lenInv;\n    lenSqr = norm( quat );\n    lenInv = ( 1.0f / sqrtf( lenSqr ) );\n    return Quat(\n        ( quat.getX() * lenInv ),\n        ( quat.getY() * lenInv ),\n        ( quat.getZ() * lenInv ),\n        ( quat.getW() * lenInv )\n    );\n}\n\ninline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 )\n{\n    float cosHalfAngleX2, recipCosHalfAngleX2;\n    cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) );\n    recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 );\n    return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) );\n}\n\ninline const Quat Quat::rotation( float radians, const Vector3 & unitVec )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    return Quat( ( unitVec * s ), c );\n}\n\ninline const Quat Quat::rotationX( float radians )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    return Quat( s, 0.0f, 0.0f, c );\n}\n\ninline const Quat Quat::rotationY( float radians )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    return Quat( 0.0f, s, 0.0f, c );\n}\n\ninline const Quat Quat::rotationZ( float radians )\n{\n    float s, c, angle;\n    angle = ( radians * 0.5f );\n    s = sinf( angle );\n    c = cosf( angle );\n    return Quat( 0.0f, 0.0f, s, c );\n}\n\ninline const Quat Quat::operator *( const Quat & quat ) const\n{\n    return Quat(\n        ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ),\n        ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ),\n        ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ),\n        ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) )\n    );\n}\n\ninline Quat & Quat::operator *=( const Quat & quat )\n{\n    *this = *this * quat;\n    return *this;\n}\n\ninline const Vector3 rotate( const Quat & quat, const Vector3 & vec )\n{\n    float tmpX, tmpY, tmpZ, tmpW;\n    tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) );\n    tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) );\n    tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) );\n    tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) );\n    return Vector3(\n        ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ),\n        ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ),\n        ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) )\n    );\n}\n\ninline const Quat conj( const Quat & quat )\n{\n    return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() );\n}\n\ninline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 )\n{\n    return Quat(\n        ( select1 )? quat1.getX() : quat0.getX(),\n        ( select1 )? quat1.getY() : quat0.getY(),\n        ( select1 )? quat1.getZ() : quat0.getZ(),\n        ( select1 )? quat1.getW() : quat0.getW()\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Quat & quat )\n{\n    printf( \"( %f %f %f %f )\\n\", quat.getX(), quat.getY(), quat.getZ(), quat.getW() );\n}\n\ninline void print( const Quat & quat, const char * name )\n{\n    printf( \"%s: ( %f %f %f %f )\\n\", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/cpp/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_CPP_H\n#define _VECTORMATH_VEC_AOS_CPP_H\n//-----------------------------------------------------------------------------\n// Constants\n\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\ninline Vector3::Vector3( const Vector3 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n}\n\ninline Vector3::Vector3( float _x, float _y, float _z )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n}\n\ninline Vector3::Vector3( const Point3 & pnt )\n{\n    mX = pnt.getX();\n    mY = pnt.getY();\n    mZ = pnt.getZ();\n}\n\ninline Vector3::Vector3( float scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n}\n\ninline const Vector3 Vector3::xAxis( )\n{\n    return Vector3( 1.0f, 0.0f, 0.0f );\n}\n\ninline const Vector3 Vector3::yAxis( )\n{\n    return Vector3( 0.0f, 1.0f, 0.0f );\n}\n\ninline const Vector3 Vector3::zAxis( )\n{\n    return Vector3( 0.0f, 0.0f, 1.0f );\n}\n\ninline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 )\n{\n    float recipSinAngle, scale0, scale1, cosAngle, angle;\n    cosAngle = dot( unitVec0, unitVec1 );\n    if ( cosAngle < _VECTORMATH_SLERP_TOL ) {\n        angle = acosf( cosAngle );\n        recipSinAngle = ( 1.0f / sinf( angle ) );\n        scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );\n        scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );\n    } else {\n        scale0 = ( 1.0f - t );\n        scale1 = t;\n    }\n    return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) );\n}\n\ninline Vector3 & Vector3::operator =( const Vector3 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( float _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline float Vector3::getX( ) const\n{\n    return mX;\n}\n\ninline Vector3 & Vector3::setY( float _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline float Vector3::getY( ) const\n{\n    return mY;\n}\n\ninline Vector3 & Vector3::setZ( float _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline float Vector3::getZ( ) const\n{\n    return mZ;\n}\n\ninline Vector3 & Vector3::setElem( int idx, float value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline float Vector3::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline float & Vector3::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline float Vector3::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector3 Vector3::operator +( const Vector3 & vec ) const\n{\n    return Vector3(\n        ( mX + vec.mX ),\n        ( mY + vec.mY ),\n        ( mZ + vec.mZ )\n    );\n}\n\ninline const Vector3 Vector3::operator -( const Vector3 & vec ) const\n{\n    return Vector3(\n        ( mX - vec.mX ),\n        ( mY - vec.mY ),\n        ( mZ - vec.mZ )\n    );\n}\n\ninline const Point3 Vector3::operator +( const Point3 & pnt ) const\n{\n    return Point3(\n        ( mX + pnt.getX() ),\n        ( mY + pnt.getY() ),\n        ( mZ + pnt.getZ() )\n    );\n}\n\ninline const Vector3 Vector3::operator *( float scalar ) const\n{\n    return Vector3(\n        ( mX * scalar ),\n        ( mY * scalar ),\n        ( mZ * scalar )\n    );\n}\n\ninline Vector3 & Vector3::operator +=( const Vector3 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator -=( const Vector3 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator /( float scalar ) const\n{\n    return Vector3(\n        ( mX / scalar ),\n        ( mY / scalar ),\n        ( mZ / scalar )\n    );\n}\n\ninline Vector3 & Vector3::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator -( ) const\n{\n    return Vector3(\n        -mX,\n        -mY,\n        -mZ\n    );\n}\n\ninline const Vector3 operator *( float scalar, const Vector3 & vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        ( vec0.getX() * vec1.getX() ),\n        ( vec0.getY() * vec1.getY() ),\n        ( vec0.getZ() * vec1.getZ() )\n    );\n}\n\ninline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        ( vec0.getX() / vec1.getX() ),\n        ( vec0.getY() / vec1.getY() ),\n        ( vec0.getZ() / vec1.getZ() )\n    );\n}\n\ninline const Vector3 recipPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        ( 1.0f / vec.getX() ),\n        ( 1.0f / vec.getY() ),\n        ( 1.0f / vec.getZ() )\n    );\n}\n\ninline const Vector3 sqrtPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        sqrtf( vec.getX() ),\n        sqrtf( vec.getY() ),\n        sqrtf( vec.getZ() )\n    );\n}\n\ninline const Vector3 rsqrtPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        ( 1.0f / sqrtf( vec.getX() ) ),\n        ( 1.0f / sqrtf( vec.getY() ) ),\n        ( 1.0f / sqrtf( vec.getZ() ) )\n    );\n}\n\ninline const Vector3 absPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        fabsf( vec.getX() ),\n        fabsf( vec.getY() ),\n        fabsf( vec.getZ() )\n    );\n}\n\ninline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ),\n        ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ),\n        ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() )\n    );\n}\n\ninline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(),\n        (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(),\n        (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ()\n    );\n}\n\ninline float maxElem( const Vector3 & vec )\n{\n    float result;\n    result = (vec.getX() > vec.getY())? vec.getX() : vec.getY();\n    result = (vec.getZ() > result)? vec.getZ() : result;\n    return result;\n}\n\ninline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(),\n        (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(),\n        (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ()\n    );\n}\n\ninline float minElem( const Vector3 & vec )\n{\n    float result;\n    result = (vec.getX() < vec.getY())? vec.getX() : vec.getY();\n    result = (vec.getZ() < result)? vec.getZ() : result;\n    return result;\n}\n\ninline float sum( const Vector3 & vec )\n{\n    float result;\n    result = ( vec.getX() + vec.getY() );\n    result = ( result + vec.getZ() );\n    return result;\n}\n\ninline float dot( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    float result;\n    result = ( vec0.getX() * vec1.getX() );\n    result = ( result + ( vec0.getY() * vec1.getY() ) );\n    result = ( result + ( vec0.getZ() * vec1.getZ() ) );\n    return result;\n}\n\ninline float lengthSqr( const Vector3 & vec )\n{\n    float result;\n    result = ( vec.getX() * vec.getX() );\n    result = ( result + ( vec.getY() * vec.getY() ) );\n    result = ( result + ( vec.getZ() * vec.getZ() ) );\n    return result;\n}\n\ninline float length( const Vector3 & vec )\n{\n    return sqrtf( lengthSqr( vec ) );\n}\n\ninline const Vector3 normalize( const Vector3 & vec )\n{\n    float lenSqr, lenInv;\n    lenSqr = lengthSqr( vec );\n    lenInv = ( 1.0f / sqrtf( lenSqr ) );\n    return Vector3(\n        ( vec.getX() * lenInv ),\n        ( vec.getY() * lenInv ),\n        ( vec.getZ() * lenInv )\n    );\n}\n\ninline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ),\n        ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ),\n        ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) )\n    );\n}\n\ninline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 )\n{\n    return Vector3(\n        ( select1 )? vec1.getX() : vec0.getX(),\n        ( select1 )? vec1.getY() : vec0.getY(),\n        ( select1 )? vec1.getZ() : vec0.getZ()\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector3 & vec )\n{\n    printf( \"( %f %f %f )\\n\", vec.getX(), vec.getY(), vec.getZ() );\n}\n\ninline void print( const Vector3 & vec, const char * name )\n{\n    printf( \"%s: ( %f %f %f )\\n\", name, vec.getX(), vec.getY(), vec.getZ() );\n}\n\n#endif\n\ninline Vector4::Vector4( const Vector4 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    mW = vec.mW;\n}\n\ninline Vector4::Vector4( float _x, float _y, float _z, float _w )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n    mW = _w;\n}\n\ninline Vector4::Vector4( const Vector3 & xyz, float _w )\n{\n    this->setXYZ( xyz );\n    this->setW( _w );\n}\n\ninline Vector4::Vector4( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    mW = 0.0f;\n}\n\ninline Vector4::Vector4( const Point3 & pnt )\n{\n    mX = pnt.getX();\n    mY = pnt.getY();\n    mZ = pnt.getZ();\n    mW = 1.0f;\n}\n\ninline Vector4::Vector4( const Quat & quat )\n{\n    mX = quat.getX();\n    mY = quat.getY();\n    mZ = quat.getZ();\n    mW = quat.getW();\n}\n\ninline Vector4::Vector4( float scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n    mW = scalar;\n}\n\ninline const Vector4 Vector4::xAxis( )\n{\n    return Vector4( 1.0f, 0.0f, 0.0f, 0.0f );\n}\n\ninline const Vector4 Vector4::yAxis( )\n{\n    return Vector4( 0.0f, 1.0f, 0.0f, 0.0f );\n}\n\ninline const Vector4 Vector4::zAxis( )\n{\n    return Vector4( 0.0f, 0.0f, 1.0f, 0.0f );\n}\n\ninline const Vector4 Vector4::wAxis( )\n{\n    return Vector4( 0.0f, 0.0f, 0.0f, 1.0f );\n}\n\ninline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 )\n{\n    float recipSinAngle, scale0, scale1, cosAngle, angle;\n    cosAngle = dot( unitVec0, unitVec1 );\n    if ( cosAngle < _VECTORMATH_SLERP_TOL ) {\n        angle = acosf( cosAngle );\n        recipSinAngle = ( 1.0f / sinf( angle ) );\n        scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );\n        scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );\n    } else {\n        scale0 = ( 1.0f - t );\n        scale1 = t;\n    }\n    return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) );\n}\n\ninline Vector4 & Vector4::operator =( const Vector4 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    mW = vec.mW;\n    return *this;\n}\n\ninline Vector4 & Vector4::setXYZ( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    return *this;\n}\n\ninline const Vector3 Vector4::getXYZ( ) const\n{\n    return Vector3( mX, mY, mZ );\n}\n\ninline Vector4 & Vector4::setX( float _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline float Vector4::getX( ) const\n{\n    return mX;\n}\n\ninline Vector4 & Vector4::setY( float _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline float Vector4::getY( ) const\n{\n    return mY;\n}\n\ninline Vector4 & Vector4::setZ( float _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline float Vector4::getZ( ) const\n{\n    return mZ;\n}\n\ninline Vector4 & Vector4::setW( float _w )\n{\n    mW = _w;\n    return *this;\n}\n\ninline float Vector4::getW( ) const\n{\n    return mW;\n}\n\ninline Vector4 & Vector4::setElem( int idx, float value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline float Vector4::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline float & Vector4::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline float Vector4::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector4 Vector4::operator +( const Vector4 & vec ) const\n{\n    return Vector4(\n        ( mX + vec.mX ),\n        ( mY + vec.mY ),\n        ( mZ + vec.mZ ),\n        ( mW + vec.mW )\n    );\n}\n\ninline const Vector4 Vector4::operator -( const Vector4 & vec ) const\n{\n    return Vector4(\n        ( mX - vec.mX ),\n        ( mY - vec.mY ),\n        ( mZ - vec.mZ ),\n        ( mW - vec.mW )\n    );\n}\n\ninline const Vector4 Vector4::operator *( float scalar ) const\n{\n    return Vector4(\n        ( mX * scalar ),\n        ( mY * scalar ),\n        ( mZ * scalar ),\n        ( mW * scalar )\n    );\n}\n\ninline Vector4 & Vector4::operator +=( const Vector4 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator -=( const Vector4 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator /( float scalar ) const\n{\n    return Vector4(\n        ( mX / scalar ),\n        ( mY / scalar ),\n        ( mZ / scalar ),\n        ( mW / scalar )\n    );\n}\n\ninline Vector4 & Vector4::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator -( ) const\n{\n    return Vector4(\n        -mX,\n        -mY,\n        -mZ,\n        -mW\n    );\n}\n\ninline const Vector4 operator *( float scalar, const Vector4 & vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        ( vec0.getX() * vec1.getX() ),\n        ( vec0.getY() * vec1.getY() ),\n        ( vec0.getZ() * vec1.getZ() ),\n        ( vec0.getW() * vec1.getW() )\n    );\n}\n\ninline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        ( vec0.getX() / vec1.getX() ),\n        ( vec0.getY() / vec1.getY() ),\n        ( vec0.getZ() / vec1.getZ() ),\n        ( vec0.getW() / vec1.getW() )\n    );\n}\n\ninline const Vector4 recipPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        ( 1.0f / vec.getX() ),\n        ( 1.0f / vec.getY() ),\n        ( 1.0f / vec.getZ() ),\n        ( 1.0f / vec.getW() )\n    );\n}\n\ninline const Vector4 sqrtPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        sqrtf( vec.getX() ),\n        sqrtf( vec.getY() ),\n        sqrtf( vec.getZ() ),\n        sqrtf( vec.getW() )\n    );\n}\n\ninline const Vector4 rsqrtPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        ( 1.0f / sqrtf( vec.getX() ) ),\n        ( 1.0f / sqrtf( vec.getY() ) ),\n        ( 1.0f / sqrtf( vec.getZ() ) ),\n        ( 1.0f / sqrtf( vec.getW() ) )\n    );\n}\n\ninline const Vector4 absPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        fabsf( vec.getX() ),\n        fabsf( vec.getY() ),\n        fabsf( vec.getZ() ),\n        fabsf( vec.getW() )\n    );\n}\n\ninline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ),\n        ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ),\n        ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ),\n        ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() )\n    );\n}\n\ninline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(),\n        (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(),\n        (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(),\n        (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW()\n    );\n}\n\ninline float maxElem( const Vector4 & vec )\n{\n    float result;\n    result = (vec.getX() > vec.getY())? vec.getX() : vec.getY();\n    result = (vec.getZ() > result)? vec.getZ() : result;\n    result = (vec.getW() > result)? vec.getW() : result;\n    return result;\n}\n\ninline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(),\n        (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(),\n        (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(),\n        (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW()\n    );\n}\n\ninline float minElem( const Vector4 & vec )\n{\n    float result;\n    result = (vec.getX() < vec.getY())? vec.getX() : vec.getY();\n    result = (vec.getZ() < result)? vec.getZ() : result;\n    result = (vec.getW() < result)? vec.getW() : result;\n    return result;\n}\n\ninline float sum( const Vector4 & vec )\n{\n    float result;\n    result = ( vec.getX() + vec.getY() );\n    result = ( result + vec.getZ() );\n    result = ( result + vec.getW() );\n    return result;\n}\n\ninline float dot( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    float result;\n    result = ( vec0.getX() * vec1.getX() );\n    result = ( result + ( vec0.getY() * vec1.getY() ) );\n    result = ( result + ( vec0.getZ() * vec1.getZ() ) );\n    result = ( result + ( vec0.getW() * vec1.getW() ) );\n    return result;\n}\n\ninline float lengthSqr( const Vector4 & vec )\n{\n    float result;\n    result = ( vec.getX() * vec.getX() );\n    result = ( result + ( vec.getY() * vec.getY() ) );\n    result = ( result + ( vec.getZ() * vec.getZ() ) );\n    result = ( result + ( vec.getW() * vec.getW() ) );\n    return result;\n}\n\ninline float length( const Vector4 & vec )\n{\n    return sqrtf( lengthSqr( vec ) );\n}\n\ninline const Vector4 normalize( const Vector4 & vec )\n{\n    float lenSqr, lenInv;\n    lenSqr = lengthSqr( vec );\n    lenInv = ( 1.0f / sqrtf( lenSqr ) );\n    return Vector4(\n        ( vec.getX() * lenInv ),\n        ( vec.getY() * lenInv ),\n        ( vec.getZ() * lenInv ),\n        ( vec.getW() * lenInv )\n    );\n}\n\ninline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 )\n{\n    return Vector4(\n        ( select1 )? vec1.getX() : vec0.getX(),\n        ( select1 )? vec1.getY() : vec0.getY(),\n        ( select1 )? vec1.getZ() : vec0.getZ(),\n        ( select1 )? vec1.getW() : vec0.getW()\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector4 & vec )\n{\n    printf( \"( %f %f %f %f )\\n\", vec.getX(), vec.getY(), vec.getZ(), vec.getW() );\n}\n\ninline void print( const Vector4 & vec, const char * name )\n{\n    printf( \"%s: ( %f %f %f %f )\\n\", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() );\n}\n\n#endif\n\ninline Point3::Point3( const Point3 & pnt )\n{\n    mX = pnt.mX;\n    mY = pnt.mY;\n    mZ = pnt.mZ;\n}\n\ninline Point3::Point3( float _x, float _y, float _z )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n}\n\ninline Point3::Point3( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n}\n\ninline Point3::Point3( float scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n}\n\ninline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) );\n}\n\ninline Point3 & Point3::operator =( const Point3 & pnt )\n{\n    mX = pnt.mX;\n    mY = pnt.mY;\n    mZ = pnt.mZ;\n    return *this;\n}\n\ninline Point3 & Point3::setX( float _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline float Point3::getX( ) const\n{\n    return mX;\n}\n\ninline Point3 & Point3::setY( float _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline float Point3::getY( ) const\n{\n    return mY;\n}\n\ninline Point3 & Point3::setZ( float _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline float Point3::getZ( ) const\n{\n    return mZ;\n}\n\ninline Point3 & Point3::setElem( int idx, float value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline float Point3::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline float & Point3::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline float Point3::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector3 Point3::operator -( const Point3 & pnt ) const\n{\n    return Vector3(\n        ( mX - pnt.mX ),\n        ( mY - pnt.mY ),\n        ( mZ - pnt.mZ )\n    );\n}\n\ninline const Point3 Point3::operator +( const Vector3 & vec ) const\n{\n    return Point3(\n        ( mX + vec.getX() ),\n        ( mY + vec.getY() ),\n        ( mZ + vec.getZ() )\n    );\n}\n\ninline const Point3 Point3::operator -( const Vector3 & vec ) const\n{\n    return Point3(\n        ( mX - vec.getX() ),\n        ( mY - vec.getY() ),\n        ( mZ - vec.getZ() )\n    );\n}\n\ninline Point3 & Point3::operator +=( const Vector3 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Point3 & Point3::operator -=( const Vector3 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        ( pnt0.getX() * pnt1.getX() ),\n        ( pnt0.getY() * pnt1.getY() ),\n        ( pnt0.getZ() * pnt1.getZ() )\n    );\n}\n\ninline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        ( pnt0.getX() / pnt1.getX() ),\n        ( pnt0.getY() / pnt1.getY() ),\n        ( pnt0.getZ() / pnt1.getZ() )\n    );\n}\n\ninline const Point3 recipPerElem( const Point3 & pnt )\n{\n    return Point3(\n        ( 1.0f / pnt.getX() ),\n        ( 1.0f / pnt.getY() ),\n        ( 1.0f / pnt.getZ() )\n    );\n}\n\ninline const Point3 sqrtPerElem( const Point3 & pnt )\n{\n    return Point3(\n        sqrtf( pnt.getX() ),\n        sqrtf( pnt.getY() ),\n        sqrtf( pnt.getZ() )\n    );\n}\n\ninline const Point3 rsqrtPerElem( const Point3 & pnt )\n{\n    return Point3(\n        ( 1.0f / sqrtf( pnt.getX() ) ),\n        ( 1.0f / sqrtf( pnt.getY() ) ),\n        ( 1.0f / sqrtf( pnt.getZ() ) )\n    );\n}\n\ninline const Point3 absPerElem( const Point3 & pnt )\n{\n    return Point3(\n        fabsf( pnt.getX() ),\n        fabsf( pnt.getY() ),\n        fabsf( pnt.getZ() )\n    );\n}\n\ninline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ),\n        ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ),\n        ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() )\n    );\n}\n\ninline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(),\n        (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(),\n        (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ()\n    );\n}\n\ninline float maxElem( const Point3 & pnt )\n{\n    float result;\n    result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY();\n    result = (pnt.getZ() > result)? pnt.getZ() : result;\n    return result;\n}\n\ninline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(),\n        (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(),\n        (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ()\n    );\n}\n\ninline float minElem( const Point3 & pnt )\n{\n    float result;\n    result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY();\n    result = (pnt.getZ() < result)? pnt.getZ() : result;\n    return result;\n}\n\ninline float sum( const Point3 & pnt )\n{\n    float result;\n    result = ( pnt.getX() + pnt.getY() );\n    result = ( result + pnt.getZ() );\n    return result;\n}\n\ninline const Point3 scale( const Point3 & pnt, float scaleVal )\n{\n    return mulPerElem( pnt, Point3( scaleVal ) );\n}\n\ninline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec )\n{\n    return mulPerElem( pnt, Point3( scaleVec ) );\n}\n\ninline float projection( const Point3 & pnt, const Vector3 & unitVec )\n{\n    float result;\n    result = ( pnt.getX() * unitVec.getX() );\n    result = ( result + ( pnt.getY() * unitVec.getY() ) );\n    result = ( result + ( pnt.getZ() * unitVec.getZ() ) );\n    return result;\n}\n\ninline float distSqrFromOrigin( const Point3 & pnt )\n{\n    return lengthSqr( Vector3( pnt ) );\n}\n\ninline float distFromOrigin( const Point3 & pnt )\n{\n    return length( Vector3( pnt ) );\n}\n\ninline float distSqr( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return lengthSqr( ( pnt1 - pnt0 ) );\n}\n\ninline float dist( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return length( ( pnt1 - pnt0 ) );\n}\n\ninline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 )\n{\n    return Point3(\n        ( select1 )? pnt1.getX() : pnt0.getX(),\n        ( select1 )? pnt1.getY() : pnt0.getY(),\n        ( select1 )? pnt1.getZ() : pnt0.getZ()\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Point3 & pnt )\n{\n    printf( \"( %f %f %f )\\n\", pnt.getX(), pnt.getY(), pnt.getZ() );\n}\n\ninline void print( const Point3 & pnt, const char * name )\n{\n    printf( \"%s: ( %f %f %f )\\n\", name, pnt.getX(), pnt.getY(), pnt.getZ() );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/scalar/cpp/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_CPP_SCALAR_H\n#define _VECTORMATH_AOS_CPP_SCALAR_H\n\n#include <math.h>\n\n#ifdef _VECTORMATH_DEBUG\n#include <stdio.h>\n#endif\n\nnamespace Vectormath {\n\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Forward Declarations\n//\n\nclass Vector3;\nclass Vector4;\nclass Point3;\nclass Quat;\nclass Matrix3;\nclass Matrix4;\nclass Transform3;\n\n// A 3-D vector in array-of-structures format\n//\nclass Vector3\n{\n    float mX;\n    float mY;\n    float mZ;\n#ifndef __GNUC__\n    float d;\n#endif\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector3( ) { };\n\n    // Copy a 3-D vector\n    // \n    inline Vector3( const Vector3 & vec );\n\n    // Construct a 3-D vector from x, y, and z elements\n    // \n    inline Vector3( float x, float y, float z );\n\n    // Copy elements from a 3-D point into a 3-D vector\n    // \n    explicit inline Vector3( const Point3 & pnt );\n\n    // Set all elements of a 3-D vector to the same scalar value\n    // \n    explicit inline Vector3( float scalar );\n\n    // Assign one 3-D vector to another\n    // \n    inline Vector3 & operator =( const Vector3 & vec );\n\n    // Set the x element of a 3-D vector\n    // \n    inline Vector3 & setX( float x );\n\n    // Set the y element of a 3-D vector\n    // \n    inline Vector3 & setY( float y );\n\n    // Set the z element of a 3-D vector\n    // \n    inline Vector3 & setZ( float z );\n\n    // Get the x element of a 3-D vector\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a 3-D vector\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a 3-D vector\n    // \n    inline float getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D vector by index\n    // \n    inline Vector3 & setElem( int idx, float value );\n\n    // Get an x, y, or z element of a 3-D vector by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline float & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Add two 3-D vectors\n    // \n    inline const Vector3 operator +( const Vector3 & vec ) const;\n\n    // Subtract a 3-D vector from another 3-D vector\n    // \n    inline const Vector3 operator -( const Vector3 & vec ) const;\n\n    // Add a 3-D vector to a 3-D point\n    // \n    inline const Point3 operator +( const Point3 & pnt ) const;\n\n    // Multiply a 3-D vector by a scalar\n    // \n    inline const Vector3 operator *( float scalar ) const;\n\n    // Divide a 3-D vector by a scalar\n    // \n    inline const Vector3 operator /( float scalar ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Vector3 & operator +=( const Vector3 & vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Vector3 & operator -=( const Vector3 & vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector3 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector3 & operator /=( float scalar );\n\n    // Negate all elements of a 3-D vector\n    // \n    inline const Vector3 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector3 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector3 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector3 zAxis( );\n\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\n;\n\n// Multiply a 3-D vector by a scalar\n// \ninline const Vector3 operator *( float scalar, const Vector3 & vec );\n\n// Multiply two 3-D vectors per element\n// \ninline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Divide two 3-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Compute the reciprocal of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector3 recipPerElem( const Vector3 & vec );\n\n// Compute the square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector3 sqrtPerElem( const Vector3 & vec );\n\n// Compute the reciprocal square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector3 rsqrtPerElem( const Vector3 & vec );\n\n// Compute the absolute value of a 3-D vector per element\n// \ninline const Vector3 absPerElem( const Vector3 & vec );\n\n// Copy sign from one 3-D vector to another, per element\n// \ninline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Maximum of two 3-D vectors per element\n// \ninline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Minimum of two 3-D vectors per element\n// \ninline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Maximum element of a 3-D vector\n// \ninline float maxElem( const Vector3 & vec );\n\n// Minimum element of a 3-D vector\n// \ninline float minElem( const Vector3 & vec );\n\n// Compute the sum of all elements of a 3-D vector\n// \ninline float sum( const Vector3 & vec );\n\n// Compute the dot product of two 3-D vectors\n// \ninline float dot( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Compute the square of the length of a 3-D vector\n// \ninline float lengthSqr( const Vector3 & vec );\n\n// Compute the length of a 3-D vector\n// \ninline float length( const Vector3 & vec );\n\n// Normalize a 3-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector3 normalize( const Vector3 & vec );\n\n// Compute cross product of two 3-D vectors\n// \ninline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Outer product of two 3-D vectors\n// \ninline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Pre-multiply a row vector by a 3x3 matrix\n// \ninline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat );\n\n// Cross-product matrix of a 3-D vector\n// \ninline const Matrix3 crossMatrix( const Vector3 & vec );\n\n// Create cross-product matrix and multiply\n// NOTE: \n// Faster than separately creating a cross-product matrix and multiplying.\n// \ninline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat );\n\n// Linear interpolation between two 3-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 );\n\n// Spherical linear interpolation between two 3-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 );\n\n// Conditionally select between two 3-D vectors\n// \ninline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector3 & vec );\n\n// Print a 3-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector3 & vec, const char * name );\n\n#endif\n\n// A 4-D vector in array-of-structures format\n//\nclass Vector4\n{\n    float mX;\n    float mY;\n    float mZ;\n    float mW;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector4( ) { };\n\n    // Copy a 4-D vector\n    // \n    inline Vector4( const Vector4 & vec );\n\n    // Construct a 4-D vector from x, y, z, and w elements\n    // \n    inline Vector4( float x, float y, float z, float w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar\n    // \n    inline Vector4( const Vector3 & xyz, float w );\n\n    // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n    // \n    explicit inline Vector4( const Vector3 & vec );\n\n    // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n    // \n    explicit inline Vector4( const Point3 & pnt );\n\n    // Copy elements from a quaternion into a 4-D vector\n    // \n    explicit inline Vector4( const Quat & quat );\n\n    // Set all elements of a 4-D vector to the same scalar value\n    // \n    explicit inline Vector4( float scalar );\n\n    // Assign one 4-D vector to another\n    // \n    inline Vector4 & operator =( const Vector4 & vec );\n\n    // Set the x, y, and z elements of a 4-D vector\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Vector4 & setXYZ( const Vector3 & vec );\n\n    // Get the x, y, and z elements of a 4-D vector\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a 4-D vector\n    // \n    inline Vector4 & setX( float x );\n\n    // Set the y element of a 4-D vector\n    // \n    inline Vector4 & setY( float y );\n\n    // Set the z element of a 4-D vector\n    // \n    inline Vector4 & setZ( float z );\n\n    // Set the w element of a 4-D vector\n    // \n    inline Vector4 & setW( float w );\n\n    // Get the x element of a 4-D vector\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a 4-D vector\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a 4-D vector\n    // \n    inline float getZ( ) const;\n\n    // Get the w element of a 4-D vector\n    // \n    inline float getW( ) const;\n\n    // Set an x, y, z, or w element of a 4-D vector by index\n    // \n    inline Vector4 & setElem( int idx, float value );\n\n    // Get an x, y, z, or w element of a 4-D vector by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline float & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Add two 4-D vectors\n    // \n    inline const Vector4 operator +( const Vector4 & vec ) const;\n\n    // Subtract a 4-D vector from another 4-D vector\n    // \n    inline const Vector4 operator -( const Vector4 & vec ) const;\n\n    // Multiply a 4-D vector by a scalar\n    // \n    inline const Vector4 operator *( float scalar ) const;\n\n    // Divide a 4-D vector by a scalar\n    // \n    inline const Vector4 operator /( float scalar ) const;\n\n    // Perform compound assignment and addition with a 4-D vector\n    // \n    inline Vector4 & operator +=( const Vector4 & vec );\n\n    // Perform compound assignment and subtraction by a 4-D vector\n    // \n    inline Vector4 & operator -=( const Vector4 & vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector4 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector4 & operator /=( float scalar );\n\n    // Negate all elements of a 4-D vector\n    // \n    inline const Vector4 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector4 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector4 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector4 zAxis( );\n\n    // Construct w axis\n    // \n    static inline const Vector4 wAxis( );\n\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\n;\n\n// Multiply a 4-D vector by a scalar\n// \ninline const Vector4 operator *( float scalar, const Vector4 & vec );\n\n// Multiply two 4-D vectors per element\n// \ninline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Divide two 4-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Compute the reciprocal of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector4 recipPerElem( const Vector4 & vec );\n\n// Compute the square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector4 sqrtPerElem( const Vector4 & vec );\n\n// Compute the reciprocal square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector4 rsqrtPerElem( const Vector4 & vec );\n\n// Compute the absolute value of a 4-D vector per element\n// \ninline const Vector4 absPerElem( const Vector4 & vec );\n\n// Copy sign from one 4-D vector to another, per element\n// \ninline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Maximum of two 4-D vectors per element\n// \ninline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Minimum of two 4-D vectors per element\n// \ninline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Maximum element of a 4-D vector\n// \ninline float maxElem( const Vector4 & vec );\n\n// Minimum element of a 4-D vector\n// \ninline float minElem( const Vector4 & vec );\n\n// Compute the sum of all elements of a 4-D vector\n// \ninline float sum( const Vector4 & vec );\n\n// Compute the dot product of two 4-D vectors\n// \ninline float dot( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Compute the square of the length of a 4-D vector\n// \ninline float lengthSqr( const Vector4 & vec );\n\n// Compute the length of a 4-D vector\n// \ninline float length( const Vector4 & vec );\n\n// Normalize a 4-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector4 normalize( const Vector4 & vec );\n\n// Outer product of two 4-D vectors\n// \ninline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Linear interpolation between two 4-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 );\n\n// Spherical linear interpolation between two 4-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 );\n\n// Conditionally select between two 4-D vectors\n// \ninline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector4 & vec );\n\n// Print a 4-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector4 & vec, const char * name );\n\n#endif\n\n// A 3-D point in array-of-structures format\n//\nclass Point3\n{\n    float mX;\n    float mY;\n    float mZ;\n#ifndef __GNUC__\n    float d;\n#endif\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Point3( ) { };\n\n    // Copy a 3-D point\n    // \n    inline Point3( const Point3 & pnt );\n\n    // Construct a 3-D point from x, y, and z elements\n    // \n    inline Point3( float x, float y, float z );\n\n    // Copy elements from a 3-D vector into a 3-D point\n    // \n    explicit inline Point3( const Vector3 & vec );\n\n    // Set all elements of a 3-D point to the same scalar value\n    // \n    explicit inline Point3( float scalar );\n\n    // Assign one 3-D point to another\n    // \n    inline Point3 & operator =( const Point3 & pnt );\n\n    // Set the x element of a 3-D point\n    // \n    inline Point3 & setX( float x );\n\n    // Set the y element of a 3-D point\n    // \n    inline Point3 & setY( float y );\n\n    // Set the z element of a 3-D point\n    // \n    inline Point3 & setZ( float z );\n\n    // Get the x element of a 3-D point\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a 3-D point\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a 3-D point\n    // \n    inline float getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D point by index\n    // \n    inline Point3 & setElem( int idx, float value );\n\n    // Get an x, y, or z element of a 3-D point by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline float & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Subtract a 3-D point from another 3-D point\n    // \n    inline const Vector3 operator -( const Point3 & pnt ) const;\n\n    // Add a 3-D point to a 3-D vector\n    // \n    inline const Point3 operator +( const Vector3 & vec ) const;\n\n    // Subtract a 3-D vector from a 3-D point\n    // \n    inline const Point3 operator -( const Vector3 & vec ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Point3 & operator +=( const Vector3 & vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Point3 & operator -=( const Vector3 & vec );\n\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\n;\n\n// Multiply two 3-D points per element\n// \ninline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Divide two 3-D points per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Compute the reciprocal of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Point3 recipPerElem( const Point3 & pnt );\n\n// Compute the square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Point3 sqrtPerElem( const Point3 & pnt );\n\n// Compute the reciprocal square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Point3 rsqrtPerElem( const Point3 & pnt );\n\n// Compute the absolute value of a 3-D point per element\n// \ninline const Point3 absPerElem( const Point3 & pnt );\n\n// Copy sign from one 3-D point to another, per element\n// \ninline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Maximum of two 3-D points per element\n// \ninline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Minimum of two 3-D points per element\n// \ninline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Maximum element of a 3-D point\n// \ninline float maxElem( const Point3 & pnt );\n\n// Minimum element of a 3-D point\n// \ninline float minElem( const Point3 & pnt );\n\n// Compute the sum of all elements of a 3-D point\n// \ninline float sum( const Point3 & pnt );\n\n// Apply uniform scale to a 3-D point\n// \ninline const Point3 scale( const Point3 & pnt, float scaleVal );\n\n// Apply non-uniform scale to a 3-D point\n// \ninline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec );\n\n// Scalar projection of a 3-D point on a unit-length 3-D vector\n// \ninline float projection( const Point3 & pnt, const Vector3 & unitVec );\n\n// Compute the square of the distance of a 3-D point from the coordinate-system origin\n// \ninline float distSqrFromOrigin( const Point3 & pnt );\n\n// Compute the distance of a 3-D point from the coordinate-system origin\n// \ninline float distFromOrigin( const Point3 & pnt );\n\n// Compute the square of the distance between two 3-D points\n// \ninline float distSqr( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Compute the distance between two 3-D points\n// \ninline float dist( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Linear interpolation between two 3-D points\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 );\n\n// Conditionally select between two 3-D points\n// \ninline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D point\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Point3 & pnt );\n\n// Print a 3-D point and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Point3 & pnt, const char * name );\n\n#endif\n\n// A quaternion in array-of-structures format\n//\nclass Quat\n{\n    float mX;\n    float mY;\n    float mZ;\n    float mW;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Quat( ) { };\n\n    // Copy a quaternion\n    // \n    inline Quat( const Quat & quat );\n\n    // Construct a quaternion from x, y, z, and w elements\n    // \n    inline Quat( float x, float y, float z, float w );\n\n    // Construct a quaternion from a 3-D vector and a scalar\n    // \n    inline Quat( const Vector3 & xyz, float w );\n\n    // Copy elements from a 4-D vector into a quaternion\n    // \n    explicit inline Quat( const Vector4 & vec );\n\n    // Convert a rotation matrix to a unit-length quaternion\n    // \n    explicit inline Quat( const Matrix3 & rotMat );\n\n    // Set all elements of a quaternion to the same scalar value\n    // \n    explicit inline Quat( float scalar );\n\n    // Assign one quaternion to another\n    // \n    inline Quat & operator =( const Quat & quat );\n\n    // Set the x, y, and z elements of a quaternion\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Quat & setXYZ( const Vector3 & vec );\n\n    // Get the x, y, and z elements of a quaternion\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a quaternion\n    // \n    inline Quat & setX( float x );\n\n    // Set the y element of a quaternion\n    // \n    inline Quat & setY( float y );\n\n    // Set the z element of a quaternion\n    // \n    inline Quat & setZ( float z );\n\n    // Set the w element of a quaternion\n    // \n    inline Quat & setW( float w );\n\n    // Get the x element of a quaternion\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a quaternion\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a quaternion\n    // \n    inline float getZ( ) const;\n\n    // Get the w element of a quaternion\n    // \n    inline float getW( ) const;\n\n    // Set an x, y, z, or w element of a quaternion by index\n    // \n    inline Quat & setElem( int idx, float value );\n\n    // Get an x, y, z, or w element of a quaternion by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline float & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Add two quaternions\n    // \n    inline const Quat operator +( const Quat & quat ) const;\n\n    // Subtract a quaternion from another quaternion\n    // \n    inline const Quat operator -( const Quat & quat ) const;\n\n    // Multiply two quaternions\n    // \n    inline const Quat operator *( const Quat & quat ) const;\n\n    // Multiply a quaternion by a scalar\n    // \n    inline const Quat operator *( float scalar ) const;\n\n    // Divide a quaternion by a scalar\n    // \n    inline const Quat operator /( float scalar ) const;\n\n    // Perform compound assignment and addition with a quaternion\n    // \n    inline Quat & operator +=( const Quat & quat );\n\n    // Perform compound assignment and subtraction by a quaternion\n    // \n    inline Quat & operator -=( const Quat & quat );\n\n    // Perform compound assignment and multiplication by a quaternion\n    // \n    inline Quat & operator *=( const Quat & quat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Quat & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Quat & operator /=( float scalar );\n\n    // Negate all elements of a quaternion\n    // \n    inline const Quat operator -( ) const;\n\n    // Construct an identity quaternion\n    // \n    static inline const Quat identity( );\n\n    // Construct a quaternion to rotate between two unit-length 3-D vectors\n    // NOTE: \n    // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n    // \n    static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector\n    // \n    static inline const Quat rotation( float radians, const Vector3 & unitVec );\n\n    // Construct a quaternion to rotate around the x axis\n    // \n    static inline const Quat rotationX( float radians );\n\n    // Construct a quaternion to rotate around the y axis\n    // \n    static inline const Quat rotationY( float radians );\n\n    // Construct a quaternion to rotate around the z axis\n    // \n    static inline const Quat rotationZ( float radians );\n\n}\n#ifdef __GNUC__\n__attribute__ ((aligned(16)))\n#endif\n;\n\n// Multiply a quaternion by a scalar\n// \ninline const Quat operator *( float scalar, const Quat & quat );\n\n// Compute the conjugate of a quaternion\n// \ninline const Quat conj( const Quat & quat );\n\n// Use a unit-length quaternion to rotate a 3-D vector\n// \ninline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec );\n\n// Compute the dot product of two quaternions\n// \ninline float dot( const Quat & quat0, const Quat & quat1 );\n\n// Compute the norm of a quaternion\n// \ninline float norm( const Quat & quat );\n\n// Compute the length of a quaternion\n// \ninline float length( const Quat & quat );\n\n// Normalize a quaternion\n// NOTE: \n// The result is unpredictable when all elements of quat are at or near zero.\n// \ninline const Quat normalize( const Quat & quat );\n\n// Linear interpolation between two quaternions\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 );\n\n// Spherical linear interpolation between two quaternions\n// NOTE: \n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n// \ninline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 );\n\n// Spherical quadrangle interpolation\n// \ninline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 );\n\n// Conditionally select between two quaternions\n// \ninline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a quaternion\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Quat & quat );\n\n// Print a quaternion and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Quat & quat, const char * name );\n\n#endif\n\n// A 3x3 matrix in array-of-structures format\n//\nclass Matrix3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix3( ) { };\n\n    // Copy a 3x3 matrix\n    // \n    inline Matrix3( const Matrix3 & mat );\n\n    // Construct a 3x3 matrix containing the specified columns\n    // \n    inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 );\n\n    // Construct a 3x3 rotation matrix from a unit-length quaternion\n    // \n    explicit inline Matrix3( const Quat & unitQuat );\n\n    // Set all elements of a 3x3 matrix to the same scalar value\n    // \n    explicit inline Matrix3( float scalar );\n\n    // Assign one 3x3 matrix to another\n    // \n    inline Matrix3 & operator =( const Matrix3 & mat );\n\n    // Set column 0 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol0( const Vector3 & col0 );\n\n    // Set column 1 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol1( const Vector3 & col1 );\n\n    // Set column 2 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol2( const Vector3 & col2 );\n\n    // Get column 0 of a 3x3 matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x3 matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x3 matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Set the column of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setCol( int col, const Vector3 & vec );\n\n    // Set the row of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setRow( int row, const Vector3 & vec );\n\n    // Get the column of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline Matrix3 & setElem( int col, int row, float val );\n\n    // Get the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline float getElem( int col, int row ) const;\n\n    // Add two 3x3 matrices\n    // \n    inline const Matrix3 operator +( const Matrix3 & mat ) const;\n\n    // Subtract a 3x3 matrix from another 3x3 matrix\n    // \n    inline const Matrix3 operator -( const Matrix3 & mat ) const;\n\n    // Negate all elements of a 3x3 matrix\n    // \n    inline const Matrix3 operator -( ) const;\n\n    // Multiply a 3x3 matrix by a scalar\n    // \n    inline const Matrix3 operator *( float scalar ) const;\n\n    // Multiply a 3x3 matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( const Vector3 & vec ) const;\n\n    // Multiply two 3x3 matrices\n    // \n    inline const Matrix3 operator *( const Matrix3 & mat ) const;\n\n    // Perform compound assignment and addition with a 3x3 matrix\n    // \n    inline Matrix3 & operator +=( const Matrix3 & mat );\n\n    // Perform compound assignment and subtraction by a 3x3 matrix\n    // \n    inline Matrix3 & operator -=( const Matrix3 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix3 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a 3x3 matrix\n    // \n    inline Matrix3 & operator *=( const Matrix3 & mat );\n\n    // Construct an identity 3x3 matrix\n    // \n    static inline const Matrix3 identity( );\n\n    // Construct a 3x3 matrix to rotate around the x axis\n    // \n    static inline const Matrix3 rotationX( float radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis\n    // \n    static inline const Matrix3 rotationY( float radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis\n    // \n    static inline const Matrix3 rotationZ( float radians );\n\n    // Construct a 3x3 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix3 rotation( float radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix3 rotation( const Quat & unitQuat );\n\n    // Construct a 3x3 matrix to perform scaling\n    // \n    static inline const Matrix3 scale( const Vector3 & scaleVec );\n\n};\n// Multiply a 3x3 matrix by a scalar\n// \ninline const Matrix3 operator *( float scalar, const Matrix3 & mat );\n\n// Append (post-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat );\n\n// Multiply two 3x3 matrices per element\n// \ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );\n\n// Compute the absolute value of a 3x3 matrix per element\n// \ninline const Matrix3 absPerElem( const Matrix3 & mat );\n\n// Transpose of a 3x3 matrix\n// \ninline const Matrix3 transpose( const Matrix3 & mat );\n\n// Compute the inverse of a 3x3 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix3 inverse( const Matrix3 & mat );\n\n// Determinant of a 3x3 matrix\n// \ninline float determinant( const Matrix3 & mat );\n\n// Conditionally select between two 3x3 matrices\n// \ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x3 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat );\n\n// Print a 3x3 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat, const char * name );\n\n#endif\n\n// A 4x4 matrix in array-of-structures format\n//\nclass Matrix4\n{\n    Vector4 mCol0;\n    Vector4 mCol1;\n    Vector4 mCol2;\n    Vector4 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix4( ) { };\n\n    // Copy a 4x4 matrix\n    // \n    inline Matrix4( const Matrix4 & mat );\n\n    // Construct a 4x4 matrix containing the specified columns\n    // \n    inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 );\n\n    // Construct a 4x4 matrix from a 3x4 transformation matrix\n    // \n    explicit inline Matrix4( const Transform3 & mat );\n\n    // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec );\n\n    // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec );\n\n    // Set all elements of a 4x4 matrix to the same scalar value\n    // \n    explicit inline Matrix4( float scalar );\n\n    // Assign one 4x4 matrix to another\n    // \n    inline Matrix4 & operator =( const Matrix4 & mat );\n\n    // Set the upper-left 3x3 submatrix\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 4x4 matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setTranslation( const Vector3 & translateVec );\n\n    // Get the translation component of a 4x4 matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol0( const Vector4 & col0 );\n\n    // Set column 1 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol1( const Vector4 & col1 );\n\n    // Set column 2 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol2( const Vector4 & col2 );\n\n    // Set column 3 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol3( const Vector4 & col3 );\n\n    // Get column 0 of a 4x4 matrix\n    // \n    inline const Vector4 getCol0( ) const;\n\n    // Get column 1 of a 4x4 matrix\n    // \n    inline const Vector4 getCol1( ) const;\n\n    // Get column 2 of a 4x4 matrix\n    // \n    inline const Vector4 getCol2( ) const;\n\n    // Get column 3 of a 4x4 matrix\n    // \n    inline const Vector4 getCol3( ) const;\n\n    // Set the column of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setCol( int col, const Vector4 & vec );\n\n    // Set the row of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setRow( int row, const Vector4 & vec );\n\n    // Get the column of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getCol( int col ) const;\n\n    // Get the row of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector4 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector4 operator []( int col ) const;\n\n    // Set the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline Matrix4 & setElem( int col, int row, float val );\n\n    // Get the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline float getElem( int col, int row ) const;\n\n    // Add two 4x4 matrices\n    // \n    inline const Matrix4 operator +( const Matrix4 & mat ) const;\n\n    // Subtract a 4x4 matrix from another 4x4 matrix\n    // \n    inline const Matrix4 operator -( const Matrix4 & mat ) const;\n\n    // Negate all elements of a 4x4 matrix\n    // \n    inline const Matrix4 operator -( ) const;\n\n    // Multiply a 4x4 matrix by a scalar\n    // \n    inline const Matrix4 operator *( float scalar ) const;\n\n    // Multiply a 4x4 matrix by a 4-D vector\n    // \n    inline const Vector4 operator *( const Vector4 & vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D vector\n    // \n    inline const Vector4 operator *( const Vector3 & vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D point\n    // \n    inline const Vector4 operator *( const Point3 & pnt ) const;\n\n    // Multiply two 4x4 matrices\n    // \n    inline const Matrix4 operator *( const Matrix4 & mat ) const;\n\n    // Multiply a 4x4 matrix by a 3x4 transformation matrix\n    // \n    inline const Matrix4 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and addition with a 4x4 matrix\n    // \n    inline Matrix4 & operator +=( const Matrix4 & mat );\n\n    // Perform compound assignment and subtraction by a 4x4 matrix\n    // \n    inline Matrix4 & operator -=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix4 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a 4x4 matrix\n    // \n    inline Matrix4 & operator *=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Matrix4 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 4x4 matrix\n    // \n    static inline const Matrix4 identity( );\n\n    // Construct a 4x4 matrix to rotate around the x axis\n    // \n    static inline const Matrix4 rotationX( float radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis\n    // \n    static inline const Matrix4 rotationY( float radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis\n    // \n    static inline const Matrix4 rotationZ( float radians );\n\n    // Construct a 4x4 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix4 rotation( float radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix4 rotation( const Quat & unitQuat );\n\n    // Construct a 4x4 matrix to perform scaling\n    // \n    static inline const Matrix4 scale( const Vector3 & scaleVec );\n\n    // Construct a 4x4 matrix to perform translation\n    // \n    static inline const Matrix4 translation( const Vector3 & translateVec );\n\n    // Construct viewing matrix based on eye position, position looked at, and up direction\n    // \n    static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec );\n\n    // Construct a perspective projection matrix\n    // \n    static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar );\n\n    // Construct a perspective projection matrix based on frustum\n    // \n    static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar );\n\n    // Construct an orthographic projection matrix\n    // \n    static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar );\n\n};\n// Multiply a 4x4 matrix by a scalar\n// \ninline const Matrix4 operator *( float scalar, const Matrix4 & mat );\n\n// Append (post-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat );\n\n// Multiply two 4x4 matrices per element\n// \ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );\n\n// Compute the absolute value of a 4x4 matrix per element\n// \ninline const Matrix4 absPerElem( const Matrix4 & mat );\n\n// Transpose of a 4x4 matrix\n// \ninline const Matrix4 transpose( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 inverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 affineInverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n// \ninline const Matrix4 orthoInverse( const Matrix4 & mat );\n\n// Determinant of a 4x4 matrix\n// \ninline float determinant( const Matrix4 & mat );\n\n// Conditionally select between two 4x4 matrices\n// \ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4x4 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat );\n\n// Print a 4x4 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat, const char * name );\n\n#endif\n\n// A 3x4 transformation matrix in array-of-structures format\n//\nclass Transform3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n    Vector3 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Transform3( ) { };\n\n    // Copy a 3x4 transformation matrix\n    // \n    inline Transform3( const Transform3 & tfrm );\n\n    // Construct a 3x4 transformation matrix containing the specified columns\n    // \n    inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 );\n\n    // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec );\n\n    // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Transform3( const Quat & unitQuat, const Vector3 & translateVec );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value\n    // \n    explicit inline Transform3( float scalar );\n\n    // Assign one 3x4 transformation matrix to another\n    // \n    inline Transform3 & operator =( const Transform3 & tfrm );\n\n    // Set the upper-left 3x3 submatrix\n    // \n    inline Transform3 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // \n    inline Transform3 & setTranslation( const Vector3 & translateVec );\n\n    // Get the translation component of a 3x4 transformation matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol0( const Vector3 & col0 );\n\n    // Set column 1 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol1( const Vector3 & col1 );\n\n    // Set column 2 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol2( const Vector3 & col2 );\n\n    // Set column 3 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol3( const Vector3 & col3 );\n\n    // Get column 0 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Get column 3 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol3( ) const;\n\n    // Set the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setCol( int col, const Vector3 & vec );\n\n    // Set the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setRow( int row, const Vector4 & vec );\n\n    // Get the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline Transform3 & setElem( int col, int row, float val );\n\n    // Get the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline float getElem( int col, int row ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( const Vector3 & vec ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D point\n    // \n    inline const Point3 operator *( const Point3 & pnt ) const;\n\n    // Multiply two 3x4 transformation matrices\n    // \n    inline const Transform3 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Transform3 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 3x4 transformation matrix\n    // \n    static inline const Transform3 identity( );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis\n    // \n    static inline const Transform3 rotationX( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis\n    // \n    static inline const Transform3 rotationY( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis\n    // \n    static inline const Transform3 rotationZ( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n    // \n    static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Transform3 rotation( float radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Transform3 rotation( const Quat & unitQuat );\n\n    // Construct a 3x4 transformation matrix to perform scaling\n    // \n    static inline const Transform3 scale( const Vector3 & scaleVec );\n\n    // Construct a 3x4 transformation matrix to perform translation\n    // \n    static inline const Transform3 translation( const Vector3 & translateVec );\n\n};\n// Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm );\n\n// Multiply two 3x4 transformation matrices per element\n// \ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );\n\n// Compute the absolute value of a 3x4 transformation matrix per element\n// \ninline const Transform3 absPerElem( const Transform3 & tfrm );\n\n// Inverse of a 3x4 transformation matrix\n// NOTE: \n// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n// \ninline const Transform3 inverse( const Transform3 & tfrm );\n\n// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n// \ninline const Transform3 orthoInverse( const Transform3 & tfrm );\n\n// Conditionally select between two 3x4 transformation matrices\n// \ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x4 transformation matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm );\n\n// Print a 3x4 transformation matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm, const char * name );\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_C_H\n#define _VECTORMATH_MAT_AOS_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_0ZB0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_0 })     \n#define _VECTORMATH_SHUF_C0X0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_YA00 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_Z })\n#define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X })\n#define _VECTORMATH_SHUF_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y })\n#define _VECTORMATH_SHUF_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZAY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_BZX0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_0ZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A })\n#define _VECTORMATH_SHUF_Z0XB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YX0C ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_CZD0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_BBY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( &result->col0, &mat->col0 );\n    vmathV3Copy( &result->col1, &mat->col1 );\n    vmathV3Copy( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar )\n{\n    vmathV3MakeFromScalar( &result->col0, scalar );\n    vmathV3MakeFromScalar( &result->col1, scalar );\n    vmathV3MakeFromScalar( &result->col2, scalar );\n}\n\nstatic inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat )\n{\n    vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    vec_uint4 select_x = (vec_uint4)spu_maskb(0xf000);\n    vec_uint4 select_z = (vec_uint4)spu_maskb(0x00f0);\n    xyzw_2 = spu_add( unitQuat->vec128, unitQuat->vec128 );\n    wwww = spu_shuffle( unitQuat->vec128, unitQuat->vec128, shuffle_wwww );\n    yzxw = spu_shuffle( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_SHUF_YZXW );\n    zxyw = spu_shuffle( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_SHUF_ZXYW );\n    yzxw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_YZXW );\n    zxyw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_ZXYW );\n    tmp0 = spu_mul( yzxw_2, wwww );\n    tmp1 = spu_nmsub( yzxw, yzxw_2, spu_splats(1.0f) );\n    tmp2 = spu_mul( yzxw, xyzw_2 );\n    tmp0 = spu_madd( zxyw, xyzw_2, tmp0 );\n    tmp1 = spu_nmsub( zxyw, zxyw_2, tmp1 );\n    tmp2 = spu_nmsub( zxyw_2, wwww, tmp2 );\n    tmp3 = spu_sel( tmp0, tmp1, select_x );\n    tmp4 = spu_sel( tmp1, tmp2, select_x );\n    tmp5 = spu_sel( tmp2, tmp0, select_x );\n    result->col0.vec128 = spu_sel( tmp3, tmp2, select_z );\n    result->col1.vec128 = spu_sel( tmp4, tmp0, select_z );\n    result->col2.vec128 = spu_sel( tmp5, tmp1, select_z );\n}\n\nstatic inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n    vmathV3Copy( &result->col1, _col1 );\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *_col0 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *_col1 )\n{\n    vmathV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec )\n{\n    vmathV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec )\n{\n    vmathV3SetElem( &result->col0, row, vmathV3GetElem( vec, 0 ) );\n    vmathV3SetElem( &result->col1, row, vmathV3GetElem( vec, 1 ) );\n    vmathV3SetElem( &result->col2, row, vmathV3GetElem( vec, 2 ) );\n}\n\nstatic inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val )\n{\n    VmathVector3 tmpV3_0;\n    vmathM3GetCol( &tmpV3_0, result, col );\n    vmathV3SetElem( &tmpV3_0, row, val );\n    vmathM3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row )\n{\n    VmathVector3 tmpV3_0;\n    vmathM3GetCol( &tmpV3_0, mat, col );\n    return vmathV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col )\n{\n    vmathV3Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row )\n{\n    vmathV3MakeFromElems( result, vmathV3GetElem( &mat->col0, row ), vmathV3GetElem( &mat->col1, row ), vmathV3GetElem( &mat->col2, row ) );\n}\n\nstatic inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vec_float4 tmp0, tmp1, res0, res1, res2;\n    tmp0 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_ZCWD );\n    res0 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_XAYB );\n    res1 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_ZBW0 );\n    res2 = spu_shuffle( tmp1, mat->col1.vec128, _VECTORMATH_SHUF_XCY0 );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2;\n    tmp2 = _vmathVfCross( mat->col0.vec128, mat->col1.vec128 );\n    tmp0 = _vmathVfCross( mat->col1.vec128, mat->col2.vec128 );\n    tmp1 = _vmathVfCross( mat->col2.vec128, mat->col0.vec128 );\n    dot = _vmathVfDot3( tmp2, mat->col2.vec128 );\n    dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) );\n    invdet = recipf4( dot );\n    tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB );\n    tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD );\n    inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB );\n    inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 );\n    inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 );\n    inv0 = spu_mul( inv0, invdet );\n    inv1 = spu_mul( inv1, invdet );\n    inv2 = spu_mul( inv2, invdet );\n    result->col0.vec128 = inv0;\n    result->col1.vec128 = inv1;\n    result->col2.vec128 = inv2;\n}\n\nstatic inline float vmathM3Determinant( const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3Cross( &tmpV3_0, &mat->col0, &mat->col1 );\n    return vmathV3Dot( &mat->col2, &tmpV3_0 );\n}\n\nstatic inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3Add( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3Sub( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3Neg( &result->col0, &mat->col0 );\n    vmathV3Neg( &result->col1, &mat->col1 );\n    vmathV3Neg( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathV3AbsPerElem( &result->col0, &mat->col0 );\n    vmathV3AbsPerElem( &result->col1, &mat->col1 );\n    vmathV3AbsPerElem( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar )\n{\n    vmathV3ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathV3ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathV3ScalarMul( &result->col2, &mat->col2, scalar );\n}\n\nstatic inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec )\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx );\n    yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy );\n    zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz );\n    res = spu_mul( mat->col0.vec128, xxxx );\n    res = spu_madd( mat->col1.vec128, yyyy, res );\n    res = spu_madd( mat->col2.vec128, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    VmathMatrix3 tmpResult;\n    vmathM3MulV3( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathM3MulV3( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathM3MulV3( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 )\n{\n    vmathV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathM3MakeIdentity( VmathMatrix3 *result )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res1 = spu_sel( zero, c, select_y );\n    res1 = spu_sel( res1, s, select_z );\n    res2 = spu_sel( zero, negatef4(s), select_y );\n    res2 = spu_sel( res2, c, select_z );\n    vmathV3MakeXAxis( &result->col0 );\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, negatef4(s), select_z );\n    res2 = spu_sel( zero, s, select_x );\n    res2 = spu_sel( res2, c, select_z );\n    result->col0.vec128 = res0;\n    vmathV3MakeYAxis( &result->col1 );\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, s, select_y );\n    res1 = spu_sel( zero, negatef4(s), select_x );\n    res1 = spu_sel( res1, c, select_y );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    vmathV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    angles = radiansXYZ->vec128;\n    angles = spu_insert( 0.0f, angles, 3 );\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 );\n    Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 );\n    Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 );\n    Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 );\n    X0 = spu_shuffle( s, s, shuffle_xxxx );\n    X1 = spu_shuffle( c, c, shuffle_xxxx );\n    tmp = spu_mul( Z0, Y1 );\n    result->col0.vec128 = spu_mul( Z0, Y0 );\n    result->col1.vec128 = spu_madd( Z1, X1, spu_mul( tmp, X0 ) );\n    result->col2.vec128 = spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) );\n}\n\nstatic inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    axis = unitVec->vec128;\n    sincosf4( spu_splats( radians ), &s, &c );\n    xxxx = spu_shuffle( axis, axis, shuffle_xxxx );\n    yyyy = spu_shuffle( axis, axis, shuffle_yyyy );\n    zzzz = spu_shuffle( axis, axis, shuffle_zzzz );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    axisS = spu_mul( axis, s );\n    negAxisS = negatef4( axisS );\n    tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 );\n    tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 );\n    tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 );\n    tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) );\n    tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) );\n    tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) );\n    result->col0.vec128 = spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 );\n    result->col1.vec128 = spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 );\n    result->col2.vec128 = spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 );\n}\n\nstatic inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat )\n{\n    vmathM3MakeFromQ( result, unitQuat );\n}\n\nstatic inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec )\n{\n    vec_float4 zero = spu_splats(0.0f);\n    result->col0.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0xf000) );\n    result->col1.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x0f00) );\n    result->col2.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x00f0) );\n}\n\nstatic inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec )\n{\n    vmathV3ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) );\n    vmathV3ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) );\n    vmathV3ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) );\n}\n\nstatic inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat )\n{\n    vmathV3MulPerElem( &result->col0, &mat->col0, scaleVec );\n    vmathV3MulPerElem( &result->col1, &mat->col1, scaleVec );\n    vmathV3MulPerElem( &result->col2, &mat->col2, scaleVec );\n}\n\nstatic inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 )\n{\n    vmathV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM3Print( const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathM3GetRow( &tmpV3_0, mat, 0 );\n    vmathV3Print( &tmpV3_0 );\n    vmathM3GetRow( &tmpV3_1, mat, 1 );\n    vmathV3Print( &tmpV3_1 );\n    vmathM3GetRow( &tmpV3_2, mat, 2 );\n    vmathV3Print( &tmpV3_2 );\n}\n\nstatic inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathM3Print( mat );\n}\n\n#endif\n\nstatic inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( &result->col0, &mat->col0 );\n    vmathV4Copy( &result->col1, &mat->col1 );\n    vmathV4Copy( &result->col2, &mat->col2 );\n    vmathV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar )\n{\n    vmathV4MakeFromScalar( &result->col0, scalar );\n    vmathV4MakeFromScalar( &result->col1, scalar );\n    vmathV4MakeFromScalar( &result->col2, scalar );\n    vmathV4MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat )\n{\n    vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, &mat->col3, 1.0f );\n}\n\nstatic inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *_col0, const VmathVector4 *_col1, const VmathVector4 *_col2, const VmathVector4 *_col3 )\n{\n    vmathV4Copy( &result->col0, _col0 );\n    vmathV4Copy( &result->col1, _col1 );\n    vmathV4Copy( &result->col2, _col2 );\n    vmathV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec )\n{\n    vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec )\n{\n    VmathMatrix3 mat;\n    vmathM3MakeFromQ( &mat, unitQuat );\n    vmathV4MakeFromV3Scalar( &result->col0, &mat.col0, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col1, &mat.col1, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col2, &mat.col2, 0.0f );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *_col0 )\n{\n    vmathV4Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *_col1 )\n{\n    vmathV4Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *_col2 )\n{\n    vmathV4Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *_col3 )\n{\n    vmathV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec )\n{\n    vmathV4Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec )\n{\n    vmathV4SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) );\n    vmathV4SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) );\n    vmathV4SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) );\n    vmathV4SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val )\n{\n    VmathVector4 tmpV3_0;\n    vmathM4GetCol( &tmpV3_0, result, col );\n    vmathV4SetElem( &tmpV3_0, row, val );\n    vmathM4SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row )\n{\n    VmathVector4 tmpV4_0;\n    vmathM4GetCol( &tmpV4_0, mat, col );\n    return vmathV4GetElem( &tmpV4_0, row );\n}\n\nstatic inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Copy( result, &mat->col3 );\n}\n\nstatic inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col )\n{\n    vmathV4Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row )\n{\n    vmathV4MakeFromElems( result, vmathV4GetElem( &mat->col0, row ), vmathV4GetElem( &mat->col1, row ), vmathV4GetElem( &mat->col2, row ), vmathV4GetElem( &mat->col3, row ) );\n}\n\nstatic inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3;\n    tmp0 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mat->col1.vec128, mat->col3.vec128, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( mat->col1.vec128, mat->col3.vec128, _VECTORMATH_SHUF_ZCWD );\n    res0 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    res1 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    res2 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n    res3 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n    result->col3.vec128 = res3;\n}\n\nstatic inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 in0, in1, in2, in3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    vec_float4 cof0, cof1, cof2, cof3;\n    vec_float4 t0, t1, t2, t3;\n    vec_float4 t01, t02, t03, t12, t23;\n    vec_float4 t1r, t2r;\n    vec_float4 t01r, t02r, t03r, t12r, t23r;\n    vec_float4 t1r3, t1r3r;\n    vec_float4 det, det1, det2, det3, invdet;\n    in0 = mat->col0.vec128;\n    in1 = mat->col1.vec128;\n    in2 = mat->col2.vec128;\n    in3 = mat->col3.vec128;\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC);    /* A E C G */\n    tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC);    /* I M K O */\n    tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD);    /* B F D H */\n    tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD);    /* J N L P */\n    t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB);    /* A E I M */\n    t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB);    /* J N B F */\n    t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD);    /* C G K O */\n    t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD);    /* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = spu_mul(t2, t3);                        /* CL GP KD OH */\n    t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ);     /* GP CL OH KD */\n    cof0 = spu_mul(t1, t23);                      /* JGP NCL BOH FKD */\n    cof1 = spu_mul(t0, t23);                      /* AGP ECL IOH MKD */\n    t23r = spu_rlqwbyte(t23, 8);                  /* OH KD GP CL */\n    cof0 = spu_msub(t1, t23r, cof0);              /* JOH NKD BGP FCL  - cof0 */\n    cof1 = spu_msub(t0, t23r, cof1);              /* AOH EKD IGP MCL  - cof1 */\n    cof1 = spu_rlqwbyte(cof1, 8);                 /* IGP MCL AOH EKD - IOH MKD AGP ECL */\n\n    t12 = spu_mul(t1, t2);                        /* JC NG BK FO */\n    t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ);     /* NG JC FO BK */\n    cof0 = spu_madd(t3, t12, cof0);               /* LNG PJC DFO HBK + cof0 */\n    cof3 = spu_mul(t0, t12);                      /* ANG EJC IFO MBK */\n    t12r = spu_rlqwbyte(t12, 8);                  /* FO BK NG JC */\n    cof0 = spu_nmsub(t3, t12r, cof0);             /* cof0 - LFO PBK DNG HJC */\n    cof3 = spu_msub(t0, t12r, cof3);              /* AFO EBK ING MJC - cof3 */\n    cof3 = spu_rlqwbyte(cof3, 8);                 /* ING MJC AFO EBK - IFO MBK ANG EJC */\n    t1r = spu_rlqwbyte(t1, 8);                    /* B F J N */\n    t2r = spu_rlqwbyte(t2, 8);                    /* K O C G */\n    t1r3 = spu_mul(t1r, t3);                      /* BL FP JD NH */\n    t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ);  /* FP BL NH JD */\n    cof0 = spu_madd(t2r, t1r3, cof0);             /* KFP OBL CNH GJD + cof0 */\n    cof2 = spu_mul(t0, t1r3);                     /* AFP EBL INH MJD */\n    t1r3r = spu_rlqwbyte(t1r3, 8);                /* NH JD FP BL */\n    cof0 = spu_nmsub(t2r, t1r3r, cof0);           /* cof0 - KNH OJD CFP GBL */\n    cof2 = spu_msub(t0, t1r3r, cof2);             /* ANH EJD IFP MBL - cof2 */\n    cof2 = spu_rlqwbyte(cof2, 8);                 /* IFP MBL ANH EJD - INH MJD AFP EBL */\n    t01 = spu_mul(t0, t1);                                /* AJ EN IB MF */\n    t01 = spu_shuffle(t01, t01, _VECTORMATH_SHUF_YXWZ);     /* EN AJ MF IB */\n    cof2 = spu_madd(t3, t01, cof2);               /* LEN PAJ DMF HIB + cof2 */\n    cof3 = spu_msub(t2r, t01, cof3);              /* KEN OAJ CMF GIB - cof3 */\n    t01r = spu_rlqwbyte(t01, 8);                  /* MF IB EN AJ */\n    cof2 = spu_msub(t3, t01r, cof2);              /* LMF PIB DEN HAJ - cof2 */\n    cof3 = spu_nmsub(t2r, t01r, cof3);            /* cof3 - KMF OIB CEN GAJ */\n    t03 = spu_mul(t0, t3);                                /* AL EP ID MH */\n    t03 = spu_shuffle(t03, t03, _VECTORMATH_SHUF_YXWZ);     /* EP AL MH ID */\n    cof1 = spu_nmsub(t2r, t03, cof1);             /* cof1 - KEP OAL CMH GID */\n    cof2 = spu_madd(t1, t03, cof2);               /* JEP NAL BMH FID + cof2 */\n    t03r = spu_rlqwbyte(t03, 8);                  /* MH ID EP AL */\n    cof1 = spu_madd(t2r, t03r, cof1);             /* KMH OID CEP GAL + cof1 */\n    cof2 = spu_nmsub(t1, t03r, cof2);             /* cof2 - JMH NID BEP FAL */\n    t02 = spu_mul(t0, t2r);                       /* AK EO IC MG */\n    t02 = spu_shuffle(t02, t02, _VECTORMATH_SHUF_YXWZ);     /* E0 AK MG IC */\n    cof1 = spu_madd(t3, t02, cof1);               /* LEO PAK DMG HIC + cof1 */\n    cof3 = spu_nmsub(t1, t02, cof3);              /* cof3 - JEO NAK BMG FIC */\n    t02r = spu_rlqwbyte(t02, 8);                  /* MG IC EO AK */\n    cof1 = spu_nmsub(t3, t02r, cof1);             /* cof1 - LMG PIC DEO HAK */\n    cof3 = spu_madd(t1, t02r, cof3);              /* JMG NIC BEO FAK + cof3 */\n    /* Compute the determinant of the matrix\n     *\n     * det = sum_across(t0 * cof0);\n     *\n     * We perform a sum across the entire vector so that\n     * we don't have to splat the result when multiplying the\n     * cofactors by the inverse of the determinant.\n     */\n    det  = spu_mul(t0, cof0);\n    det1 = spu_rlqwbyte(det, 4);\n    det2 = spu_rlqwbyte(det, 8);\n    det3 = spu_rlqwbyte(det, 12);\n    det  = spu_add(det, det1);\n    det2 = spu_add(det2, det3);\n    det  = spu_add(det, det2);\n    /* Compute the reciprocal of the determinant.\n     */\n    invdet = recipf4(det);\n    /* Multiply the cofactors by the reciprocal of the determinant.\n     */\n    result->col0.vec128 = spu_mul(cof0, invdet);\n    result->col1.vec128 = spu_mul(cof1, invdet);\n    result->col2.vec128 = spu_mul(cof2, invdet);\n    result->col3.vec128 = spu_mul(cof3, invdet);\n}\n\nstatic inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathTransform3 affineMat, tmpT3_0;\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathT3Inverse( &tmpT3_0, &affineMat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    VmathTransform3 affineMat, tmpT3_0;\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathT3OrthoInverse( &tmpT3_0, &affineMat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline float vmathM4Determinant( const VmathMatrix4 *mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 in0, in1, in2, in3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    vec_float4 cof0;\n    vec_float4 t0, t1, t2, t3;\n    vec_float4 t12, t23;\n    vec_float4 t1r, t2r;\n    vec_float4 t12r, t23r;\n    vec_float4 t1r3, t1r3r;\n    in0 = mat->col0.vec128;\n    in1 = mat->col1.vec128;\n    in2 = mat->col2.vec128;\n    in3 = mat->col3.vec128;\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC);    /* A E C G */\n    tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC);    /* I M K O */\n    tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD);    /* B F D H */\n    tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD);    /* J N L P */\n    t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB);    /* A E I M */\n    t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB);    /* J N B F */\n    t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD);    /* C G K O */\n    t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD);    /* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = spu_mul(t2, t3);                        /* CL GP KD OH */\n    t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ);     /* GP CL OH KD */\n    cof0 = spu_mul(t1, t23);                      /* JGP NCL BOH FKD */\n    t23r = spu_rlqwbyte(t23, 8);                  /* OH KD GP CL */\n    cof0 = spu_msub(t1, t23r, cof0);              /* JOH NKD BGP FCL  - cof0 */\n\n    t12 = spu_mul(t1, t2);                        /* JC NG BK FO */\n    t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ);     /* NG JC FO BK */\n    cof0 = spu_madd(t3, t12, cof0);               /* LNG PJC DFO HBK + cof0 */\n    t12r = spu_rlqwbyte(t12, 8);                  /* FO BK NG JC */\n    cof0 = spu_nmsub(t3, t12r, cof0);             /* cof0 - LFO PBK DNG HJC */\n    t1r = spu_rlqwbyte(t1, 8);                    /* B F J N */\n    t2r = spu_rlqwbyte(t2, 8);                    /* K O C G */\n    t1r3 = spu_mul(t1r, t3);                      /* BL FP JD NH */\n    t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ);  /* FP BL NH JD */\n    cof0 = spu_madd(t2r, t1r3, cof0);             /* KFP OBL CNH GJD + cof0 */\n    t1r3r = spu_rlqwbyte(t1r3, 8);                /* NH JD FP BL */\n    cof0 = spu_nmsub(t2r, t1r3r, cof0);           /* cof0 - KNH OJD CFP GBL */\n    return spu_extract( _vmathVfDot4(t0,cof0), 0 );\n}\n\nstatic inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4Add( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4Add( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4Sub( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4Sub( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4Neg( &result->col0, &mat->col0 );\n    vmathV4Neg( &result->col1, &mat->col1 );\n    vmathV4Neg( &result->col2, &mat->col2 );\n    vmathV4Neg( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathV4AbsPerElem( &result->col0, &mat->col0 );\n    vmathV4AbsPerElem( &result->col1, &mat->col1 );\n    vmathV4AbsPerElem( &result->col2, &mat->col2 );\n    vmathV4AbsPerElem( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar )\n{\n    vmathV4ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathV4ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathV4ScalarMul( &result->col2, &mat->col2, scalar );\n    vmathV4ScalarMul( &result->col3, &mat->col3, scalar );\n}\n\nstatic inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec )\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz, wwww;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx );\n    yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy );\n    zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz );\n    wwww = spu_shuffle( vec->vec128, vec->vec128, shuffle_wwww );\n    tmp0 = spu_mul( mat->col0.vec128, xxxx );\n    tmp1 = spu_mul( mat->col1.vec128, yyyy );\n    tmp0 = spu_madd( mat->col2.vec128, zzzz, tmp0 );\n    tmp1 = spu_madd( mat->col3.vec128, wwww, tmp1 );\n    res = spu_add( tmp0, tmp1 );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec )\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx );\n    yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy );\n    zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz );\n    res = spu_mul( mat->col0.vec128, xxxx );\n    res = spu_madd( mat->col1.vec128, yyyy, res );\n    res = spu_madd( mat->col2.vec128, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt )\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_xxxx );\n    yyyy = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_yyyy );\n    zzzz = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_zzzz );\n    tmp0 = spu_mul( mat->col0.vec128, xxxx );\n    tmp1 = spu_mul( mat->col1.vec128, yyyy );\n    tmp0 = spu_madd( mat->col2.vec128, zzzz, tmp0 );\n    tmp1 = spu_add( mat->col3.vec128, tmp1 );\n    res = spu_add( tmp0, tmp1 );\n    result->vec128 = res;\n}\n\nstatic inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    VmathMatrix4 tmpResult;\n    vmathM4MulV4( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathM4MulV4( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathM4MulV4( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathM4MulV4( &tmpResult.col3, mat0, &mat1->col3 );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm1 )\n{\n    VmathMatrix4 tmpResult;\n    VmathPoint3 tmpP3_0;\n    vmathM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 );\n    vmathM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 );\n    vmathM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 );\n    vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathM4MulP3( &tmpResult.col3, mat, &tmpP3_0 );\n    vmathM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 )\n{\n    vmathV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathM4MakeIdentity( VmathMatrix4 *result )\n{\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 )\n{\n    vmathV4SetXYZ( &result->col0, &mat3->col0 );\n    vmathV4SetXYZ( &result->col1, &mat3->col1 );\n    vmathV4SetXYZ( &result->col2, &mat3->col2 );\n}\n\nstatic inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat )\n{\n    vmathV4GetXYZ( &result->col0, &mat->col0 );\n    vmathV4GetXYZ( &result->col1, &mat->col1 );\n    vmathV4GetXYZ( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec )\n{\n    vmathV4SetXYZ( &result->col3, translateVec );\n}\n\nstatic inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat )\n{\n    vmathV4GetXYZ( result, &mat->col3 );\n}\n\nstatic inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res1 = spu_sel( zero, c, select_y );\n    res1 = spu_sel( res1, s, select_z );\n    res2 = spu_sel( zero, negatef4(s), select_y );\n    res2 = spu_sel( res2, c, select_z );\n    vmathV4MakeXAxis( &result->col0 );\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, negatef4(s), select_z );\n    res2 = spu_sel( zero, s, select_x );\n    res2 = spu_sel( res2, c, select_z );\n    result->col0.vec128 = res0;\n    vmathV4MakeYAxis( &result->col1 );\n    result->col2.vec128 = res2;\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, s, select_y );\n    res1 = spu_sel( zero, negatef4(s), select_x );\n    res1 = spu_sel( res1, c, select_y );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    angles = radiansXYZ->vec128;\n    angles = spu_insert( 0.0f, angles, 3 );\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 );\n    Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 );\n    Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 );\n    Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 );\n    X0 = spu_shuffle( s, s, shuffle_xxxx );\n    X1 = spu_shuffle( c, c, shuffle_xxxx );\n    tmp = spu_mul( Z0, Y1 );\n    result->col0.vec128 = spu_mul( Z0, Y0 );\n    result->col1.vec128 = spu_madd( Z1, X1, spu_mul( tmp, X0 ) );\n    result->col2.vec128 = spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    axis = unitVec->vec128;\n    sincosf4( spu_splats( radians ), &s, &c );\n    xxxx = spu_shuffle( axis, axis, shuffle_xxxx );\n    yyyy = spu_shuffle( axis, axis, shuffle_yyyy );\n    zzzz = spu_shuffle( axis, axis, shuffle_zzzz );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    axisS = spu_mul( axis, s );\n    negAxisS = negatef4( axisS );\n    tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 );\n    tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 );\n    tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 );\n    tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) );\n    tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) );\n    tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) );\n    zeroW = (vec_float4)spu_maskb(0x000f);\n    axis = spu_andc( axis, zeroW );\n    result->col0.vec128 = spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 );\n    result->col1.vec128 = spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 );\n    result->col2.vec128 = spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat )\n{\n    VmathTransform3 tmpT3_0;\n    vmathT3MakeRotationQ( &tmpT3_0, unitQuat );\n    vmathM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec )\n{\n    vec_float4 zero = spu_splats(0.0f);\n    result->col0.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0xf000) );\n    result->col1.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x0f00) );\n    result->col2.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x00f0) );\n    vmathV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec )\n{\n    vmathV4ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) );\n    vmathV4ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) );\n    vmathV4ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) );\n    vmathV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat )\n{\n    VmathVector4 scale4;\n    vmathV4MakeFromV3Scalar( &scale4, scaleVec, 1.0f );\n    vmathV4MulPerElem( &result->col0, &mat->col0, &scale4 );\n    vmathV4MulPerElem( &result->col1, &mat->col1, &scale4 );\n    vmathV4MulPerElem( &result->col2, &mat->col2, &scale4 );\n    vmathV4MulPerElem( &result->col3, &mat->col3, &scale4 );\n}\n\nstatic inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec )\n{\n    vmathV4MakeXAxis( &result->col0 );\n    vmathV4MakeYAxis( &result->col1 );\n    vmathV4MakeZAxis( &result->col2 );\n    vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f );\n}\n\nstatic inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec )\n{\n    VmathMatrix4 m4EyeFrame;\n    VmathVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1;\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathV3Normalize( &v3Y, upVec );\n    vmathP3Sub( &tmpV3_0, eyePos, lookAtPos );\n    vmathV3Normalize( &v3Z, &tmpV3_0 );\n    vmathV3Cross( &tmpV3_1, &v3Y, &v3Z );\n    vmathV3Normalize( &v3X, &tmpV3_1 );\n    vmathV3Cross( &v3Y, &v3Z, &v3X );\n    vmathV4MakeFromV3( &tmpV4_0, &v3X );\n    vmathV4MakeFromV3( &tmpV4_1, &v3Y );\n    vmathV4MakeFromV3( &tmpV4_2, &v3Z );\n    vmathV4MakeFromP3( &tmpV4_3, eyePos );\n    vmathM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 );\n    vmathM4OrthoInverse( result, &m4EyeFrame );\n}\n\nstatic inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    vec_float4 zero, col0, col1, col2, col3;\n    f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f );\n    rangeInv = 1.0f / ( zNear - zFar );\n    zero = spu_splats(0.0f);\n    col0 = zero;\n    col1 = zero;\n    col2 = zero;\n    col3 = zero;\n    col0 = spu_insert( f / aspect, col0, 0 );\n    col1 = spu_insert( f, col1, 1 );\n    col2 = spu_insert( ( zNear + zFar ) * rangeInv, col2, 2 );\n    col2 = spu_insert( -1.0f, col2, 3 );\n    col3 = spu_insert( zNear * zFar * rangeInv * 2.0f, col3, 2 );\n    result->col0.vec128 = col0;\n    result->col1.vec128 = col1;\n    result->col2.vec128 = col2;\n    result->col3.vec128 = col3;\n}\n\nstatic inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff;\n    vec_float4 diagonal, column, near2;\n    vec_float4 zero = spu_splats(0.0f);\n    lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB );\n    lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB );\n    diff = spu_sub( rtn, lbf );\n    sum  = spu_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    near2 = spu_splats( zNear );\n    near2 = spu_add( near2, near2 );\n    diagonal = spu_mul( near2, inv_diff );\n    column = spu_mul( sum, inv_diff );\n    result->col0.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) );\n    result->col1.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) );\n    result->col2.vec128 = spu_sel( column, spu_splats(-1.0f), (vec_uint4)spu_maskb(0x000f) );\n    result->col3.vec128 = spu_sel( zero, spu_mul( diagonal, spu_splats(zFar) ), (vec_uint4)spu_maskb(0x00f0) );\n}\n\nstatic inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff, neg_inv_diff;\n    vec_float4 diagonal, column;\n    vec_float4 zero = spu_splats(0.0f);\n    lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB );\n    lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB );\n    diff = spu_sub( rtn, lbf );\n    sum  = spu_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    neg_inv_diff = negatef4( inv_diff );\n    diagonal = spu_add( inv_diff, inv_diff );\n    column = spu_mul( sum, spu_sel( neg_inv_diff, inv_diff, (vec_uint4)spu_maskb(0x00f0) ) );\n    result->col0.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) );\n    result->col1.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) );\n    result->col2.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x00f0) );\n    result->col3.vec128 = spu_sel( column, spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) );\n}\n\nstatic inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 )\n{\n    vmathV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n    vmathV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM4Print( const VmathMatrix4 *mat )\n{\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathM4GetRow( &tmpV4_0, mat, 0 );\n    vmathV4Print( &tmpV4_0 );\n    vmathM4GetRow( &tmpV4_1, mat, 1 );\n    vmathV4Print( &tmpV4_1 );\n    vmathM4GetRow( &tmpV4_2, mat, 2 );\n    vmathV4Print( &tmpV4_2 );\n    vmathM4GetRow( &tmpV4_3, mat, 3 );\n    vmathV4Print( &tmpV4_3 );\n}\n\nstatic inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathM4Print( mat );\n}\n\n#endif\n\nstatic inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( &result->col0, &tfrm->col0 );\n    vmathV3Copy( &result->col1, &tfrm->col1 );\n    vmathV3Copy( &result->col2, &tfrm->col2 );\n    vmathV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar )\n{\n    vmathV3MakeFromScalar( &result->col0, scalar );\n    vmathV3MakeFromScalar( &result->col1, scalar );\n    vmathV3MakeFromScalar( &result->col2, scalar );\n    vmathV3MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2, const VmathVector3 *_col3 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n    vmathV3Copy( &result->col1, _col1 );\n    vmathV3Copy( &result->col2, _col2 );\n    vmathV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec )\n{\n    vmathT3SetUpper3x3( result, tfrm );\n    vmathT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec )\n{\n    VmathMatrix3 tmpM3_0;\n    vmathM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathT3SetUpper3x3( result, &tmpM3_0 );\n    vmathT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *_col0 )\n{\n    vmathV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *_col1 )\n{\n    vmathV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *_col2 )\n{\n    vmathV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *_col3 )\n{\n    vmathV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec )\n{\n    vmathV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec )\n{\n    vmathV3SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) );\n    vmathV3SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) );\n    vmathV3SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) );\n    vmathV3SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val )\n{\n    VmathVector3 tmpV3_0;\n    vmathT3GetCol( &tmpV3_0, result, col );\n    vmathV3SetElem( &tmpV3_0, row, val );\n    vmathT3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row )\n{\n    VmathVector3 tmpV3_0;\n    vmathT3GetCol( &tmpV3_0, tfrm, col );\n    return vmathV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col0 );\n}\n\nstatic inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col1 );\n}\n\nstatic inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col2 );\n}\n\nstatic inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col )\n{\n    vmathV3Copy( result, (&tfrm->col0 + col) );\n}\n\nstatic inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row )\n{\n    vmathV4MakeFromElems( result, vmathV3GetElem( &tfrm->col0, row ), vmathV3GetElem( &tfrm->col1, row ), vmathV3GetElem( &tfrm->col2, row ), vmathV3GetElem( &tfrm->col3, row ) );\n}\n\nstatic inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    tmp2 = _vmathVfCross( tfrm->col0.vec128, tfrm->col1.vec128 );\n    tmp0 = _vmathVfCross( tfrm->col1.vec128, tfrm->col2.vec128 );\n    tmp1 = _vmathVfCross( tfrm->col2.vec128, tfrm->col0.vec128 );\n    inv3 = negatef4( tfrm->col3.vec128 );\n    dot = _vmathVfDot3( tmp2, tfrm->col2.vec128 );\n    dot = spu_shuffle( dot, dot, shuffle_xxxx );\n    invdet = recipf4( dot );\n    tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB );\n    tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD );\n    inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB );\n    xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx );\n    inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 );\n    inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 );\n    yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy );\n    zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz );\n    inv3 = spu_mul( inv0, xxxx );\n    inv3 = spu_madd( inv1, yyyy, inv3 );\n    inv3 = spu_madd( inv2, zzzz, inv3 );\n    inv0 = spu_mul( inv0, invdet );\n    inv1 = spu_mul( inv1, invdet );\n    inv2 = spu_mul( inv2, invdet );\n    inv3 = spu_mul( inv3, invdet );\n    result->col0.vec128 = inv0;\n    result->col1.vec128 = inv1;\n    result->col2.vec128 = inv2;\n    result->col3.vec128 = inv3;\n}\n\nstatic inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    tmp0 = spu_shuffle( tfrm->col0.vec128, tfrm->col2.vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( tfrm->col0.vec128, tfrm->col2.vec128, _VECTORMATH_SHUF_ZCWD );\n    inv3 = negatef4( tfrm->col3.vec128 );\n    inv0 = spu_shuffle( tmp0, tfrm->col1.vec128, _VECTORMATH_SHUF_XAYB );\n    xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx );\n    inv1 = spu_shuffle( tmp0, tfrm->col1.vec128, _VECTORMATH_SHUF_ZBW0 );\n    inv2 = spu_shuffle( tmp1, tfrm->col1.vec128, _VECTORMATH_SHUF_XCY0 );\n    yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy );\n    zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz );\n    inv3 = spu_mul( inv0, xxxx );\n    inv3 = spu_madd( inv1, yyyy, inv3 );\n    inv3 = spu_madd( inv2, zzzz, inv3 );\n    result->col0.vec128 = inv0;\n    result->col1.vec128 = inv1;\n    result->col2.vec128 = inv2;\n    result->col3.vec128 = inv3;\n}\n\nstatic inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3AbsPerElem( &result->col0, &tfrm->col0 );\n    vmathV3AbsPerElem( &result->col1, &tfrm->col1 );\n    vmathV3AbsPerElem( &result->col2, &tfrm->col2 );\n    vmathV3AbsPerElem( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec )\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx );\n    yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy );\n    zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz );\n    res = spu_mul( tfrm->col0.vec128, xxxx );\n    res = spu_madd( tfrm->col1.vec128, yyyy, res );\n    res = spu_madd( tfrm->col2.vec128, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt )\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_xxxx );\n    yyyy = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_yyyy );\n    zzzz = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_zzzz );\n    tmp0 = spu_mul( tfrm->col0.vec128, xxxx );\n    tmp1 = spu_mul( tfrm->col1.vec128, yyyy );\n    tmp0 = spu_madd( tfrm->col2.vec128, zzzz, tmp0 );\n    tmp1 = spu_add( tfrm->col3.vec128, tmp1 );\n    res = spu_add( tmp0, tmp1 );\n    result->vec128 = res;\n}\n\nstatic inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 )\n{\n    VmathTransform3 tmpResult;\n    VmathPoint3 tmpP3_0, tmpP3_1;\n    vmathT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 );\n    vmathT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 );\n    vmathT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 );\n    vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 );\n    vmathV3MakeFromP3( &tmpResult.col3, &tmpP3_1 );\n    vmathT3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 )\n{\n    vmathV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 );\n    vmathV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 );\n    vmathV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 );\n    vmathV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 );\n}\n\nstatic inline void vmathT3MakeIdentity( VmathTransform3 *result )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *tfrm )\n{\n    vmathV3Copy( &result->col0, &tfrm->col0 );\n    vmathV3Copy( &result->col1, &tfrm->col1 );\n    vmathV3Copy( &result->col2, &tfrm->col2 );\n}\n\nstatic inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm )\n{\n    vmathM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 );\n}\n\nstatic inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec )\n{\n    vmathV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm )\n{\n    vmathV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res1 = spu_sel( zero, c, select_y );\n    res1 = spu_sel( res1, s, select_z );\n    res2 = spu_sel( zero, negatef4(s), select_y );\n    res2 = spu_sel( res2, c, select_z );\n    vmathV3MakeXAxis( &result->col0 );\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, negatef4(s), select_z );\n    res2 = spu_sel( zero, s, select_x );\n    res2 = spu_sel( res2, c, select_z );\n    result->col0.vec128 = res0;\n    vmathV3MakeYAxis( &result->col1 );\n    result->col2.vec128 = res2;\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, s, select_y );\n    res1 = spu_sel( zero, negatef4(s), select_x );\n    res1 = spu_sel( res1, c, select_y );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    angles = radiansXYZ->vec128;\n    angles = spu_insert( 0.0f, angles, 3 );\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 );\n    Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 );\n    Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 );\n    Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 );\n    X0 = spu_shuffle( s, s, shuffle_xxxx );\n    X1 = spu_shuffle( c, c, shuffle_xxxx );\n    tmp = spu_mul( Z0, Y1 );\n    result->col0.vec128 = spu_mul( Z0, Y0 );\n    result->col1.vec128 = spu_madd( Z1, X1, spu_mul( tmp, X0 ) );\n    result->col2.vec128 = spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec )\n{\n    VmathMatrix3 tmpM3_0;\n    VmathVector3 tmpV3_0;\n    vmathM3MakeRotationAxis( &tmpM3_0, radians, unitVec );\n    vmathV3MakeFromScalar( &tmpV3_0, 0.0f );\n    vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat )\n{\n    VmathMatrix3 tmpM3_0;\n    VmathVector3 tmpV3_0;\n    vmathM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathV3MakeFromScalar( &tmpV3_0, 0.0f );\n    vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec )\n{\n    vec_float4 zero = spu_splats(0.0f);\n    result->col0.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0xf000) );\n    result->col1.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x0f00) );\n    result->col2.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x00f0) );\n    vmathV3MakeFromScalar( &result->col3, 0.0f );\n}\n\nstatic inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec )\n{\n    vmathV3ScalarMul( &result->col0, &tfrm->col0, vmathV3GetX( scaleVec ) );\n    vmathV3ScalarMul( &result->col1, &tfrm->col1, vmathV3GetY( scaleVec ) );\n    vmathV3ScalarMul( &result->col2, &tfrm->col2, vmathV3GetZ( scaleVec ) );\n    vmathV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm )\n{\n    vmathV3MulPerElem( &result->col0, &tfrm->col0, scaleVec );\n    vmathV3MulPerElem( &result->col1, &tfrm->col1, scaleVec );\n    vmathV3MulPerElem( &result->col2, &tfrm->col2, scaleVec );\n    vmathV3MulPerElem( &result->col3, &tfrm->col3, scaleVec );\n}\n\nstatic inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec )\n{\n    vmathV3MakeXAxis( &result->col0 );\n    vmathV3MakeYAxis( &result->col1 );\n    vmathV3MakeZAxis( &result->col2 );\n    vmathV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 )\n{\n    vmathV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 );\n    vmathV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 );\n    vmathV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 );\n    vmathV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathT3Print( const VmathTransform3 *tfrm )\n{\n    VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2;\n    vmathT3GetRow( &tmpV4_0, tfrm, 0 );\n    vmathV4Print( &tmpV4_0 );\n    vmathT3GetRow( &tmpV4_1, tfrm, 1 );\n    vmathV4Print( &tmpV4_1 );\n    vmathT3GetRow( &tmpV4_2, tfrm, 2 );\n    vmathV4Print( &tmpV4_2 );\n}\n\nstatic inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathT3Print( tfrm );\n}\n\n#endif\n\nstatic inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *tfrm )\n{\n    vec_float4 res;\n    vec_float4 col0, col1, col2;\n    vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff;\n    vec_float4 zy_xz_yx, yz_zx_xy, sum, diff;\n    vec_float4 radicand, invSqrt, scale;\n    vec_float4 res0, res1, res2, res3;\n    vec_float4 xx, yy, zz;\n    vec_uint4 select_x = (vec_uint4)spu_maskb( 0xf000 );\n    vec_uint4 select_y = (vec_uint4)spu_maskb( 0x0f00 );\n    vec_uint4 select_z = (vec_uint4)spu_maskb( 0x00f0 );\n    vec_uint4 select_w = (vec_uint4)spu_maskb( 0x000f );\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((unsigned int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((unsigned int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((unsigned int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((unsigned int)0x0c0d0e0f);\n\n    col0 = tfrm->col0.vec128;\n    col1 = tfrm->col1.vec128;\n    col2 = tfrm->col2.vec128;\n\n    /* four cases: */\n    /* trace > 0 */\n    /* else */\n    /*    xx largest diagonal element */\n    /*    yy largest diagonal element */\n    /*    zz largest diagonal element */\n\n    /* compute quaternion for each case */\n\n    xx_yy = spu_sel( col0, col1, select_y );\n    xx_yy_zz_xx = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_XYCX );\n    yy_zz_xx_yy = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_YCXY );\n    zz_xx_yy_zz = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_CXYC );\n\n    diagSum = spu_add( spu_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    diagDiff = spu_sub( spu_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    radicand = spu_add( spu_sel( diagDiff, diagSum, select_w ), spu_splats(1.0f) );\n    invSqrt = rsqrtf4( radicand );\n\n    zy_xz_yx = spu_sel( col0, col1, select_z );\n    zy_xz_yx = spu_shuffle( zy_xz_yx, col2, _VECTORMATH_SHUF_ZAY0 );\n    yz_zx_xy = spu_sel( col0, col1, select_x );\n    yz_zx_xy = spu_shuffle( yz_zx_xy, col2, _VECTORMATH_SHUF_BZX0 );\n\n    sum = spu_add( zy_xz_yx, yz_zx_xy );\n    diff = spu_sub( zy_xz_yx, yz_zx_xy );\n\n    scale = spu_mul( invSqrt, spu_splats(0.5f) );\n    res0 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_0ZYA );\n    res1 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_Z0XB );\n    res2 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_YX0C );\n    res3 = diff;\n    res0 = spu_sel( res0, radicand, select_x );\n    res1 = spu_sel( res1, radicand, select_y );\n    res2 = spu_sel( res2, radicand, select_z );\n    res3 = spu_sel( res3, radicand, select_w );\n    res0 = spu_mul( res0, spu_shuffle( scale, scale, shuffle_xxxx ) );\n    res1 = spu_mul( res1, spu_shuffle( scale, scale, shuffle_yyyy ) );\n    res2 = spu_mul( res2, spu_shuffle( scale, scale, shuffle_zzzz ) );\n    res3 = spu_mul( res3, spu_shuffle( scale, scale, shuffle_wwww ) );\n\n    /* determine case and select answer */\n\n    xx = spu_shuffle( col0, col0, shuffle_xxxx );\n    yy = spu_shuffle( col1, col1, shuffle_yyyy );\n    zz = spu_shuffle( col2, col2, shuffle_zzzz );\n    res = spu_sel( res0, res1, spu_cmpgt( yy, xx ) );\n    res = spu_sel( res, res2, spu_and( spu_cmpgt( zz, xx ), spu_cmpgt( zz, yy ) ) );\n    res = spu_sel( res, res3, spu_cmpgt( spu_shuffle( diagSum, diagSum, shuffle_xxxx ), spu_splats(0.0f) ) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *tfrm0, const VmathVector3 *tfrm1 )\n{\n    vmathV3ScalarMul( &result->col0, tfrm0, vmathV3GetX( tfrm1 ) );\n    vmathV3ScalarMul( &result->col1, tfrm0, vmathV3GetY( tfrm1 ) );\n    vmathV3ScalarMul( &result->col2, tfrm0, vmathV3GetZ( tfrm1 ) );\n}\n\nstatic inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *tfrm0, const VmathVector4 *tfrm1 )\n{\n    vmathV4ScalarMul( &result->col0, tfrm0, vmathV4GetX( tfrm1 ) );\n    vmathV4ScalarMul( &result->col1, tfrm0, vmathV4GetY( tfrm1 ) );\n    vmathV4ScalarMul( &result->col2, tfrm0, vmathV4GetZ( tfrm1 ) );\n    vmathV4ScalarMul( &result->col3, tfrm0, vmathV4GetW( tfrm1 ) );\n}\n\nstatic inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat )\n{\n    vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    tmp0 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_ZCWD );\n    xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx );\n    mcol0 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_XAYB );\n    mcol1 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_ZBW0 );\n    mcol2 = spu_shuffle( tmp1, mat->col1.vec128, _VECTORMATH_SHUF_XCY0 );\n    yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy );\n    res = spu_mul( mcol0, xxxx );\n    zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz );\n    res = spu_madd( mcol1, yyyy, res );\n    res = spu_madd( mcol2, zzzz, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec )\n{\n    vec_float4 neg, res0, res1, res2;\n    neg = negatef4( vec->vec128 );\n    res0 = spu_shuffle( vec->vec128, neg, _VECTORMATH_SHUF_0ZB0 );\n    res1 = spu_shuffle( vec->vec128, neg, _VECTORMATH_SHUF_C0X0 );\n    res2 = spu_shuffle( vec->vec128, neg, _VECTORMATH_SHUF_YA00 );\n    result->col0.vec128 = res0;\n    result->col1.vec128 = res1;\n    result->col2.vec128 = res2;\n}\n\nstatic inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat )\n{\n    VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathV3Cross( &tmpV3_0, vec, &mat->col0 );\n    vmathV3Cross( &tmpV3_1, vec, &mat->col1 );\n    vmathV3Cross( &tmpV3_2, vec, &mat->col2 );\n    vmathM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 );\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/mat_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_V_C_H\n#define _VECTORMATH_MAT_AOS_V_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_0ZB0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_0 })     \n#define _VECTORMATH_SHUF_C0X0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_YA00 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_Z })\n#define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X })\n#define _VECTORMATH_SHUF_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y })\n#define _VECTORMATH_SHUF_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZAY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_BZX0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_0ZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A })\n#define _VECTORMATH_SHUF_Z0XB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YX0C ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_CZD0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_BBY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2 )\n{\n    VmathMatrix3 result;\n    vmathM3MakeFromCols(&result, &_col0, &_col1, &_col2);\n    return result;\n}\n\nstatic inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 _col0 )\n{\n    vmathM3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 _col1 )\n{\n    vmathM3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 _col2 )\n{\n    vmathM3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec )\n{\n    vmathM3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec )\n{\n    vmathM3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val )\n{\n    vmathM3SetElem(result, col, row, val);\n}\n\nstatic inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row )\n{\n    return vmathM3GetElem(&mat, col, row);\n}\n\nstatic inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathM3GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col )\n{\n    VmathVector3 result;\n    vmathM3GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row )\n{\n    VmathVector3 result;\n    vmathM3GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline float vmathM3Determinant_V( VmathMatrix3 mat )\n{\n    return vmathM3Determinant(&mat);\n}\n\nstatic inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar )\n{\n    VmathMatrix3 result;\n    vmathM3ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathM3MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 )\n{\n    VmathMatrix3 result;\n    vmathM3MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeIdentity_V( )\n{\n    VmathMatrix3 result;\n    vmathM3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationX_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationY_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix3 result;\n    vmathM3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathMatrix3 result;\n    vmathM3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec )\n{\n    VmathMatrix3 result;\n    vmathM3AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathM3PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 )\n{\n    VmathMatrix3 result;\n    vmathM3Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM3Print_V( VmathMatrix3 mat )\n{\n    vmathM3Print(&mat);\n}\n\nstatic inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name )\n{\n    vmathM3Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromT3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 _col0, VmathVector4 _col1, VmathVector4 _col2, VmathVector4 _col3 )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromM3V3(&result, &mat, &translateVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 _col0 )\n{\n    vmathM4SetCol0(result, &_col0);\n}\n\nstatic inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 _col1 )\n{\n    vmathM4SetCol1(result, &_col1);\n}\n\nstatic inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 _col2 )\n{\n    vmathM4SetCol2(result, &_col2);\n}\n\nstatic inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 _col3 )\n{\n    vmathM4SetCol3(result, &_col3);\n}\n\nstatic inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec )\n{\n    vmathM4SetCol(result, col, &vec);\n}\n\nstatic inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec )\n{\n    vmathM4SetRow(result, row, &vec);\n}\n\nstatic inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val )\n{\n    vmathM4SetElem(result, col, row, val);\n}\n\nstatic inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row )\n{\n    return vmathM4GetElem(&mat, col, row);\n}\n\nstatic inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat )\n{\n    VmathVector4 result;\n    vmathM4GetCol3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col )\n{\n    VmathVector4 result;\n    vmathM4GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row )\n{\n    VmathVector4 result;\n    vmathM4GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4AffineInverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4OrthoInverse(&result, &mat);\n    return result;\n}\n\nstatic inline float vmathM4Determinant_V( VmathMatrix4 mat )\n{\n    return vmathM4Determinant(&mat);\n}\n\nstatic inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar )\n{\n    VmathMatrix4 result;\n    vmathM4ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathM4MulV4(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec )\n{\n    VmathVector4 result;\n    vmathM4MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt )\n{\n    VmathVector4 result;\n    vmathM4MulP3(&result, &mat, &pnt);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm1 )\n{\n    VmathMatrix4 result;\n    vmathM4MulT3(&result, &mat, &tfrm1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 )\n{\n    VmathMatrix4 result;\n    vmathM4MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeIdentity_V( )\n{\n    VmathMatrix4 result;\n    vmathM4MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 )\n{\n    vmathM4SetUpper3x3(result, &mat3);\n}\n\nstatic inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat )\n{\n    VmathMatrix3 result;\n    vmathM4GetUpper3x3(&result, &mat);\n    return result;\n}\n\nstatic inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec )\n{\n    vmathM4SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat )\n{\n    VmathVector3 result;\n    vmathM4GetTranslation(&result, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationX_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationY_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathMatrix4 result;\n    vmathM4MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec )\n{\n    VmathMatrix4 result;\n    vmathM4AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat )\n{\n    VmathMatrix4 result;\n    vmathM4PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec )\n{\n    VmathMatrix4 result;\n    vmathM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    VmathMatrix4 result;\n    vmathM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 )\n{\n    VmathMatrix4 result;\n    vmathM4Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathM4Print_V( VmathMatrix4 mat )\n{\n    vmathM4Print(&mat);\n}\n\nstatic inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name )\n{\n    vmathM4Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2, VmathVector3 _col3 )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromM3V3(&result, &tfrm, &translateVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 _col0 )\n{\n    vmathT3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 _col1 )\n{\n    vmathT3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 _col2 )\n{\n    vmathT3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 _col3 )\n{\n    vmathT3SetCol3(result, &_col3);\n}\n\nstatic inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec )\n{\n    vmathT3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec )\n{\n    vmathT3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val )\n{\n    vmathT3SetElem(result, col, row, val);\n}\n\nstatic inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row )\n{\n    return vmathT3GetElem(&tfrm, col, row);\n}\n\nstatic inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol0(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol1(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol2(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetCol3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col )\n{\n    VmathVector3 result;\n    vmathT3GetCol(&result, &tfrm, col);\n    return result;\n}\n\nstatic inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row )\n{\n    VmathVector4 result;\n    vmathT3GetRow(&result, &tfrm, row);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3Inverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3OrthoInverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3AbsPerElem(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathT3MulV3(&result, &tfrm, &vec);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathT3MulP3(&result, &tfrm, &pnt);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 )\n{\n    VmathTransform3 result;\n    vmathT3Mul(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 )\n{\n    VmathTransform3 result;\n    vmathT3MulPerElem(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeIdentity_V( )\n{\n    VmathTransform3 result;\n    vmathT3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 tfrm )\n{\n    vmathT3SetUpper3x3(result, &tfrm);\n}\n\nstatic inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm )\n{\n    VmathMatrix3 result;\n    vmathT3GetUpper3x3(&result, &tfrm);\n    return result;\n}\n\nstatic inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec )\n{\n    vmathT3SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm )\n{\n    VmathVector3 result;\n    vmathT3GetTranslation(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationX_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationY_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationZ_V( float radians )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat )\n{\n    VmathTransform3 result;\n    vmathT3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec )\n{\n    VmathTransform3 result;\n    vmathT3AppendScale(&result, &tfrm, &scaleVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm )\n{\n    VmathTransform3 result;\n    vmathT3PrependScale(&result, &scaleVec, &tfrm);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec )\n{\n    VmathTransform3 result;\n    vmathT3MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 )\n{\n    VmathTransform3 result;\n    vmathT3Select(&result, &tfrm0, &tfrm1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathT3Print_V( VmathTransform3 tfrm )\n{\n    vmathT3Print(&tfrm);\n}\n\nstatic inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name )\n{\n    vmathT3Prints(&tfrm, name);\n}\n\n#endif\n\nstatic inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 tfrm )\n{\n    VmathQuat result;\n    vmathQMakeFromM3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3Outer_V( VmathVector3 tfrm0, VmathVector3 tfrm1 )\n{\n    VmathMatrix3 result;\n    vmathV3Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathMatrix4 vmathV4Outer_V( VmathVector4 tfrm0, VmathVector4 tfrm1 )\n{\n    VmathMatrix4 result;\n    vmathV4Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat )\n{\n    VmathVector3 result;\n    vmathV3RowMul(&result, &vec, &mat);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec )\n{\n    VmathMatrix3 result;\n    vmathV3CrossMatrix(&result, &vec);\n    return result;\n}\n\nstatic inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat )\n{\n    VmathMatrix3 result;\n    vmathV3CrossMatrixMul(&result, &vec, &mat);\n    return result;\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/mat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_SOA_C_H\n#define _VECTORMATH_MAT_SOA_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( &result->col0, &mat->col0 );\n    vmathSoaV3Copy( &result->col1, &mat->col1 );\n    vmathSoaV3Copy( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar )\n{\n    vmathSoaV3MakeFromScalar( &result->col0, scalar );\n    vmathSoaV3MakeFromScalar( &result->col1, scalar );\n    vmathSoaV3MakeFromScalar( &result->col2, scalar );\n}\n\nstatic inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat )\n{\n    vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2;\n    qx = unitQuat->x;\n    qy = unitQuat->y;\n    qz = unitQuat->z;\n    qw = unitQuat->w;\n    qx2 = spu_add( qx, qx );\n    qy2 = spu_add( qy, qy );\n    qz2 = spu_add( qz, qz );\n    qxqx2 = spu_mul( qx, qx2 );\n    qxqy2 = spu_mul( qx, qy2 );\n    qxqz2 = spu_mul( qx, qz2 );\n    qxqw2 = spu_mul( qw, qx2 );\n    qyqy2 = spu_mul( qy, qy2 );\n    qyqz2 = spu_mul( qy, qz2 );\n    qyqw2 = spu_mul( qw, qy2 );\n    qzqz2 = spu_mul( qz, qz2 );\n    qzqw2 = spu_mul( qw, qz2 );\n    vmathSoaV3MakeFromElems( &result->col0, spu_sub( spu_sub( spu_splats(1.0f), qyqy2 ), qzqz2 ), spu_add( qxqy2, qzqw2 ), spu_sub( qxqz2, qyqw2 ) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_sub( qxqy2, qzqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qzqz2 ), spu_add( qyqz2, qxqw2 ) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_add( qxqz2, qyqw2 ), spu_sub( qyqz2, qxqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qyqy2 ) );\n}\n\nstatic inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n    vmathSoaV3Copy( &result->col1, _col1 );\n    vmathSoaV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat )\n{\n    vmathSoaV3MakeFromAos( &result->col0, &mat->col0 );\n    vmathSoaV3MakeFromAos( &result->col1, &mat->col1 );\n    vmathSoaV3MakeFromAos( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 )\n{\n    vmathSoaV3MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 );\n    vmathSoaV3MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 );\n    vmathSoaV3MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 );\n}\n\nstatic inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 )\n{\n    vmathSoaV3Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 );\n    vmathSoaV3Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 );\n    vmathSoaV3Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 );\n}\n\nstatic inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col1 )\n{\n    vmathSoaV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col2 )\n{\n    vmathSoaV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3SetElem( &result->col0, row, vmathSoaV3GetElem( vec, 0 ) );\n    vmathSoaV3SetElem( &result->col1, row, vmathSoaV3GetElem( vec, 1 ) );\n    vmathSoaV3SetElem( &result->col2, row, vmathSoaV3GetElem( vec, 2 ) );\n}\n\nstatic inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3GetCol( &tmpV3_0, result, col );\n    vmathSoaV3SetElem( &tmpV3_0, row, val );\n    vmathSoaM3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3GetCol( &tmpV3_0, mat, col );\n    return vmathSoaV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col )\n{\n    vmathSoaV3Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row )\n{\n    vmathSoaV3MakeFromElems( result, vmathSoaV3GetElem( &mat->col0, row ), vmathSoaV3GetElem( &mat->col1, row ), vmathSoaV3GetElem( &mat->col2, row ) );\n}\n\nstatic inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    VmathSoaMatrix3 tmpResult;\n    vmathSoaV3MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x );\n    vmathSoaV3MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y );\n    vmathSoaV3MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z );\n    vmathSoaM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    VmathSoaVector3 tmp0, tmp1, tmp2;\n    vec_float4 detinv;\n    vmathSoaV3Cross( &tmp0, &mat->col1, &mat->col2 );\n    vmathSoaV3Cross( &tmp1, &mat->col2, &mat->col0 );\n    vmathSoaV3Cross( &tmp2, &mat->col0, &mat->col1 );\n    detinv = recipf4( vmathSoaV3Dot( &mat->col2, &tmp2 ) );\n    vmathSoaV3MakeFromElems( &result->col0, spu_mul( tmp0.x, detinv ), spu_mul( tmp1.x, detinv ), spu_mul( tmp2.x, detinv ) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_mul( tmp0.y, detinv ), spu_mul( tmp1.y, detinv ), spu_mul( tmp2.y, detinv ) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_mul( tmp0.z, detinv ), spu_mul( tmp1.z, detinv ), spu_mul( tmp2.z, detinv ) );\n}\n\nstatic inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaV3Cross( &tmpV3_0, &mat->col0, &mat->col1 );\n    return vmathSoaV3Dot( &mat->col2, &tmpV3_0 );\n}\n\nstatic inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    vmathSoaV3Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV3Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV3Add( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    vmathSoaV3Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV3Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV3Sub( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3Neg( &result->col0, &mat->col0 );\n    vmathSoaV3Neg( &result->col1, &mat->col1 );\n    vmathSoaV3Neg( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3AbsPerElem( &result->col0, &mat->col0 );\n    vmathSoaV3AbsPerElem( &result->col1, &mat->col1 );\n    vmathSoaV3AbsPerElem( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar )\n{\n    vmathSoaV3ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathSoaV3ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathSoaV3ScalarMul( &result->col2, &mat->col2, scalar );\n}\n\nstatic inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = spu_add( spu_add( spu_mul( mat->col0.x, vec->x ), spu_mul( mat->col1.x, vec->y ) ), spu_mul( mat->col2.x, vec->z ) );\n    tmpY = spu_add( spu_add( spu_mul( mat->col0.y, vec->x ), spu_mul( mat->col1.y, vec->y ) ), spu_mul( mat->col2.y, vec->z ) );\n    tmpZ = spu_add( spu_add( spu_mul( mat->col0.z, vec->x ), spu_mul( mat->col1.z, vec->y ) ), spu_mul( mat->col2.z, vec->z ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    VmathSoaMatrix3 tmpResult;\n    vmathSoaM3MulV3( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathSoaM3MulV3( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathSoaM3MulV3( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathSoaM3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 )\n{\n    vmathSoaV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n}\n\nstatic inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result )\n{\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), c, s );\n    vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), negatef4( s ), c );\n}\n\nstatic inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, spu_splats(0.0f), negatef4( s ) );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeFromElems( &result->col2, s, spu_splats(0.0f), c );\n}\n\nstatic inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, s, spu_splats(0.0f) );\n    vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, spu_splats(0.0f) );\n    vmathSoaV3MakeZAxis( &result->col2 );\n}\n\nstatic inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ->x, &sX, &cX );\n    sincosf4( radiansXYZ->y, &sY, &cY );\n    sincosf4( radiansXYZ->z, &sZ, &cZ );\n    tmp0 = spu_mul( cZ, sY );\n    tmp1 = spu_mul( sZ, sY );\n    vmathSoaV3MakeFromElems( &result->col0, spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_sub( spu_mul( tmp0, sX ), spu_mul( sZ, cX ) ), spu_add( spu_mul( tmp1, sX ), spu_mul( cZ, cX ) ), spu_mul( cY, sX ) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_add( spu_mul( tmp0, cX ), spu_mul( sZ, sX ) ), spu_sub( spu_mul( tmp1, cX ), spu_mul( cZ, sX ) ), spu_mul( cY, cX ) );\n}\n\nstatic inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec->x;\n    y = unitVec->y;\n    z = unitVec->z;\n    xy = spu_mul( x, y );\n    yz = spu_mul( y, z );\n    zx = spu_mul( z, x );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    vmathSoaV3MakeFromElems( &result->col0, spu_add( spu_mul( spu_mul( x, x ), oneMinusC ), c ), spu_add( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_sub( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_sub( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_add( spu_mul( spu_mul( y, y ), oneMinusC ), c ), spu_add( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_add( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ), spu_sub( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ), spu_add( spu_mul( spu_mul( z, z ), oneMinusC ), c ) );\n}\n\nstatic inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat )\n{\n    vmathSoaM3MakeFromQ( result, unitQuat );\n}\n\nstatic inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3MakeFromElems( &result->col0, scaleVec->x, spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), scaleVec->y, spu_splats(0.0f) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), scaleVec->z );\n}\n\nstatic inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) );\n}\n\nstatic inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat )\n{\n    vmathSoaV3MulPerElem( &result->col0, &mat->col0, scaleVec );\n    vmathSoaV3MulPerElem( &result->col1, &mat->col1, scaleVec );\n    vmathSoaV3MulPerElem( &result->col2, &mat->col2, scaleVec );\n}\n\nstatic inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 )\n{\n    vmathSoaV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathSoaV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathSoaV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat )\n{\n    VmathMatrix3 mat0, mat1, mat2, mat3;\n    vmathSoaM3Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 );\n    printf(\"slot 0:\\n\");\n    vmathM3Print( &mat0 );\n    printf(\"slot 1:\\n\");\n    vmathM3Print( &mat1 );\n    printf(\"slot 2:\\n\");\n    vmathM3Print( &mat2 );\n    printf(\"slot 3:\\n\");\n    vmathM3Print( &mat3 );\n}\n\nstatic inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathSoaM3Print( mat );\n}\n\n#endif\n\nstatic inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( &result->col0, &mat->col0 );\n    vmathSoaV4Copy( &result->col1, &mat->col1 );\n    vmathSoaV4Copy( &result->col2, &mat->col2 );\n    vmathSoaV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar )\n{\n    vmathSoaV4MakeFromScalar( &result->col0, scalar );\n    vmathSoaV4MakeFromScalar( &result->col1, scalar );\n    vmathSoaV4MakeFromScalar( &result->col2, scalar );\n    vmathSoaV4MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat )\n{\n    vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, &mat->col3, spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0, const VmathSoaVector4 *_col1, const VmathSoaVector4 *_col2, const VmathSoaVector4 *_col3 )\n{\n    vmathSoaV4Copy( &result->col0, _col0 );\n    vmathSoaV4Copy( &result->col1, _col1 );\n    vmathSoaV4Copy( &result->col2, _col2 );\n    vmathSoaV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec )\n{\n    VmathSoaMatrix3 mat;\n    vmathSoaM3MakeFromQ( &mat, unitQuat );\n    vmathSoaV4MakeFromV3Scalar( &result->col0, &mat.col0, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col1, &mat.col1, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col2, &mat.col2, spu_splats(0.0f) );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat )\n{\n    vmathSoaV4MakeFromAos( &result->col0, &mat->col0 );\n    vmathSoaV4MakeFromAos( &result->col1, &mat->col1 );\n    vmathSoaV4MakeFromAos( &result->col2, &mat->col2 );\n    vmathSoaV4MakeFromAos( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 )\n{\n    vmathSoaV4MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 );\n    vmathSoaV4MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 );\n    vmathSoaV4MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 );\n    vmathSoaV4MakeFrom4Aos( &result->col3, &mat0->col3, &mat1->col3, &mat2->col3, &mat3->col3 );\n}\n\nstatic inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 )\n{\n    vmathSoaV4Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 );\n    vmathSoaV4Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 );\n    vmathSoaV4Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 );\n    vmathSoaV4Get4Aos( &mat->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 );\n}\n\nstatic inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0 )\n{\n    vmathSoaV4Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col1 )\n{\n    vmathSoaV4Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col2 )\n{\n    vmathSoaV4Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col3 )\n{\n    vmathSoaV4Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec )\n{\n    vmathSoaV4Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec )\n{\n    vmathSoaV4SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) );\n    vmathSoaV4SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) );\n    vmathSoaV4SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) );\n    vmathSoaV4SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val )\n{\n    VmathSoaVector4 tmpV3_0;\n    vmathSoaM4GetCol( &tmpV3_0, result, col );\n    vmathSoaV4SetElem( &tmpV3_0, row, val );\n    vmathSoaM4SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row )\n{\n    VmathSoaVector4 tmpV4_0;\n    vmathSoaM4GetCol( &tmpV4_0, mat, col );\n    return vmathSoaV4GetElem( &tmpV4_0, row );\n}\n\nstatic inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col0 );\n}\n\nstatic inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col1 );\n}\n\nstatic inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col2 );\n}\n\nstatic inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Copy( result, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col )\n{\n    vmathSoaV4Copy( result, (&mat->col0 + col) );\n}\n\nstatic inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row )\n{\n    vmathSoaV4MakeFromElems( result, vmathSoaV4GetElem( &mat->col0, row ), vmathSoaV4GetElem( &mat->col1, row ), vmathSoaV4GetElem( &mat->col2, row ), vmathSoaV4GetElem( &mat->col3, row ) );\n}\n\nstatic inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaMatrix4 tmpResult;\n    vmathSoaV4MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x, mat->col3.x );\n    vmathSoaV4MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y, mat->col3.y );\n    vmathSoaV4MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z, mat->col3.z );\n    vmathSoaV4MakeFromElems( &tmpResult.col3, mat->col0.w, mat->col1.w, mat->col2.w, mat->col3.w );\n    vmathSoaM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaVector4 res0, res1, res2, res3;\n    vec_float4 mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv;\n    mA = mat->col0.x;\n    mB = mat->col0.y;\n    mC = mat->col0.z;\n    mD = mat->col0.w;\n    mE = mat->col1.x;\n    mF = mat->col1.y;\n    mG = mat->col1.z;\n    mH = mat->col1.w;\n    mI = mat->col2.x;\n    mJ = mat->col2.y;\n    mK = mat->col2.z;\n    mL = mat->col2.w;\n    mM = mat->col3.x;\n    mN = mat->col3.y;\n    mO = mat->col3.z;\n    mP = mat->col3.w;\n    tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) );\n    tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) );\n    tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) );\n    tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) );\n    tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) );\n    tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) );\n    vmathSoaV4SetX( &res0, spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) ) );\n    vmathSoaV4SetY( &res0, spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) ) );\n    vmathSoaV4SetZ( &res0, spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) ) );\n    vmathSoaV4SetW( &res0, spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) ) );\n    detInv = recipf4( spu_add( spu_add( spu_add( spu_mul( mA, res0.x ), spu_mul( mE, res0.y ) ), spu_mul( mI, res0.z ) ), spu_mul( mM, res0.w ) ) );\n    vmathSoaV4SetX( &res1, spu_mul( mI, tmp1 ) );\n    vmathSoaV4SetY( &res1, spu_mul( mM, tmp0 ) );\n    vmathSoaV4SetZ( &res1, spu_mul( mA, tmp1 ) );\n    vmathSoaV4SetW( &res1, spu_mul( mE, tmp0 ) );\n    vmathSoaV4SetX( &res3, spu_mul( mI, tmp3 ) );\n    vmathSoaV4SetY( &res3, spu_mul( mM, tmp2 ) );\n    vmathSoaV4SetZ( &res3, spu_mul( mA, tmp3 ) );\n    vmathSoaV4SetW( &res3, spu_mul( mE, tmp2 ) );\n    vmathSoaV4SetX( &res2, spu_mul( mI, tmp5 ) );\n    vmathSoaV4SetY( &res2, spu_mul( mM, tmp4 ) );\n    vmathSoaV4SetZ( &res2, spu_mul( mA, tmp5 ) );\n    vmathSoaV4SetW( &res2, spu_mul( mE, tmp4 ) );\n    tmp0 = spu_sub( spu_mul( mI, mB ), spu_mul( mA, mJ ) );\n    tmp1 = spu_sub( spu_mul( mM, mF ), spu_mul( mE, mN ) );\n    tmp2 = spu_sub( spu_mul( mI, mD ), spu_mul( mA, mL ) );\n    tmp3 = spu_sub( spu_mul( mM, mH ), spu_mul( mE, mP ) );\n    tmp4 = spu_sub( spu_mul( mI, mC ), spu_mul( mA, mK ) );\n    tmp5 = spu_sub( spu_mul( mM, mG ), spu_mul( mE, mO ) );\n    vmathSoaV4SetX( &res2, spu_add( spu_sub( spu_mul( mL, tmp1 ), spu_mul( mJ, tmp3 ) ), res2.x ) );\n    vmathSoaV4SetY( &res2, spu_add( spu_sub( spu_mul( mP, tmp0 ), spu_mul( mN, tmp2 ) ), res2.y ) );\n    vmathSoaV4SetZ( &res2, spu_sub( spu_sub( spu_mul( mB, tmp3 ), spu_mul( mD, tmp1 ) ), res2.z ) );\n    vmathSoaV4SetW( &res2, spu_sub( spu_sub( spu_mul( mF, tmp2 ), spu_mul( mH, tmp0 ) ), res2.w ) );\n    vmathSoaV4SetX( &res3, spu_add( spu_sub( spu_mul( mJ, tmp5 ), spu_mul( mK, tmp1 ) ), res3.x ) );\n    vmathSoaV4SetY( &res3, spu_add( spu_sub( spu_mul( mN, tmp4 ), spu_mul( mO, tmp0 ) ), res3.y ) );\n    vmathSoaV4SetZ( &res3, spu_sub( spu_sub( spu_mul( mC, tmp1 ), spu_mul( mB, tmp5 ) ), res3.z ) );\n    vmathSoaV4SetW( &res3, spu_sub( spu_sub( spu_mul( mG, tmp0 ), spu_mul( mF, tmp4 ) ), res3.w ) );\n    vmathSoaV4SetX( &res1, spu_sub( spu_sub( spu_mul( mK, tmp3 ), spu_mul( mL, tmp5 ) ), res1.x ) );\n    vmathSoaV4SetY( &res1, spu_sub( spu_sub( spu_mul( mO, tmp2 ), spu_mul( mP, tmp4 ) ), res1.y ) );\n    vmathSoaV4SetZ( &res1, spu_add( spu_sub( spu_mul( mD, tmp5 ), spu_mul( mC, tmp3 ) ), res1.z ) );\n    vmathSoaV4SetW( &res1, spu_add( spu_sub( spu_mul( mH, tmp4 ), spu_mul( mG, tmp2 ) ), res1.w ) );\n    vmathSoaV4ScalarMul( &result->col0, &res0, detInv );\n    vmathSoaV4ScalarMul( &result->col1, &res1, detInv );\n    vmathSoaV4ScalarMul( &result->col2, &res2, detInv );\n    vmathSoaV4ScalarMul( &result->col3, &res3, detInv );\n}\n\nstatic inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaTransform3 affineMat, tmpT3_0;\n    VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathSoaT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathSoaT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathSoaT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathSoaT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathSoaT3Inverse( &tmpT3_0, &affineMat );\n    vmathSoaM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaTransform3 affineMat, tmpT3_0;\n    VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 );\n    vmathSoaT3SetCol0( &affineMat, &tmpV3_0 );\n    vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 );\n    vmathSoaT3SetCol1( &affineMat, &tmpV3_1 );\n    vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 );\n    vmathSoaT3SetCol2( &affineMat, &tmpV3_2 );\n    vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 );\n    vmathSoaT3SetCol3( &affineMat, &tmpV3_3 );\n    vmathSoaT3OrthoInverse( &tmpT3_0, &affineMat );\n    vmathSoaM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat )\n{\n    vec_float4 dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    mA = mat->col0.x;\n    mB = mat->col0.y;\n    mC = mat->col0.z;\n    mD = mat->col0.w;\n    mE = mat->col1.x;\n    mF = mat->col1.y;\n    mG = mat->col1.z;\n    mH = mat->col1.w;\n    mI = mat->col2.x;\n    mJ = mat->col2.y;\n    mK = mat->col2.z;\n    mL = mat->col2.w;\n    mM = mat->col3.x;\n    mN = mat->col3.y;\n    mO = mat->col3.z;\n    mP = mat->col3.w;\n    tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) );\n    tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) );\n    tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) );\n    tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) );\n    tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) );\n    tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) );\n    dx = spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) );\n    dy = spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) );\n    dz = spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) );\n    dw = spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) );\n    return spu_add( spu_add( spu_add( spu_mul( mA, dx ), spu_mul( mE, dy ) ), spu_mul( mI, dz ) ), spu_mul( mM, dw ) );\n}\n\nstatic inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    vmathSoaV4Add( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV4Add( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV4Add( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathSoaV4Add( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    vmathSoaV4Sub( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV4Sub( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV4Sub( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathSoaV4Sub( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4Neg( &result->col0, &mat->col0 );\n    vmathSoaV4Neg( &result->col1, &mat->col1 );\n    vmathSoaV4Neg( &result->col2, &mat->col2 );\n    vmathSoaV4Neg( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4AbsPerElem( &result->col0, &mat->col0 );\n    vmathSoaV4AbsPerElem( &result->col1, &mat->col1 );\n    vmathSoaV4AbsPerElem( &result->col2, &mat->col2 );\n    vmathSoaV4AbsPerElem( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar )\n{\n    vmathSoaV4ScalarMul( &result->col0, &mat->col0, scalar );\n    vmathSoaV4ScalarMul( &result->col1, &mat->col1, scalar );\n    vmathSoaV4ScalarMul( &result->col2, &mat->col2, scalar );\n    vmathSoaV4ScalarMul( &result->col3, &mat->col3, scalar );\n}\n\nstatic inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = spu_add( spu_add( spu_add( spu_mul( mat->col0.x, vec->x ), spu_mul( mat->col1.x, vec->y ) ), spu_mul( mat->col2.x, vec->z ) ), spu_mul( mat->col3.x, vec->w ) );\n    tmpY = spu_add( spu_add( spu_add( spu_mul( mat->col0.y, vec->x ), spu_mul( mat->col1.y, vec->y ) ), spu_mul( mat->col2.y, vec->z ) ), spu_mul( mat->col3.y, vec->w ) );\n    tmpZ = spu_add( spu_add( spu_add( spu_mul( mat->col0.z, vec->x ), spu_mul( mat->col1.z, vec->y ) ), spu_mul( mat->col2.z, vec->z ) ), spu_mul( mat->col3.z, vec->w ) );\n    tmpW = spu_add( spu_add( spu_add( spu_mul( mat->col0.w, vec->x ), spu_mul( mat->col1.w, vec->y ) ), spu_mul( mat->col2.w, vec->z ) ), spu_mul( mat->col3.w, vec->w ) );\n    vmathSoaV4MakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );\n}\n\nstatic inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec )\n{\n    result->x = spu_add( spu_add( spu_mul( mat->col0.x, vec->x ), spu_mul( mat->col1.x, vec->y ) ), spu_mul( mat->col2.x, vec->z ) );\n    result->y = spu_add( spu_add( spu_mul( mat->col0.y, vec->x ), spu_mul( mat->col1.y, vec->y ) ), spu_mul( mat->col2.y, vec->z ) );\n    result->z = spu_add( spu_add( spu_mul( mat->col0.z, vec->x ), spu_mul( mat->col1.z, vec->y ) ), spu_mul( mat->col2.z, vec->z ) );\n    result->w = spu_add( spu_add( spu_mul( mat->col0.w, vec->x ), spu_mul( mat->col1.w, vec->y ) ), spu_mul( mat->col2.w, vec->z ) );\n}\n\nstatic inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt )\n{\n    result->x = spu_add( spu_add( spu_add( spu_mul( mat->col0.x, pnt->x ), spu_mul( mat->col1.x, pnt->y ) ), spu_mul( mat->col2.x, pnt->z ) ), mat->col3.x );\n    result->y = spu_add( spu_add( spu_add( spu_mul( mat->col0.y, pnt->x ), spu_mul( mat->col1.y, pnt->y ) ), spu_mul( mat->col2.y, pnt->z ) ), mat->col3.y );\n    result->z = spu_add( spu_add( spu_add( spu_mul( mat->col0.z, pnt->x ), spu_mul( mat->col1.z, pnt->y ) ), spu_mul( mat->col2.z, pnt->z ) ), mat->col3.z );\n    result->w = spu_add( spu_add( spu_add( spu_mul( mat->col0.w, pnt->x ), spu_mul( mat->col1.w, pnt->y ) ), spu_mul( mat->col2.w, pnt->z ) ), mat->col3.w );\n}\n\nstatic inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    VmathSoaMatrix4 tmpResult;\n    vmathSoaM4MulV4( &tmpResult.col0, mat0, &mat1->col0 );\n    vmathSoaM4MulV4( &tmpResult.col1, mat0, &mat1->col1 );\n    vmathSoaM4MulV4( &tmpResult.col2, mat0, &mat1->col2 );\n    vmathSoaM4MulV4( &tmpResult.col3, mat0, &mat1->col3 );\n    vmathSoaM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm1 )\n{\n    VmathSoaMatrix4 tmpResult;\n    VmathSoaPoint3 tmpP3_0;\n    vmathSoaM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 );\n    vmathSoaM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 );\n    vmathSoaM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 );\n    vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathSoaM4MulP3( &tmpResult.col3, mat, &tmpP3_0 );\n    vmathSoaM4Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 )\n{\n    vmathSoaV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 );\n    vmathSoaV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 );\n    vmathSoaV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 );\n    vmathSoaV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 );\n}\n\nstatic inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result )\n{\n    vmathSoaV4MakeXAxis( &result->col0 );\n    vmathSoaV4MakeYAxis( &result->col1 );\n    vmathSoaV4MakeZAxis( &result->col2 );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 )\n{\n    vmathSoaV4SetXYZ( &result->col0, &mat3->col0 );\n    vmathSoaV4SetXYZ( &result->col1, &mat3->col1 );\n    vmathSoaV4SetXYZ( &result->col2, &mat3->col2 );\n}\n\nstatic inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4GetXYZ( &result->col0, &mat->col0 );\n    vmathSoaV4GetXYZ( &result->col1, &mat->col1 );\n    vmathSoaV4GetXYZ( &result->col2, &mat->col2 );\n}\n\nstatic inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV4SetXYZ( &result->col3, translateVec );\n}\n\nstatic inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat )\n{\n    vmathSoaV4GetXYZ( result, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV4MakeXAxis( &result->col0 );\n    vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), c, s, spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), negatef4( s ), c, spu_splats(0.0f) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV4MakeFromElems( &result->col0, c, spu_splats(0.0f), negatef4( s ), spu_splats(0.0f) );\n    vmathSoaV4MakeYAxis( &result->col1 );\n    vmathSoaV4MakeFromElems( &result->col2, s, spu_splats(0.0f), c, spu_splats(0.0f) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV4MakeFromElems( &result->col0, c, s, spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, negatef4( s ), c, spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeZAxis( &result->col2 );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ->x, &sX, &cX );\n    sincosf4( radiansXYZ->y, &sY, &cY );\n    sincosf4( radiansXYZ->z, &sZ, &cZ );\n    tmp0 = spu_mul( cZ, sY );\n    tmp1 = spu_mul( sZ, sY );\n    vmathSoaV4MakeFromElems( &result->col0, spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, spu_sub( spu_mul( tmp0, sX ), spu_mul( sZ, cX ) ), spu_add( spu_mul( tmp1, sX ), spu_mul( cZ, cX ) ), spu_mul( cY, sX ), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_add( spu_mul( tmp0, cX ), spu_mul( sZ, sX ) ), spu_sub( spu_mul( tmp1, cX ), spu_mul( cZ, sX ) ), spu_mul( cY, cX ), spu_splats(0.0f) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec->x;\n    y = unitVec->y;\n    z = unitVec->z;\n    xy = spu_mul( x, y );\n    yz = spu_mul( y, z );\n    zx = spu_mul( z, x );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    vmathSoaV4MakeFromElems( &result->col0, spu_add( spu_mul( spu_mul( x, x ), oneMinusC ), c ), spu_add( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_sub( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, spu_sub( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_add( spu_mul( spu_mul( y, y ), oneMinusC ), c ), spu_add( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_add( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ), spu_sub( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ), spu_add( spu_mul( spu_mul( z, z ), oneMinusC ), c ), spu_splats(0.0f) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat )\n{\n    VmathSoaTransform3 tmpT3_0;\n    vmathSoaT3MakeRotationQ( &tmpT3_0, unitQuat );\n    vmathSoaM4MakeFromT3( result, &tmpT3_0 );\n}\n\nstatic inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV4MakeFromElems( &result->col0, scaleVec->x, spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), scaleVec->y, spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), scaleVec->z, spu_splats(0.0f) );\n    vmathSoaV4MakeWAxis( &result->col3 );\n}\n\nstatic inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV4ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) );\n    vmathSoaV4ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) );\n    vmathSoaV4ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) );\n    vmathSoaV4Copy( &result->col3, &mat->col3 );\n}\n\nstatic inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat )\n{\n    VmathSoaVector4 scale4;\n    vmathSoaV4MakeFromV3Scalar( &scale4, scaleVec, spu_splats(1.0f) );\n    vmathSoaV4MulPerElem( &result->col0, &mat->col0, &scale4 );\n    vmathSoaV4MulPerElem( &result->col1, &mat->col1, &scale4 );\n    vmathSoaV4MulPerElem( &result->col2, &mat->col2, &scale4 );\n    vmathSoaV4MulPerElem( &result->col3, &mat->col3, &scale4 );\n}\n\nstatic inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV4MakeXAxis( &result->col0 );\n    vmathSoaV4MakeYAxis( &result->col1 );\n    vmathSoaV4MakeZAxis( &result->col2 );\n    vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec )\n{\n    VmathSoaMatrix4 m4EyeFrame;\n    VmathSoaVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1;\n    VmathSoaVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    vmathSoaV3Normalize( &v3Y, upVec );\n    vmathSoaP3Sub( &tmpV3_0, eyePos, lookAtPos );\n    vmathSoaV3Normalize( &v3Z, &tmpV3_0 );\n    vmathSoaV3Cross( &tmpV3_1, &v3Y, &v3Z );\n    vmathSoaV3Normalize( &v3X, &tmpV3_1 );\n    vmathSoaV3Cross( &v3Y, &v3Z, &v3X );\n    vmathSoaV4MakeFromV3( &tmpV4_0, &v3X );\n    vmathSoaV4MakeFromV3( &tmpV4_1, &v3Y );\n    vmathSoaV4MakeFromV3( &tmpV4_2, &v3Z );\n    vmathSoaV4MakeFromP3( &tmpV4_3, eyePos );\n    vmathSoaM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 );\n    vmathSoaM4OrthoInverse( result, &m4EyeFrame );\n}\n\nstatic inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 f, rangeInv;\n    f = tanf4( spu_sub( spu_splats( _VECTORMATH_PI_OVER_2 ), spu_mul( spu_splats(0.5f), fovyRadians ) ) );\n    rangeInv = recipf4( spu_sub( zNear, zFar ) );\n    vmathSoaV4MakeFromElems( &result->col0, divf4( f, aspect ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), f, spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_add( zNear, zFar ), rangeInv ), spu_splats(-1.0f) );\n    vmathSoaV4MakeFromElems( &result->col3, spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_mul( spu_mul( zNear, zFar ), rangeInv ), spu_splats(2.0f) ), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2;\n    sum_rl = spu_add( right, left );\n    sum_tb = spu_add( top, bottom );\n    sum_nf = spu_add( zNear, zFar );\n    inv_rl = recipf4( spu_sub( right, left ) );\n    inv_tb = recipf4( spu_sub( top, bottom ) );\n    inv_nf = recipf4( spu_sub( zNear, zFar ) );\n    n2 = spu_add( zNear, zNear );\n    vmathSoaV4MakeFromElems( &result->col0, spu_mul( n2, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), spu_mul( n2, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_mul( sum_rl, inv_rl ), spu_mul( sum_tb, inv_tb ), spu_mul( sum_nf, inv_nf ), spu_splats(-1.0f) );\n    vmathSoaV4MakeFromElems( &result->col3, spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_mul( n2, inv_nf ), zFar ), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf;\n    sum_rl = spu_add( right, left );\n    sum_tb = spu_add( top, bottom );\n    sum_nf = spu_add( zNear, zFar );\n    inv_rl = recipf4( spu_sub( right, left ) );\n    inv_tb = recipf4( spu_sub( top, bottom ) );\n    inv_nf = recipf4( spu_sub( zNear, zFar ) );\n    vmathSoaV4MakeFromElems( &result->col0, spu_add( inv_rl, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), spu_add( inv_tb, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), spu_add( inv_nf, inv_nf ), spu_splats(0.0f) );\n    vmathSoaV4MakeFromElems( &result->col3, spu_mul( negatef4( sum_rl ), inv_rl ), spu_mul( negatef4( sum_tb ), inv_tb ), spu_mul( sum_nf, inv_nf ), spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 )\n{\n    vmathSoaV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 );\n    vmathSoaV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 );\n    vmathSoaV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 );\n    vmathSoaV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat )\n{\n    VmathMatrix4 mat0, mat1, mat2, mat3;\n    vmathSoaM4Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 );\n    printf(\"slot 0:\\n\");\n    vmathM4Print( &mat0 );\n    printf(\"slot 1:\\n\");\n    vmathM4Print( &mat1 );\n    printf(\"slot 2:\\n\");\n    vmathM4Print( &mat2 );\n    printf(\"slot 3:\\n\");\n    vmathM4Print( &mat3 );\n}\n\nstatic inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathSoaM4Print( mat );\n}\n\n#endif\n\nstatic inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( &result->col0, &tfrm->col0 );\n    vmathSoaV3Copy( &result->col1, &tfrm->col1 );\n    vmathSoaV3Copy( &result->col2, &tfrm->col2 );\n    vmathSoaV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar )\n{\n    vmathSoaV3MakeFromScalar( &result->col0, scalar );\n    vmathSoaV3MakeFromScalar( &result->col1, scalar );\n    vmathSoaV3MakeFromScalar( &result->col2, scalar );\n    vmathSoaV3MakeFromScalar( &result->col3, scalar );\n}\n\nstatic inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2, const VmathSoaVector3 *_col3 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n    vmathSoaV3Copy( &result->col1, _col1 );\n    vmathSoaV3Copy( &result->col2, _col2 );\n    vmathSoaV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaT3SetUpper3x3( result, tfrm );\n    vmathSoaT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec )\n{\n    VmathSoaMatrix3 tmpM3_0;\n    vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathSoaT3SetUpper3x3( result, &tmpM3_0 );\n    vmathSoaT3SetTranslation( result, translateVec );\n}\n\nstatic inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm )\n{\n    vmathSoaV3MakeFromAos( &result->col0, &tfrm->col0 );\n    vmathSoaV3MakeFromAos( &result->col1, &tfrm->col1 );\n    vmathSoaV3MakeFromAos( &result->col2, &tfrm->col2 );\n    vmathSoaV3MakeFromAos( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 )\n{\n    vmathSoaV3MakeFrom4Aos( &result->col0, &tfrm0->col0, &tfrm1->col0, &tfrm2->col0, &tfrm3->col0 );\n    vmathSoaV3MakeFrom4Aos( &result->col1, &tfrm0->col1, &tfrm1->col1, &tfrm2->col1, &tfrm3->col1 );\n    vmathSoaV3MakeFrom4Aos( &result->col2, &tfrm0->col2, &tfrm1->col2, &tfrm2->col2, &tfrm3->col2 );\n    vmathSoaV3MakeFrom4Aos( &result->col3, &tfrm0->col3, &tfrm1->col3, &tfrm2->col3, &tfrm3->col3 );\n}\n\nstatic inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 )\n{\n    vmathSoaV3Get4Aos( &tfrm->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 );\n    vmathSoaV3Get4Aos( &tfrm->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 );\n    vmathSoaV3Get4Aos( &tfrm->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 );\n    vmathSoaV3Get4Aos( &tfrm->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 );\n}\n\nstatic inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0 )\n{\n    vmathSoaV3Copy( &result->col0, _col0 );\n}\n\nstatic inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *_col1 )\n{\n    vmathSoaV3Copy( &result->col1, _col1 );\n}\n\nstatic inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *_col2 )\n{\n    vmathSoaV3Copy( &result->col2, _col2 );\n}\n\nstatic inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *_col3 )\n{\n    vmathSoaV3Copy( &result->col3, _col3 );\n}\n\nstatic inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3Copy( (&result->col0 + col), vec );\n}\n\nstatic inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec )\n{\n    vmathSoaV3SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) );\n    vmathSoaV3SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) );\n    vmathSoaV3SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) );\n    vmathSoaV3SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) );\n}\n\nstatic inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaT3GetCol( &tmpV3_0, result, col );\n    vmathSoaV3SetElem( &tmpV3_0, row, val );\n    vmathSoaT3SetCol( result, col, &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaT3GetCol( &tmpV3_0, tfrm, col );\n    return vmathSoaV3GetElem( &tmpV3_0, row );\n}\n\nstatic inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col0 );\n}\n\nstatic inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col1 );\n}\n\nstatic inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col2 );\n}\n\nstatic inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col )\n{\n    vmathSoaV3Copy( result, (&tfrm->col0 + col) );\n}\n\nstatic inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row )\n{\n    vmathSoaV4MakeFromElems( result, vmathSoaV3GetElem( &tfrm->col0, row ), vmathSoaV3GetElem( &tfrm->col1, row ), vmathSoaV3GetElem( &tfrm->col2, row ), vmathSoaV3GetElem( &tfrm->col3, row ) );\n}\n\nstatic inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    VmathSoaVector3 tmp0, tmp1, tmp2, inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5;\n    vec_float4 detinv;\n    vmathSoaV3Cross( &tmp0, &tfrm->col1, &tfrm->col2 );\n    vmathSoaV3Cross( &tmp1, &tfrm->col2, &tfrm->col0 );\n    vmathSoaV3Cross( &tmp2, &tfrm->col0, &tfrm->col1 );\n    detinv = recipf4( vmathSoaV3Dot( &tfrm->col2, &tmp2 ) );\n    vmathSoaV3MakeFromElems( &inv0, spu_mul( tmp0.x, detinv ), spu_mul( tmp1.x, detinv ), spu_mul( tmp2.x, detinv ) );\n    vmathSoaV3MakeFromElems( &inv1, spu_mul( tmp0.y, detinv ), spu_mul( tmp1.y, detinv ), spu_mul( tmp2.y, detinv ) );\n    vmathSoaV3MakeFromElems( &inv2, spu_mul( tmp0.z, detinv ), spu_mul( tmp1.z, detinv ), spu_mul( tmp2.z, detinv ) );\n    vmathSoaV3Copy( &result->col0, &inv0 );\n    vmathSoaV3Copy( &result->col1, &inv1 );\n    vmathSoaV3Copy( &result->col2, &inv2 );\n    vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x );\n    vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y );\n    vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z );\n    vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 );\n    vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 );\n    vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 );\n    vmathSoaV3Copy( &result->col3, &tmpV3_5 );\n}\n\nstatic inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    VmathSoaVector3 inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5;\n    vmathSoaV3MakeFromElems( &inv0, tfrm->col0.x, tfrm->col1.x, tfrm->col2.x );\n    vmathSoaV3MakeFromElems( &inv1, tfrm->col0.y, tfrm->col1.y, tfrm->col2.y );\n    vmathSoaV3MakeFromElems( &inv2, tfrm->col0.z, tfrm->col1.z, tfrm->col2.z );\n    vmathSoaV3Copy( &result->col0, &inv0 );\n    vmathSoaV3Copy( &result->col1, &inv1 );\n    vmathSoaV3Copy( &result->col2, &inv2 );\n    vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x );\n    vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y );\n    vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z );\n    vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 );\n    vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 );\n    vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 );\n    vmathSoaV3Copy( &result->col3, &tmpV3_5 );\n}\n\nstatic inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3AbsPerElem( &result->col0, &tfrm->col0 );\n    vmathSoaV3AbsPerElem( &result->col1, &tfrm->col1 );\n    vmathSoaV3AbsPerElem( &result->col2, &tfrm->col2 );\n    vmathSoaV3AbsPerElem( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = spu_add( spu_add( spu_mul( tfrm->col0.x, vec->x ), spu_mul( tfrm->col1.x, vec->y ) ), spu_mul( tfrm->col2.x, vec->z ) );\n    tmpY = spu_add( spu_add( spu_mul( tfrm->col0.y, vec->x ), spu_mul( tfrm->col1.y, vec->y ) ), spu_mul( tfrm->col2.y, vec->z ) );\n    tmpZ = spu_add( spu_add( spu_mul( tfrm->col0.z, vec->x ), spu_mul( tfrm->col1.z, vec->y ) ), spu_mul( tfrm->col2.z, vec->z ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = spu_add( spu_add( spu_add( spu_mul( tfrm->col0.x, pnt->x ), spu_mul( tfrm->col1.x, pnt->y ) ), spu_mul( tfrm->col2.x, pnt->z ) ), tfrm->col3.x );\n    tmpY = spu_add( spu_add( spu_add( spu_mul( tfrm->col0.y, pnt->x ), spu_mul( tfrm->col1.y, pnt->y ) ), spu_mul( tfrm->col2.y, pnt->z ) ), tfrm->col3.y );\n    tmpZ = spu_add( spu_add( spu_add( spu_mul( tfrm->col0.z, pnt->x ), spu_mul( tfrm->col1.z, pnt->y ) ), spu_mul( tfrm->col2.z, pnt->z ) ), tfrm->col3.z );\n    vmathSoaP3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 )\n{\n    VmathSoaTransform3 tmpResult;\n    VmathSoaPoint3 tmpP3_0, tmpP3_1;\n    vmathSoaT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 );\n    vmathSoaT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 );\n    vmathSoaT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 );\n    vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 );\n    vmathSoaT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 );\n    vmathSoaV3MakeFromP3( &tmpResult.col3, &tmpP3_1 );\n    vmathSoaT3Copy( result, &tmpResult );\n}\n\nstatic inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 )\n{\n    vmathSoaV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 );\n    vmathSoaV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 );\n    vmathSoaV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 );\n    vmathSoaV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 );\n}\n\nstatic inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result )\n{\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeZAxis( &result->col2 );\n    vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm )\n{\n    vmathSoaV3Copy( &result->col0, &tfrm->col0 );\n    vmathSoaV3Copy( &result->col1, &tfrm->col1 );\n    vmathSoaV3Copy( &result->col2, &tfrm->col2 );\n}\n\nstatic inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 );\n}\n\nstatic inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3Copy( result, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), c, s );\n    vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), negatef4( s ), c );\n    vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, spu_splats(0.0f), negatef4( s ) );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeFromElems( &result->col2, s, spu_splats(0.0f), c );\n    vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    vmathSoaV3MakeFromElems( &result->col0, c, s, spu_splats(0.0f) );\n    vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, spu_splats(0.0f) );\n    vmathSoaV3MakeZAxis( &result->col2 );\n    vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ->x, &sX, &cX );\n    sincosf4( radiansXYZ->y, &sY, &cY );\n    sincosf4( radiansXYZ->z, &sZ, &cZ );\n    tmp0 = spu_mul( cZ, sY );\n    tmp1 = spu_mul( sZ, sY );\n    vmathSoaV3MakeFromElems( &result->col0, spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_sub( spu_mul( tmp0, sX ), spu_mul( sZ, cX ) ), spu_add( spu_mul( tmp1, sX ), spu_mul( cZ, cX ) ), spu_mul( cY, sX ) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_add( spu_mul( tmp0, cX ), spu_mul( sZ, sX ) ), spu_sub( spu_mul( tmp1, cX ), spu_mul( cZ, sX ) ), spu_mul( cY, cX ) );\n    vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    VmathSoaMatrix3 tmpM3_0;\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3MakeRotationAxis( &tmpM3_0, radians, unitVec );\n    vmathSoaV3MakeFromScalar( &tmpV3_0, spu_splats(0.0f) );\n    vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat )\n{\n    VmathSoaMatrix3 tmpM3_0;\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat );\n    vmathSoaV3MakeFromScalar( &tmpV3_0, spu_splats(0.0f) );\n    vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 );\n}\n\nstatic inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3MakeFromElems( &result->col0, scaleVec->x, spu_splats(0.0f), spu_splats(0.0f) );\n    vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), scaleVec->y, spu_splats(0.0f) );\n    vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), scaleVec->z );\n    vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec )\n{\n    vmathSoaV3ScalarMul( &result->col0, &tfrm->col0, vmathSoaV3GetX( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col1, &tfrm->col1, vmathSoaV3GetY( scaleVec ) );\n    vmathSoaV3ScalarMul( &result->col2, &tfrm->col2, vmathSoaV3GetZ( scaleVec ) );\n    vmathSoaV3Copy( &result->col3, &tfrm->col3 );\n}\n\nstatic inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm )\n{\n    vmathSoaV3MulPerElem( &result->col0, &tfrm->col0, scaleVec );\n    vmathSoaV3MulPerElem( &result->col1, &tfrm->col1, scaleVec );\n    vmathSoaV3MulPerElem( &result->col2, &tfrm->col2, scaleVec );\n    vmathSoaV3MulPerElem( &result->col3, &tfrm->col3, scaleVec );\n}\n\nstatic inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec )\n{\n    vmathSoaV3MakeXAxis( &result->col0 );\n    vmathSoaV3MakeYAxis( &result->col1 );\n    vmathSoaV3MakeZAxis( &result->col2 );\n    vmathSoaV3Copy( &result->col3, translateVec );\n}\n\nstatic inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 )\n{\n    vmathSoaV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 );\n    vmathSoaV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 );\n    vmathSoaV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 );\n    vmathSoaV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm )\n{\n    VmathTransform3 mat0, mat1, mat2, mat3;\n    vmathSoaT3Get4Aos( tfrm, &mat0, &mat1, &mat2, &mat3 );\n    printf(\"slot 0:\\n\");\n    vmathT3Print( &mat0 );\n    printf(\"slot 1:\\n\");\n    vmathT3Print( &mat1 );\n    printf(\"slot 2:\\n\");\n    vmathT3Print( &mat2 );\n    printf(\"slot 3:\\n\");\n    vmathT3Print( &mat3 );\n}\n\nstatic inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name )\n{\n    printf(\"%s:\\n\", name);\n    vmathSoaT3Print( tfrm );\n}\n\n#endif\n\nstatic inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *tfrm )\n{\n    vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw;\n    vec_uint4 negTrace, ZgtX, ZgtY, YgtX;\n    vec_uint4 largestXorY, largestYorZ, largestZorX;\n\n    xx = tfrm->col0.x;\n    yx = tfrm->col0.y;\n    zx = tfrm->col0.z;\n    xy = tfrm->col1.x;\n    yy = tfrm->col1.y;\n    zy = tfrm->col1.z;\n    xz = tfrm->col2.x;\n    yz = tfrm->col2.y;\n    zz = tfrm->col2.z;\n\n    trace = spu_add( spu_add( xx, yy ), zz );\n\n    negTrace = spu_cmpgt( spu_splats(0.0f), trace );\n    ZgtX = spu_cmpgt( zz, xx );\n    ZgtY = spu_cmpgt( zz, yy );\n    YgtX = spu_cmpgt( yy, xx );\n    largestXorY = spu_and( negTrace, spu_nand( ZgtX, ZgtY ) );\n    largestYorZ = spu_and( negTrace, spu_or( YgtX, ZgtX ) );\n    largestZorX = spu_and( negTrace, spu_orc( ZgtY, YgtX ) );\n    \n    zz = spu_sel( zz, negatef4(zz), largestXorY );\n    xy = spu_sel( xy, negatef4(xy), largestXorY );\n    xx = spu_sel( xx, negatef4(xx), largestYorZ );\n    yz = spu_sel( yz, negatef4(yz), largestYorZ );\n    yy = spu_sel( yy, negatef4(yy), largestZorX );\n    zx = spu_sel( zx, negatef4(zx), largestZorX );\n\n    radicand = spu_add( spu_add( spu_add( xx, yy ), zz ), spu_splats(1.0f) );\n    scale = spu_mul( spu_splats(0.5f), rsqrtf4( radicand ) );\n\n    tmpx = spu_mul( spu_sub( zy, yz ), scale );\n    tmpy = spu_mul( spu_sub( xz, zx ), scale );\n    tmpz = spu_mul( spu_sub( yx, xy ), scale );\n    tmpw = spu_mul( radicand, scale );\n    qx = tmpx;\n    qy = tmpy;\n    qz = tmpz;\n    qw = tmpw;\n\n    qx = spu_sel( qx, tmpw, largestXorY );\n    qy = spu_sel( qy, tmpz, largestXorY );\n    qz = spu_sel( qz, tmpy, largestXorY );\n    qw = spu_sel( qw, tmpx, largestXorY );\n    tmpx = qx;\n    tmpz = qz;\n    qx = spu_sel( qx, qy, largestYorZ );\n    qy = spu_sel( qy, tmpx, largestYorZ );\n    qz = spu_sel( qz, qw, largestYorZ );\n    qw = spu_sel( qw, tmpz, largestYorZ );\n\n    result->x = qx;\n    result->y = qy;\n    result->z = qz;\n    result->w = qw;\n}\n\nstatic inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *tfrm0, const VmathSoaVector3 *tfrm1 )\n{\n    vmathSoaV3ScalarMul( &result->col0, tfrm0, vmathSoaV3GetX( tfrm1 ) );\n    vmathSoaV3ScalarMul( &result->col1, tfrm0, vmathSoaV3GetY( tfrm1 ) );\n    vmathSoaV3ScalarMul( &result->col2, tfrm0, vmathSoaV3GetZ( tfrm1 ) );\n}\n\nstatic inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *tfrm0, const VmathSoaVector4 *tfrm1 )\n{\n    vmathSoaV4ScalarMul( &result->col0, tfrm0, vmathSoaV4GetX( tfrm1 ) );\n    vmathSoaV4ScalarMul( &result->col1, tfrm0, vmathSoaV4GetY( tfrm1 ) );\n    vmathSoaV4ScalarMul( &result->col2, tfrm0, vmathSoaV4GetZ( tfrm1 ) );\n    vmathSoaV4ScalarMul( &result->col3, tfrm0, vmathSoaV4GetW( tfrm1 ) );\n}\n\nstatic inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = spu_add( spu_add( spu_mul( vec->x, mat->col0.x ), spu_mul( vec->y, mat->col0.y ) ), spu_mul( vec->z, mat->col0.z ) );\n    tmpY = spu_add( spu_add( spu_mul( vec->x, mat->col1.x ), spu_mul( vec->y, mat->col1.y ) ), spu_mul( vec->z, mat->col1.z ) );\n    tmpZ = spu_add( spu_add( spu_mul( vec->x, mat->col2.x ), spu_mul( vec->y, mat->col2.y ) ), spu_mul( vec->z, mat->col2.z ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec )\n{\n    vmathSoaV3MakeFromElems( &result->col0, spu_splats(0.0f), vec->z, negatef4( vec->y ) );\n    vmathSoaV3MakeFromElems( &result->col1, negatef4( vec->z ), spu_splats(0.0f), vec->x );\n    vmathSoaV3MakeFromElems( &result->col2, vec->y, negatef4( vec->x ), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2;\n    vmathSoaV3Cross( &tmpV3_0, vec, &mat->col0 );\n    vmathSoaV3Cross( &tmpV3_1, vec, &mat->col1 );\n    vmathSoaV3Cross( &tmpV3_2, vec, &mat->col2 );\n    vmathSoaM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 );\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/mat_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_SOA_V_C_H\n#define _VECTORMATH_MAT_SOA_V_C_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n */\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromCols(&result, &_col0, &_col1, &_col2);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFromAos(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3);\n    return result;\n}\n\nstatic inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 )\n{\n    vmathSoaM3Get4Aos(&mat, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col0 )\n{\n    vmathSoaM3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col1 )\n{\n    vmathSoaM3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col2 )\n{\n    vmathSoaM3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec )\n{\n    vmathSoaM3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec )\n{\n    vmathSoaM3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val )\n{\n    vmathSoaM3SetElem(result, col, row, val);\n}\n\nstatic inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row )\n{\n    return vmathSoaM3GetElem(&mat, col, row);\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat )\n{\n    return vmathSoaM3Determinant(&mat);\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaM3MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM3Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat )\n{\n    vmathSoaM3Print(&mat);\n}\n\nstatic inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name )\n{\n    vmathSoaM3Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromT3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 _col0, VmathSoaVector4 _col1, VmathSoaVector4 _col2, VmathSoaVector4 _col3 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromM3V3(&result, &mat, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFromAos(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3);\n    return result;\n}\n\nstatic inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 )\n{\n    vmathSoaM4Get4Aos(&mat, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col0 )\n{\n    vmathSoaM4SetCol0(result, &_col0);\n}\n\nstatic inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col1 )\n{\n    vmathSoaM4SetCol1(result, &_col1);\n}\n\nstatic inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col2 )\n{\n    vmathSoaM4SetCol2(result, &_col2);\n}\n\nstatic inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col3 )\n{\n    vmathSoaM4SetCol3(result, &_col3);\n}\n\nstatic inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec )\n{\n    vmathSoaM4SetCol(result, col, &vec);\n}\n\nstatic inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec )\n{\n    vmathSoaM4SetRow(result, row, &vec);\n}\n\nstatic inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val )\n{\n    vmathSoaM4SetElem(result, col, row, val);\n}\n\nstatic inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row )\n{\n    return vmathSoaM4GetElem(&mat, col, row);\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol0(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol1(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol2(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol3(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetCol(&result, &mat, col);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4GetRow(&result, &mat, row);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Transpose(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Inverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4AffineInverse(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4OrthoInverse(&result, &mat);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat )\n{\n    return vmathSoaM4Determinant(&mat);\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Add(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Sub(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Neg(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4AbsPerElem(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4ScalarMul(&result, &mat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4MulV4(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4MulV3(&result, &mat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt )\n{\n    VmathSoaVector4 result;\n    vmathSoaM4MulP3(&result, &mat, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Mul(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MulT3(&result, &mat, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MulPerElem(&result, &mat0, &mat1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 )\n{\n    vmathSoaM4SetUpper3x3(result, &mat3);\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaM4GetUpper3x3(&result, &mat);\n    return result;\n}\n\nstatic inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec )\n{\n    vmathSoaM4SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaM4GetTranslation(&result, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4AppendScale(&result, &mat, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4PrependScale(&result, &scaleVec, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaM4Select(&result, &mat0, &mat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat )\n{\n    vmathSoaM4Print(&mat);\n}\n\nstatic inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name )\n{\n    vmathSoaM4Prints(&mat, name);\n}\n\n#endif\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2, VmathSoaVector3 _col3 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromM3V3(&result, &tfrm, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromQV3(&result, &unitQuat, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFromAos(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeFrom4Aos(&result, &tfrm0, &tfrm1, &tfrm2, &tfrm3);\n    return result;\n}\n\nstatic inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 )\n{\n    vmathSoaT3Get4Aos(&tfrm, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 _col0 )\n{\n    vmathSoaT3SetCol0(result, &_col0);\n}\n\nstatic inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 _col1 )\n{\n    vmathSoaT3SetCol1(result, &_col1);\n}\n\nstatic inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 _col2 )\n{\n    vmathSoaT3SetCol2(result, &_col2);\n}\n\nstatic inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 _col3 )\n{\n    vmathSoaT3SetCol3(result, &_col3);\n}\n\nstatic inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec )\n{\n    vmathSoaT3SetCol(result, col, &vec);\n}\n\nstatic inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec )\n{\n    vmathSoaT3SetRow(result, row, &vec);\n}\n\nstatic inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val )\n{\n    vmathSoaT3SetElem(result, col, row, val);\n}\n\nstatic inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row )\n{\n    return vmathSoaT3GetElem(&tfrm, col, row);\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol0(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol1(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol2(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetCol(&result, &tfrm, col);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row )\n{\n    VmathSoaVector4 result;\n    vmathSoaT3GetRow(&result, &tfrm, row);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3Inverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3OrthoInverse(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3AbsPerElem(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3MulV3(&result, &tfrm, &vec);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaT3MulP3(&result, &tfrm, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3Mul(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MulPerElem(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeIdentity(&result);\n    return result;\n}\n\nstatic inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 tfrm )\n{\n    vmathSoaT3SetUpper3x3(result, &tfrm);\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaT3GetUpper3x3(&result, &tfrm);\n    return result;\n}\n\nstatic inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec )\n{\n    vmathSoaT3SetTranslation(result, &translateVec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm )\n{\n    VmathSoaVector3 result;\n    vmathSoaT3GetTranslation(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationZYX(&result, &radiansXYZ);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeRotationQ(&result, &unitQuat);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeScale(&result, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3AppendScale(&result, &tfrm, &scaleVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3PrependScale(&result, &scaleVec, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3MakeTranslation(&result, &translateVec);\n    return result;\n}\n\nstatic inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 )\n{\n    VmathSoaTransform3 result;\n    vmathSoaT3Select(&result, &tfrm0, &tfrm1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm )\n{\n    vmathSoaT3Print(&tfrm);\n}\n\nstatic inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name )\n{\n    vmathSoaT3Prints(&tfrm, name);\n}\n\n#endif\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 tfrm )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromM3(&result, &tfrm);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 tfrm0, VmathSoaVector3 tfrm1 )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaV3Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 tfrm0, VmathSoaVector4 tfrm1 )\n{\n    VmathSoaMatrix4 result;\n    vmathSoaV4Outer(&result, &tfrm0, &tfrm1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3RowMul(&result, &vec, &mat);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaV3CrossMatrix(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat )\n{\n    VmathSoaMatrix3 result;\n    vmathSoaV3CrossMatrixMul(&result, &vec, &mat);\n    return result;\n}\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_C_H\n#define _VECTORMATH_QUAT_AOS_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat )\n{\n    result->vec128 = quat->vec128;\n}\n\nstatic inline void vmathQMakeFromElems( VmathQuat *result, float _x, float _y, float _z, float _w )\n{\n    result->vec128 = (vec_float4){ _x, _y, _z, _w };\n}\n\nstatic inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float _w )\n{\n    result->vec128 = spu_shuffle( xyz->vec128, spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA );\n}\n\nstatic inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathQMakeFromScalar( VmathQuat *result, float scalar )\n{\n    result->vec128 = spu_splats( scalar );\n}\n\nstatic inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathQMakeIdentity( VmathQuat *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0001;\n}\n\nstatic inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    VmathQuat tmpQ_0, tmpQ_1;\n    vmathQSub( &tmpQ_0, quat1, quat0 );\n    vmathQScalarMul( &tmpQ_1, &tmpQ_0, t );\n    vmathQAdd( result, quat0, &tmpQ_1 );\n}\n\nstatic inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 )\n{\n    VmathQuat start;\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    cosAngle = _vmathVfDot4( unitQuat0->vec128, unitQuat1->vec128 );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle );\n    cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start.vec128 = spu_sel( unitQuat0->vec128, negatef4( unitQuat0->vec128 ), selectMask );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = spu_splats(t);\n    oneMinusT = spu_sub( spu_splats(1.0f), tttt );\n    angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) );\n    angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) );\n    angles = spu_mul( angles, angle );\n    sines = sinf4( angles );\n    scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) );\n    scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask );\n    scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask );\n    result->vec128 = spu_madd( start.vec128, scale0, spu_mul( unitQuat1->vec128, scale1 ) );\n}\n\nstatic inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 )\n{\n    VmathQuat tmp0, tmp1;\n    vmathQSlerp( &tmp0, t, unitQuat0, unitQuat3 );\n    vmathQSlerp( &tmp1, t, unitQuat1, unitQuat2 );\n    vmathQSlerp( result, ( ( 2.0f * t ) * ( 1.0f - t ) ), &tmp0, &tmp1 );\n}\n\nstatic inline vec_float4 vmathQGet128( const VmathQuat *quat )\n{\n    return quat->vec128;\n}\n\nstatic inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec )\n{\n    result->vec128 = spu_sel( vec->vec128, result->vec128, (vec_uint4)spu_maskb(0x000f) );\n}\n\nstatic inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat )\n{\n    result->vec128 = quat->vec128;\n}\n\nstatic inline void vmathQSetX( VmathQuat *result, float _x )\n{\n    result->vec128 = spu_insert( _x, result->vec128, 0 );\n}\n\nstatic inline float vmathQGetX( const VmathQuat *quat )\n{\n    return spu_extract( quat->vec128, 0 );\n}\n\nstatic inline void vmathQSetY( VmathQuat *result, float _y )\n{\n    result->vec128 = spu_insert( _y, result->vec128, 1 );\n}\n\nstatic inline float vmathQGetY( const VmathQuat *quat )\n{\n    return spu_extract( quat->vec128, 1 );\n}\n\nstatic inline void vmathQSetZ( VmathQuat *result, float _z )\n{\n    result->vec128 = spu_insert( _z, result->vec128, 2 );\n}\n\nstatic inline float vmathQGetZ( const VmathQuat *quat )\n{\n    return spu_extract( quat->vec128, 2 );\n}\n\nstatic inline void vmathQSetW( VmathQuat *result, float _w )\n{\n    result->vec128 = spu_insert( _w, result->vec128, 3 );\n}\n\nstatic inline float vmathQGetW( const VmathQuat *quat )\n{\n    return spu_extract( quat->vec128, 3 );\n}\n\nstatic inline void vmathQSetElem( VmathQuat *result, int idx, float value )\n{\n    result->vec128 = spu_insert( value, result->vec128, idx );\n}\n\nstatic inline float vmathQGetElem( const VmathQuat *quat, int idx )\n{\n    return spu_extract( quat->vec128, idx );\n}\n\nstatic inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    result->vec128 = spu_add( quat0->vec128, quat1->vec128 );\n}\n\nstatic inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    result->vec128 = spu_sub( quat0->vec128, quat1->vec128 );\n}\n\nstatic inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar )\n{\n    result->vec128 = spu_mul( quat->vec128, spu_splats(scalar) );\n}\n\nstatic inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar )\n{\n    result->vec128 = divf4( quat->vec128, spu_splats(scalar) );\n}\n\nstatic inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat )\n{\n    result->vec128 = negatef4( quat->vec128 );\n}\n\nstatic inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    return spu_extract( _vmathVfDot4( quat0->vec128, quat1->vec128 ), 0 );\n}\n\nstatic inline float vmathQNorm( const VmathQuat *quat )\n{\n    return spu_extract( _vmathVfDot4( quat->vec128, quat->vec128 ), 0 );\n}\n\nstatic inline float vmathQLength( const VmathQuat *quat )\n{\n    return sqrtf( vmathQNorm( quat ) );\n}\n\nstatic inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat )\n{\n    vec_float4 dot = _vmathVfDot4( quat->vec128, quat->vec128 );\n    result->vec128 = spu_mul( quat->vec128, rsqrtf4( dot ) );\n}\n\nstatic inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 )\n{\n    VmathVector3 crossVec, tmpV3_0;\n    vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res;\n    cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, (vec_uchar16)spu_splats(0x00010203) );\n    cosAngleX2Plus2 = spu_madd( cosAngle, spu_splats(2.0f), spu_splats(2.0f) );\n    recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 );\n    cosHalfAngleX2 = spu_mul( recipCosHalfAngleX2, cosAngleX2Plus2 );\n    vmathV3Cross( &tmpV3_0, unitVec0, unitVec1 );\n    crossVec = tmpV3_0;\n    res = spu_mul( crossVec.vec128, recipCosHalfAngleX2 );\n    res = spu_sel( res, spu_mul( cosHalfAngleX2, spu_splats(0.5f) ), (vec_uint4)spu_maskb(0x000f) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_mul( unitVec->vec128, s ), c, (vec_uint4)spu_maskb(0x000f) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationX( VmathQuat *result, float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0xf000) );\n    res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationY( VmathQuat *result, float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x0f00) );\n    res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMakeRotationZ( VmathQuat *result, float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x00f0) );\n    res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 )\n{\n    vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;\n    vec_float4 product, l_wxyz, r_wxyz, xy, qw;\n    ldata = quat0->vec128;\n    rdata = quat1->vec128;\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    tmp0 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_YZXW );\n    tmp1 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_ZXYW );\n    tmp2 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_YZXW );\n    qv = spu_mul( spu_shuffle( ldata, ldata, shuffle_wwww ), rdata );\n    qv = spu_madd( spu_shuffle( rdata, rdata, shuffle_wwww ), ldata, qv );\n    qv = spu_madd( tmp0, tmp1, qv );\n    qv = spu_nmsub( tmp2, tmp3, qv );\n    product = spu_mul( ldata, rdata );\n    l_wxyz = spu_rlqwbyte( ldata, 12 );\n    r_wxyz = spu_rlqwbyte( rdata, 12 );\n    qw = spu_nmsub( l_wxyz, r_wxyz, product );\n    xy = spu_madd( l_wxyz, r_wxyz, product );\n    qw = spu_sub( qw, spu_rlqwbyte( xy, 8 ) );\n    result->vec128 = spu_sel( qv, qw, (vec_uint4)spu_maskb( 0x000f ) );\n}\n\nstatic inline void vmathQRotate( VmathVector3 *result, const VmathQuat *quat, const VmathVector3 *vec )\n{\n    vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res;\n    qdata = quat->vec128;\n    vdata = vec->vec128;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    tmp0 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_YZXW );\n    tmp1 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_ZXYW );\n    tmp2 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_YZXW );\n    wwww = spu_shuffle( qdata, qdata, shuffle_wwww );\n    qv = spu_mul( wwww, vdata );\n    qv = spu_madd( tmp0, tmp1, qv );\n    qv = spu_nmsub( tmp2, tmp3, qv );\n    product = spu_mul( qdata, vdata );\n    qw = spu_madd( spu_rlqwbyte( qdata, 4 ), spu_rlqwbyte( vdata, 4 ), product );\n    qw = spu_add( spu_rlqwbyte( product, 8 ), qw );\n    tmp1 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_YZXW );\n    res = spu_mul( spu_shuffle( qw, qw, shuffle_xxxx ), qdata );\n    res = spu_madd( wwww, qv, res );\n    res = spu_madd( tmp0, tmp1, res );\n    res = spu_nmsub( tmp2, tmp3, res );\n    result->vec128 = res;\n}\n\nstatic inline void vmathQConj( VmathQuat *result, const VmathQuat *quat )\n{\n    result->vec128 = spu_xor( quat->vec128, ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) );\n}\n\nstatic inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 )\n{\n    result->vec128 = spu_sel( quat0->vec128, quat1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathQPrint( const VmathQuat *quat )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat->vec128;\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\nstatic inline void vmathQPrints( const VmathQuat *quat, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat->vec128;\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/quat_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_V_C_H\n#define _VECTORMATH_QUAT_AOS_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathQuat vmathQMakeFromElems_V( float _x, float _y, float _z, float _w )\n{\n    VmathQuat result;\n    vmathQMakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float _w )\n{\n    VmathQuat result;\n    vmathQMakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec )\n{\n    VmathQuat result;\n    vmathQMakeFromV4(&result, &vec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFromScalar_V( float scalar )\n{\n    VmathQuat result;\n    vmathQMakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 )\n{\n    VmathQuat result;\n    vmathQMakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeIdentity_V( )\n{\n    VmathQuat result;\n    vmathQMakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQLerp(&result, t, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 )\n{\n    VmathQuat result;\n    vmathQSlerp(&result, t, &unitQuat0, &unitQuat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 )\n{\n    VmathQuat result;\n    vmathQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3);\n    return result;\n}\n\nstatic inline vec_float4 vmathQGet128_V( VmathQuat quat )\n{\n    return vmathQGet128(&quat);\n}\n\nstatic inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec )\n{\n    vmathQSetXYZ(result, &vec);\n}\n\nstatic inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat )\n{\n    VmathVector3 result;\n    vmathQGetXYZ(&result, &quat);\n    return result;\n}\n\nstatic inline void vmathQSetX_V( VmathQuat *result, float _x )\n{\n    vmathQSetX(result, _x);\n}\n\nstatic inline float vmathQGetX_V( VmathQuat quat )\n{\n    return vmathQGetX(&quat);\n}\n\nstatic inline void vmathQSetY_V( VmathQuat *result, float _y )\n{\n    vmathQSetY(result, _y);\n}\n\nstatic inline float vmathQGetY_V( VmathQuat quat )\n{\n    return vmathQGetY(&quat);\n}\n\nstatic inline void vmathQSetZ_V( VmathQuat *result, float _z )\n{\n    vmathQSetZ(result, _z);\n}\n\nstatic inline float vmathQGetZ_V( VmathQuat quat )\n{\n    return vmathQGetZ(&quat);\n}\n\nstatic inline void vmathQSetW_V( VmathQuat *result, float _w )\n{\n    vmathQSetW(result, _w);\n}\n\nstatic inline float vmathQGetW_V( VmathQuat quat )\n{\n    return vmathQGetW(&quat);\n}\n\nstatic inline void vmathQSetElem_V( VmathQuat *result, int idx, float value )\n{\n    vmathQSetElem(result, idx, value);\n}\n\nstatic inline float vmathQGetElem_V( VmathQuat quat, int idx )\n{\n    return vmathQGetElem(&quat, idx);\n}\n\nstatic inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQAdd(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQSub(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar )\n{\n    VmathQuat result;\n    vmathQScalarMul(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar )\n{\n    VmathQuat result;\n    vmathQScalarDiv(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathQuat vmathQNeg_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQNeg(&result, &quat);\n    return result;\n}\n\nstatic inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    return vmathQDot(&quat0, &quat1);\n}\n\nstatic inline float vmathQNorm_V( VmathQuat quat )\n{\n    return vmathQNorm(&quat);\n}\n\nstatic inline float vmathQLength_V( VmathQuat quat )\n{\n    return vmathQLength(&quat);\n}\n\nstatic inline VmathQuat vmathQNormalize_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQNormalize(&result, &quat);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 )\n{\n    VmathQuat result;\n    vmathQMakeRotationArc(&result, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec )\n{\n    VmathQuat result;\n    vmathQMakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationX_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationY_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMakeRotationZ_V( float radians )\n{\n    VmathQuat result;\n    vmathQMakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 )\n{\n    VmathQuat result;\n    vmathQMul(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathQRotate_V( VmathQuat quat, VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathQRotate(&result, &quat, &vec);\n    return result;\n}\n\nstatic inline VmathQuat vmathQConj_V( VmathQuat quat )\n{\n    VmathQuat result;\n    vmathQConj(&result, &quat);\n    return result;\n}\n\nstatic inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 )\n{\n    VmathQuat result;\n    vmathQSelect(&result, &quat0, &quat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathQPrint_V( VmathQuat quat )\n{\n    vmathQPrint(&quat);\n}\n\nstatic inline void vmathQPrints_V( VmathQuat quat, const char *name )\n{\n    vmathQPrints(&quat, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/quat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_SOA_C_H\n#define _VECTORMATH_QUAT_SOA_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    result->x = quat->x;\n    result->y = quat->y;\n    result->z = quat->z;\n    result->w = quat->w;\n}\n\nstatic inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n    result->w = _w;\n}\n\nstatic inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 _w )\n{\n    vmathSoaQSetXYZ( result, xyz );\n    vmathSoaQSetW( result, _w );\n}\n\nstatic inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = vec->w;\n}\n\nstatic inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n    result->w = scalar;\n}\n\nstatic inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    vec_float4 vec128 = quat->vec128;\n    result->x = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    result->y = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    result->z = spu_shuffle( vec128, vec128, shuffle_zzzz );\n    result->w = spu_shuffle( vec128, vec128, shuffle_wwww );\n}\n\nstatic inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( quat0->vec128, quat2->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( quat1->vec128, quat3->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( quat0->vec128, quat2->vec128, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( quat1->vec128, quat3->vec128, _VECTORMATH_SHUF_ZCWD );\n    result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n    result->w = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD );\n}\n\nstatic inline void vmathSoaQMakeIdentity( VmathSoaQuat *result )\n{\n    vmathSoaQMakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    VmathSoaQuat tmpQ_0, tmpQ_1;\n    vmathSoaQSub( &tmpQ_0, quat1, quat0 );\n    vmathSoaQScalarMul( &tmpQ_1, &tmpQ_0, t );\n    vmathSoaQAdd( result, quat0, &tmpQ_1 );\n}\n\nstatic inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 )\n{\n    VmathSoaQuat start, tmpQ_0, tmpQ_1;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = vmathSoaQDot( unitQuat0, unitQuat1 );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle );\n    cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    vmathSoaQSetX( &start, spu_sel( unitQuat0->x, negatef4( unitQuat0->x ), selectMask ) );\n    vmathSoaQSetY( &start, spu_sel( unitQuat0->y, negatef4( unitQuat0->y ), selectMask ) );\n    vmathSoaQSetZ( &start, spu_sel( unitQuat0->z, negatef4( unitQuat0->z ), selectMask ) );\n    vmathSoaQSetW( &start, spu_sel( unitQuat0->w, negatef4( unitQuat0->w ), selectMask ) );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = recipf4( sinf4( angle ) );\n    scale0 = spu_sel( spu_sub( spu_splats(1.0f), t ), spu_mul( sinf4( spu_mul( spu_sub( spu_splats(1.0f), t ), angle ) ), recipSinAngle ), selectMask );\n    scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask );\n    vmathSoaQScalarMul( &tmpQ_0, &start, scale0 );\n    vmathSoaQScalarMul( &tmpQ_1, unitQuat1, scale1 );\n    vmathSoaQAdd( result, &tmpQ_0, &tmpQ_1 );\n}\n\nstatic inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 )\n{\n    VmathSoaQuat tmp0, tmp1;\n    vmathSoaQSlerp( &tmp0, t, unitQuat0, unitQuat3 );\n    vmathSoaQSlerp( &tmp1, t, unitQuat1, unitQuat2 );\n    vmathSoaQSlerp( result, spu_mul( spu_mul( spu_splats(2.0f), t ), spu_sub( spu_splats(1.0f), t ) ), &tmp0, &tmp1 );\n}\n\nstatic inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( quat->x, quat->z, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( quat->y, quat->w, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( quat->x, quat->z, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( quat->y, quat->w, _VECTORMATH_SHUF_ZCWD );\n    vmathQMakeFrom128( result0, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) );\n    vmathQMakeFrom128( result1, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) );\n    vmathQMakeFrom128( result2, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) );\n    vmathQMakeFrom128( result3, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) );\n}\n\nstatic inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat )\n{\n    vmathSoaV3MakeFromElems( result, quat->x, quat->y, quat->z );\n}\n\nstatic inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat )\n{\n    return quat->x;\n}\n\nstatic inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat )\n{\n    return quat->y;\n}\n\nstatic inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat )\n{\n    return quat->z;\n}\n\nstatic inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 _w )\n{\n    result->w = _w;\n}\n\nstatic inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat )\n{\n    return quat->w;\n}\n\nstatic inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx )\n{\n    return *(&quat->x + idx);\n}\n\nstatic inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    result->x = spu_add( quat0->x, quat1->x );\n    result->y = spu_add( quat0->y, quat1->y );\n    result->z = spu_add( quat0->z, quat1->z );\n    result->w = spu_add( quat0->w, quat1->w );\n}\n\nstatic inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    result->x = spu_sub( quat0->x, quat1->x );\n    result->y = spu_sub( quat0->y, quat1->y );\n    result->z = spu_sub( quat0->z, quat1->z );\n    result->w = spu_sub( quat0->w, quat1->w );\n}\n\nstatic inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar )\n{\n    result->x = spu_mul( quat->x, scalar );\n    result->y = spu_mul( quat->y, scalar );\n    result->z = spu_mul( quat->z, scalar );\n    result->w = spu_mul( quat->w, scalar );\n}\n\nstatic inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar )\n{\n    result->x = divf4( quat->x, scalar );\n    result->y = divf4( quat->y, scalar );\n    result->z = divf4( quat->z, scalar );\n    result->w = divf4( quat->w, scalar );\n}\n\nstatic inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    result->x = negatef4( quat->x );\n    result->y = negatef4( quat->y );\n    result->z = negatef4( quat->z );\n    result->w = negatef4( quat->w );\n}\n\nstatic inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    vec_float4 result;\n    result = spu_mul( quat0->x, quat1->x );\n    result = spu_add( result, spu_mul( quat0->y, quat1->y ) );\n    result = spu_add( result, spu_mul( quat0->z, quat1->z ) );\n    result = spu_add( result, spu_mul( quat0->w, quat1->w ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat )\n{\n    vec_float4 result;\n    result = spu_mul( quat->x, quat->x );\n    result = spu_add( result, spu_mul( quat->y, quat->y ) );\n    result = spu_add( result, spu_mul( quat->z, quat->z ) );\n    result = spu_add( result, spu_mul( quat->w, quat->w ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat )\n{\n    return sqrtf4( vmathSoaQNorm( quat ) );\n}\n\nstatic inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = vmathSoaQNorm( quat );\n    lenInv = rsqrtf4( lenSqr );\n    result->x = spu_mul( quat->x, lenInv );\n    result->y = spu_mul( quat->y, lenInv );\n    result->z = spu_mul( quat->z, lenInv );\n    result->w = spu_mul( quat->w, lenInv );\n}\n\nstatic inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vec_float4 cosHalfAngleX2, recipCosHalfAngleX2;\n    cosHalfAngleX2 = sqrtf4( spu_mul( spu_splats(2.0f), spu_add( spu_splats(1.0f), vmathSoaV3Dot( unitVec0, unitVec1 ) ) ) );\n    recipCosHalfAngleX2 = recipf4( cosHalfAngleX2 );\n    vmathSoaV3Cross( &tmpV3_0, unitVec0, unitVec1 );\n    vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 );\n    vmathSoaQMakeFromV3Scalar( result, &tmpV3_1, spu_mul( cosHalfAngleX2, spu_splats(0.5f) ) );\n}\n\nstatic inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec )\n{\n    VmathSoaVector3 tmpV3_0;\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    vmathSoaV3ScalarMul( &tmpV3_0, unitVec, s );\n    vmathSoaQMakeFromV3Scalar( result, &tmpV3_0, c );\n}\n\nstatic inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    vmathSoaQMakeFromElems( result, s, spu_splats(0.0f), spu_splats(0.0f), c );\n}\n\nstatic inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    vmathSoaQMakeFromElems( result, spu_splats(0.0f), s, spu_splats(0.0f), c );\n}\n\nstatic inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    vmathSoaQMakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), s, c );\n}\n\nstatic inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = spu_sub( spu_add( spu_add( spu_mul( quat0->w, quat1->x ), spu_mul( quat0->x, quat1->w ) ), spu_mul( quat0->y, quat1->z ) ), spu_mul( quat0->z, quat1->y ) );\n    tmpY = spu_sub( spu_add( spu_add( spu_mul( quat0->w, quat1->y ), spu_mul( quat0->y, quat1->w ) ), spu_mul( quat0->z, quat1->x ) ), spu_mul( quat0->x, quat1->z ) );\n    tmpZ = spu_sub( spu_add( spu_add( spu_mul( quat0->w, quat1->z ), spu_mul( quat0->z, quat1->w ) ), spu_mul( quat0->x, quat1->y ) ), spu_mul( quat0->y, quat1->x ) );\n    tmpW = spu_sub( spu_sub( spu_sub( spu_mul( quat0->w, quat1->w ), spu_mul( quat0->x, quat1->x ) ), spu_mul( quat0->y, quat1->y ) ), spu_mul( quat0->z, quat1->z ) );\n    vmathSoaQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );\n}\n\nstatic inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *quat, const VmathSoaVector3 *vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = spu_sub( spu_add( spu_mul( quat->w, vec->x ), spu_mul( quat->y, vec->z ) ), spu_mul( quat->z, vec->y ) );\n    tmpY = spu_sub( spu_add( spu_mul( quat->w, vec->y ), spu_mul( quat->z, vec->x ) ), spu_mul( quat->x, vec->z ) );\n    tmpZ = spu_sub( spu_add( spu_mul( quat->w, vec->z ), spu_mul( quat->x, vec->y ) ), spu_mul( quat->y, vec->x ) );\n    tmpW = spu_add( spu_add( spu_mul( quat->x, vec->x ), spu_mul( quat->y, vec->y ) ), spu_mul( quat->z, vec->z ) );\n    result->x = spu_add( spu_sub( spu_add( spu_mul( tmpW, quat->x ), spu_mul( tmpX, quat->w ) ), spu_mul( tmpY, quat->z ) ), spu_mul( tmpZ, quat->y ) );\n    result->y = spu_add( spu_sub( spu_add( spu_mul( tmpW, quat->y ), spu_mul( tmpY, quat->w ) ), spu_mul( tmpZ, quat->x ) ), spu_mul( tmpX, quat->z ) );\n    result->z = spu_add( spu_sub( spu_add( spu_mul( tmpW, quat->z ), spu_mul( tmpZ, quat->w ) ), spu_mul( tmpX, quat->y ) ), spu_mul( tmpY, quat->x ) );\n}\n\nstatic inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat )\n{\n    vmathSoaQMakeFromElems( result, negatef4( quat->x ), negatef4( quat->y ), negatef4( quat->z ), quat->w );\n}\n\nstatic inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 )\n{\n    result->x = spu_sel( quat0->x, quat1->x, select1 );\n    result->y = spu_sel( quat0->y, quat1->y, select1 );\n    result->z = spu_sel( quat0->z, quat1->z, select1 );\n    result->w = spu_sel( quat0->w, quat1->w, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaQPrint( const VmathSoaQuat *quat )\n{\n    VmathQuat vec0, vec1, vec2, vec3;\n    vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathQPrint( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathQPrint( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathQPrint( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathQPrint( &vec3 );\n}\n\nstatic inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name )\n{\n    VmathQuat vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathQPrint( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathQPrint( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathQPrint( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathQPrint( &vec3 );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/quat_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_SOA_V_C_H\n#define _VECTORMATH_QUAT_SOA_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromV4(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFromAos(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeFrom4Aos(&result, &quat0, &quat1, &quat2, &quat3);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeIdentity_V( )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeIdentity(&result);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQLerp(&result, t, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSlerp(&result, t, &unitQuat0, &unitQuat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3);\n    return result;\n}\n\nstatic inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 )\n{\n    vmathSoaQGet4Aos(&quat, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec )\n{\n    vmathSoaQSetXYZ(result, &vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat )\n{\n    VmathSoaVector3 result;\n    vmathSoaQGetXYZ(&result, &quat);\n    return result;\n}\n\nstatic inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 _x )\n{\n    vmathSoaQSetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetX(&quat);\n}\n\nstatic inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 _y )\n{\n    vmathSoaQSetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetY(&quat);\n}\n\nstatic inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 _z )\n{\n    vmathSoaQSetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetZ(&quat);\n}\n\nstatic inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 _w )\n{\n    vmathSoaQSetW(result, _w);\n}\n\nstatic inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat )\n{\n    return vmathSoaQGetW(&quat);\n}\n\nstatic inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value )\n{\n    vmathSoaQSetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx )\n{\n    return vmathSoaQGetElem(&quat, idx);\n}\n\nstatic inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQAdd(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSub(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar )\n{\n    VmathSoaQuat result;\n    vmathSoaQScalarMul(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar )\n{\n    VmathSoaQuat result;\n    vmathSoaQScalarDiv(&result, &quat, scalar);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQNeg(&result, &quat);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    return vmathSoaQDot(&quat0, &quat1);\n}\n\nstatic inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat )\n{\n    return vmathSoaQNorm(&quat);\n}\n\nstatic inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat )\n{\n    return vmathSoaQLength(&quat);\n}\n\nstatic inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQNormalize(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationArc(&result, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationAxis(&result, radians, &unitVec);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationX(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationY(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians )\n{\n    VmathSoaQuat result;\n    vmathSoaQMakeRotationZ(&result, radians);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQMul(&result, &quat0, &quat1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat quat, VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaQRotate(&result, &quat, &vec);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat )\n{\n    VmathSoaQuat result;\n    vmathSoaQConj(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 )\n{\n    VmathSoaQuat result;\n    vmathSoaQSelect(&result, &quat0, &quat1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaQPrint_V( VmathSoaQuat quat )\n{\n    vmathSoaQPrint(&quat);\n}\n\nstatic inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name )\n{\n    vmathSoaQPrints(&quat, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_C_H\n#define _VECTORMATH_VEC_AOS_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_SHUF_X 0x00010203\n#define _VECTORMATH_SHUF_Y 0x04050607\n#define _VECTORMATH_SHUF_Z 0x08090a0b\n#define _VECTORMATH_SHUF_W 0x0c0d0e0f\n#define _VECTORMATH_SHUF_A 0x10111213\n#define _VECTORMATH_SHUF_B 0x14151617\n#define _VECTORMATH_SHUF_C 0x18191a1b\n#define _VECTORMATH_SHUF_D 0x1c1d1e1f\n#define _VECTORMATH_SHUF_0 0x80808080\n#define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A }\n#define _VECTORMATH_SHUF_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_W }\n#define _VECTORMATH_SHUF_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W }\n#define _VECTORMATH_SHUF_WABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C }\n#define _VECTORMATH_SHUF_ZWAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }\n#define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A }\n#define _VECTORMATH_SHUF_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }\n#define _VECTORMATH_SHUF_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C }\n#define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\nstatic inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0, vec1 );\n    result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );\n    return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0, vec1 );\n    result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );\n    return spu_add( spu_rlqwbyte( result, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, result;\n    tmp0 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_YZXW );\n    tmp1 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_ZXYW );\n    tmp2 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_YZXW );\n    result = spu_mul( tmp0, tmp1 );\n    result = spu_nmsub( tmp2, tmp3, result );\n    return result;\n}\n\nstatic inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v)\n{\n    vec_int4 bexp;\n    vec_uint4 mant, sign, hfloat;\n    vec_uint4 notZero, isInf;\n    const vec_uint4 hfloatInf = spu_splats(0x00007c00u);\n    const vec_uint4 mergeMant = spu_splats(0x000003ffu);\n    const vec_uint4 mergeSign = spu_splats(0x00008000u);\n\n    sign = spu_rlmask((vec_uint4)v, -16);\n    mant = spu_rlmask((vec_uint4)v, -13);\n    bexp = spu_and(spu_rlmask((vec_int4)v, -23), 0xff);\n\n    notZero = spu_cmpgt(bexp, 112);\n    isInf = spu_cmpgt(bexp, 142);\n\n    bexp = spu_add(bexp, -112);\n    bexp = spu_sl(bexp, 10);\n\n    hfloat = spu_sel((vec_uint4)bexp, mant, mergeMant);\n    hfloat = spu_sel(spu_splats(0u), hfloat, notZero);\n    hfloat = spu_sel(hfloat, hfloatInf, isInf);\n    hfloat = spu_sel(hfloat, sign, mergeSign);\n\n    return hfloat;\n}\n\nstatic inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v)\n{\n    vec_uint4 hfloat_u, hfloat_v;\n    const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31};\n    hfloat_u = _vmathVfToHalfFloatsUnpacked(u);\n    hfloat_v = _vmathVfToHalfFloatsUnpacked(v);\n    return (vec_ushort8)spu_shuffle(hfloat_u, hfloat_v, pack);\n}\n\n#endif\n\nstatic inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathV3MakeFromElems( VmathVector3 *result, float _x, float _y, float _z )\n{\n    result->vec128 = (vec_float4){ _x, _y, _z, 0.0f  };\n}\n\nstatic inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = pnt->vec128;\n}\n\nstatic inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar )\n{\n    result->vec128 = spu_splats( scalar );\n}\n\nstatic inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathV3MakeXAxis( VmathVector3 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_1000;\n}\n\nstatic inline void vmathV3MakeYAxis( VmathVector3 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0100;\n}\n\nstatic inline void vmathV3MakeZAxis( VmathVector3 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0010;\n}\n\nstatic inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    vmathV3Sub( &tmpV3_0, vec1, vec0 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathV3Add( result, vec0, &tmpV3_1 );\n}\n\nstatic inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = spu_splats(t);\n    oneMinusT = spu_sub( spu_splats(1.0f), tttt );\n    angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) );\n    angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) );\n    angles = spu_mul( angles, angle );\n    sines = sinf4( angles );\n    scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) );\n    scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask );\n    scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask );\n    result->vec128 = spu_madd( unitVec0->vec128, scale0, spu_mul( unitVec1->vec128, scale1 ) );\n}\n\nstatic inline vec_float4 vmathV3Get128( const VmathVector3 *vec )\n{\n    return vec->vec128;\n}\n\nstatic inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = (vec_uint4)spu_maskb(0x000f);\n    dstVec = spu_sel(vec->vec128, dstVec, mask);\n    *quad = dstVec;\n}\n\nstatic inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC );\n    xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB );\n    xyz3 = spu_rlqwbyte( zxyz, 4 );\n    vec0->vec128 = xyzx;\n    vec1->vec128 = xyz1;\n    vec2->vec128 = xyz2;\n    vec3->vec128 = xyz3;\n}\n\nstatic inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = spu_shuffle( vec0->vec128, vec1->vec128, _VECTORMATH_SHUF_XYZA );\n    yzxy = spu_shuffle( vec1->vec128, vec2->vec128, _VECTORMATH_SHUF_YZAB );\n    zxyz = spu_shuffle( vec2->vec128, vec3->vec128, _VECTORMATH_SHUF_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathV3StoreHalfFloats( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, const VmathVector3 *vec4, const VmathVector3 *vec5, const VmathVector3 *vec6, const VmathVector3 *vec7, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathV3StoreXYZArray( vec0, vec1, vec2, vec3, xyz0 );\n    vmathV3StoreXYZArray( vec4, vec5, vec6, vec7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathV3SetX( VmathVector3 *result, float _x )\n{\n    result->vec128 = spu_insert( _x, result->vec128, 0 );\n}\n\nstatic inline float vmathV3GetX( const VmathVector3 *vec )\n{\n    return spu_extract( vec->vec128, 0 );\n}\n\nstatic inline void vmathV3SetY( VmathVector3 *result, float _y )\n{\n    result->vec128 = spu_insert( _y, result->vec128, 1 );\n}\n\nstatic inline float vmathV3GetY( const VmathVector3 *vec )\n{\n    return spu_extract( vec->vec128, 1 );\n}\n\nstatic inline void vmathV3SetZ( VmathVector3 *result, float _z )\n{\n    result->vec128 = spu_insert( _z, result->vec128, 2 );\n}\n\nstatic inline float vmathV3GetZ( const VmathVector3 *vec )\n{\n    return spu_extract( vec->vec128, 2 );\n}\n\nstatic inline void vmathV3SetElem( VmathVector3 *result, int idx, float value )\n{\n    result->vec128 = spu_insert( value, result->vec128, idx );\n}\n\nstatic inline float vmathV3GetElem( const VmathVector3 *vec, int idx )\n{\n    return spu_extract( vec->vec128, idx );\n}\n\nstatic inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = spu_add( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = spu_sub( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = spu_add( vec->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar )\n{\n    result->vec128 = spu_mul( vec->vec128, spu_splats(scalar) );\n}\n\nstatic inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar )\n{\n    result->vec128 = divf4( vec->vec128, spu_splats(scalar) );\n}\n\nstatic inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = negatef4( vec->vec128 );\n}\n\nstatic inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = spu_mul( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = divf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = recipf4( vec->vec128 );\n}\n\nstatic inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = sqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = rsqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = fabsf4( vec->vec128 );\n}\n\nstatic inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = copysignf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV3MaxElem( const VmathVector3 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 );\n    result = fmaxf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\nstatic inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = fminf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV3MinElem( const VmathVector3 *vec )\n{\n    vec_float4 result;\n    result = fminf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 );\n    result = fminf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\nstatic inline float vmathV3Sum( const VmathVector3 *vec )\n{\n    return\n        spu_extract( vec->vec128, 0 ) +\n        spu_extract( vec->vec128, 1 ) +\n        spu_extract( vec->vec128, 2 );\n}\n\nstatic inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    return spu_extract( _vmathVfDot3( vec0->vec128, vec1->vec128 ), 0 );\n}\n\nstatic inline float vmathV3LengthSqr( const VmathVector3 *vec )\n{\n    return spu_extract( _vmathVfDot3( vec->vec128, vec->vec128 ), 0 );\n}\n\nstatic inline float vmathV3Length( const VmathVector3 *vec )\n{\n    return sqrtf( vmathV3LengthSqr( vec ) );\n}\n\nstatic inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec )\n{\n    vec_float4 dot = _vmathVfDot3( vec->vec128, vec->vec128 );\n    dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) );\n    result->vec128 = spu_mul( vec->vec128, rsqrtf4( dot ) );\n}\n\nstatic inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 )\n{\n    result->vec128 = _vmathVfCross( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 )\n{\n    result->vec128 = spu_sel( vec0->vec128, vec1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV3Print( const VmathVector3 *vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\nstatic inline void vmathV3Prints( const VmathVector3 *vec, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\nstatic inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathV4MakeFromElems( VmathVector4 *result, float _x, float _y, float _z, float _w )\n{\n    result->vec128 = (vec_float4){ _x, _y, _z, _w };\n}\n\nstatic inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float _w )\n{\n    result->vec128 = spu_shuffle( xyz->vec128, spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA );\n}\n\nstatic inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec )\n{\n    result->vec128 = spu_sel( vec->vec128, spu_splats(0.0f), (vec_uint4)spu_maskb(0x000f) );\n}\n\nstatic inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = spu_sel( pnt->vec128, spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) );\n}\n\nstatic inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat )\n{\n    result->vec128 = quat->vec128;\n}\n\nstatic inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar )\n{\n    result->vec128 = spu_splats( scalar );\n}\n\nstatic inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathV4MakeXAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_1000;\n}\n\nstatic inline void vmathV4MakeYAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0100;\n}\n\nstatic inline void vmathV4MakeZAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0010;\n}\n\nstatic inline void vmathV4MakeWAxis( VmathVector4 *result )\n{\n    result->vec128 = _VECTORMATH_UNIT_0001;\n}\n\nstatic inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    VmathVector4 tmpV4_0, tmpV4_1;\n    vmathV4Sub( &tmpV4_0, vec1, vec0 );\n    vmathV4ScalarMul( &tmpV4_1, &tmpV4_0, t );\n    vmathV4Add( result, vec0, &tmpV4_1 );\n}\n\nstatic inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    cosAngle = _vmathVfDot4( unitVec0->vec128, unitVec1->vec128 );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = spu_splats(t);\n    oneMinusT = spu_sub( spu_splats(1.0f), tttt );\n    angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) );\n    angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) );\n    angles = spu_mul( angles, angle );\n    sines = sinf4( angles );\n    scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) );\n    scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask );\n    scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask );\n    result->vec128 = spu_madd( unitVec0->vec128, scale0, spu_mul( unitVec1->vec128, scale1 ) );\n}\n\nstatic inline vec_float4 vmathV4Get128( const VmathVector4 *vec )\n{\n    return vec->vec128;\n}\n\nstatic inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads )\n{\n    twoQuads[0] = _vmath2VfToHalfFloats(vec0->vec128, vec1->vec128);\n    twoQuads[1] = _vmath2VfToHalfFloats(vec2->vec128, vec3->vec128);\n}\n\nstatic inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec )\n{\n    result->vec128 = spu_sel( vec->vec128, result->vec128, (vec_uint4)spu_maskb(0x000f) );\n}\n\nstatic inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathV4SetX( VmathVector4 *result, float _x )\n{\n    result->vec128 = spu_insert( _x, result->vec128, 0 );\n}\n\nstatic inline float vmathV4GetX( const VmathVector4 *vec )\n{\n    return spu_extract( vec->vec128, 0 );\n}\n\nstatic inline void vmathV4SetY( VmathVector4 *result, float _y )\n{\n    result->vec128 = spu_insert( _y, result->vec128, 1 );\n}\n\nstatic inline float vmathV4GetY( const VmathVector4 *vec )\n{\n    return spu_extract( vec->vec128, 1 );\n}\n\nstatic inline void vmathV4SetZ( VmathVector4 *result, float _z )\n{\n    result->vec128 = spu_insert( _z, result->vec128, 2 );\n}\n\nstatic inline float vmathV4GetZ( const VmathVector4 *vec )\n{\n    return spu_extract( vec->vec128, 2 );\n}\n\nstatic inline void vmathV4SetW( VmathVector4 *result, float _w )\n{\n    result->vec128 = spu_insert( _w, result->vec128, 3 );\n}\n\nstatic inline float vmathV4GetW( const VmathVector4 *vec )\n{\n    return spu_extract( vec->vec128, 3 );\n}\n\nstatic inline void vmathV4SetElem( VmathVector4 *result, int idx, float value )\n{\n    result->vec128 = spu_insert( value, result->vec128, idx );\n}\n\nstatic inline float vmathV4GetElem( const VmathVector4 *vec, int idx )\n{\n    return spu_extract( vec->vec128, idx );\n}\n\nstatic inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = spu_add( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = spu_sub( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar )\n{\n    result->vec128 = spu_mul( vec->vec128, spu_splats(scalar) );\n}\n\nstatic inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar )\n{\n    result->vec128 = divf4( vec->vec128, spu_splats(scalar) );\n}\n\nstatic inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = negatef4( vec->vec128 );\n}\n\nstatic inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = spu_mul( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = divf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = recipf4( vec->vec128 );\n}\n\nstatic inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = sqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = rsqrtf4( vec->vec128 );\n}\n\nstatic inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec )\n{\n    result->vec128 = fabsf4( vec->vec128 );\n}\n\nstatic inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = copysignf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV4MaxElem( const VmathVector4 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 );\n    result = fmaxf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result );\n    result = fmaxf4( spu_promote( spu_extract( vec->vec128, 3 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\nstatic inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    result->vec128 = fminf4( vec0->vec128, vec1->vec128 );\n}\n\nstatic inline float vmathV4MinElem( const VmathVector4 *vec )\n{\n    vec_float4 result;\n    result = fminf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 );\n    result = fminf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result );\n    result = fminf4( spu_promote( spu_extract( vec->vec128, 3 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\nstatic inline float vmathV4Sum( const VmathVector4 *vec )\n{\n    return\n        spu_extract( vec->vec128, 0 ) +\n        spu_extract( vec->vec128, 1 ) +\n        spu_extract( vec->vec128, 2 ) +\n        spu_extract( vec->vec128, 3 );\n}\n\nstatic inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 )\n{\n    return spu_extract( _vmathVfDot4( vec0->vec128, vec1->vec128 ), 0 );\n}\n\nstatic inline float vmathV4LengthSqr( const VmathVector4 *vec )\n{\n    return spu_extract( _vmathVfDot4( vec->vec128, vec->vec128 ), 0 );\n}\n\nstatic inline float vmathV4Length( const VmathVector4 *vec )\n{\n    return sqrtf( vmathV4LengthSqr( vec ) );\n}\n\nstatic inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec )\n{\n    vec_float4 dot = _vmathVfDot4( vec->vec128, vec->vec128 );\n    result->vec128 = spu_mul( vec->vec128, rsqrtf4( dot ) );\n}\n\nstatic inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 )\n{\n    result->vec128 = spu_sel( vec0->vec128, vec1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV4Print( const VmathVector4 *vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\nstatic inline void vmathV4Prints( const VmathVector4 *vec, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec->vec128;\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\nstatic inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = pnt->vec128;\n}\n\nstatic inline void vmathP3MakeFromElems( VmathPoint3 *result, float _x, float _y, float _z )\n{\n    result->vec128 = (vec_float4){ _x, _y, _z, 0.0f  };\n}\n\nstatic inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec )\n{\n    result->vec128 = vec->vec128;\n}\n\nstatic inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar )\n{\n    result->vec128 = spu_splats( scalar );\n}\n\nstatic inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 )\n{\n    result->vec128 = vf4;\n}\n\nstatic inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0, tmpV3_1;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathP3AddV3( result, pnt0, &tmpV3_1 );\n}\n\nstatic inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt )\n{\n    return pnt->vec128;\n}\n\nstatic inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = (vec_uint4)spu_maskb(0x000f);\n    dstVec = spu_sel(pnt->vec128, dstVec, mask);\n    *quad = dstVec;\n}\n\nstatic inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC );\n    xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB );\n    xyz3 = spu_rlqwbyte( zxyz, 4 );\n    pnt0->vec128 = xyzx;\n    pnt1->vec128 = xyz1;\n    pnt2->vec128 = xyz2;\n    pnt3->vec128 = xyz3;\n}\n\nstatic inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = spu_shuffle( pnt0->vec128, pnt1->vec128, _VECTORMATH_SHUF_XYZA );\n    yzxy = spu_shuffle( pnt1->vec128, pnt2->vec128, _VECTORMATH_SHUF_YZAB );\n    zxyz = spu_shuffle( pnt2->vec128, pnt3->vec128, _VECTORMATH_SHUF_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathP3StoreHalfFloats( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, const VmathPoint3 *pnt4, const VmathPoint3 *pnt5, const VmathPoint3 *pnt6, const VmathPoint3 *pnt7, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathP3StoreXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 );\n    vmathP3StoreXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathP3SetX( VmathPoint3 *result, float _x )\n{\n    result->vec128 = spu_insert( _x, result->vec128, 0 );\n}\n\nstatic inline float vmathP3GetX( const VmathPoint3 *pnt )\n{\n    return spu_extract( pnt->vec128, 0 );\n}\n\nstatic inline void vmathP3SetY( VmathPoint3 *result, float _y )\n{\n    result->vec128 = spu_insert( _y, result->vec128, 1 );\n}\n\nstatic inline float vmathP3GetY( const VmathPoint3 *pnt )\n{\n    return spu_extract( pnt->vec128, 1 );\n}\n\nstatic inline void vmathP3SetZ( VmathPoint3 *result, float _z )\n{\n    result->vec128 = spu_insert( _z, result->vec128, 2 );\n}\n\nstatic inline float vmathP3GetZ( const VmathPoint3 *pnt )\n{\n    return spu_extract( pnt->vec128, 2 );\n}\n\nstatic inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value )\n{\n    result->vec128 = spu_insert( value, result->vec128, idx );\n}\n\nstatic inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx )\n{\n    return spu_extract( pnt->vec128, idx );\n}\n\nstatic inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = spu_sub( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 )\n{\n    result->vec128 = spu_add( pnt->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 )\n{\n    result->vec128 = spu_sub( pnt->vec128, vec1->vec128 );\n}\n\nstatic inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = spu_mul( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = divf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = recipf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = sqrtf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = rsqrtf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt )\n{\n    result->vec128 = fabsf4( pnt->vec128 );\n}\n\nstatic inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = copysignf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = fmaxf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline float vmathP3MaxElem( const VmathPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( spu_promote( spu_extract( pnt->vec128, 1 ), 0 ), pnt->vec128 );\n    result = fmaxf4( spu_promote( spu_extract( pnt->vec128, 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\nstatic inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    result->vec128 = fminf4( pnt0->vec128, pnt1->vec128 );\n}\n\nstatic inline float vmathP3MinElem( const VmathPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fminf4( spu_promote( spu_extract( pnt->vec128, 1 ), 0 ), pnt->vec128 );\n    result = fminf4( spu_promote( spu_extract( pnt->vec128, 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\nstatic inline float vmathP3Sum( const VmathPoint3 *pnt )\n{\n    return\n        spu_extract( pnt->vec128, 0 ) +\n        spu_extract( pnt->vec128, 1 ) +\n        spu_extract( pnt->vec128, 2 );\n}\n\nstatic inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal )\n{\n    VmathPoint3 tmpP3_0;\n    vmathP3MakeFromScalar( &tmpP3_0, scaleVal );\n    vmathP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec )\n{\n    VmathPoint3 tmpP3_0;\n    vmathP3MakeFromV3( &tmpP3_0, scaleVec );\n    vmathP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec )\n{\n    return spu_extract( _vmathVfDot3( pnt->vec128, unitVec->vec128 ), 0 );\n}\n\nstatic inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt )\n{\n    VmathVector3 tmpV3_0;\n    vmathV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathV3Length( &tmpV3_0 );\n}\n\nstatic inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 )\n{\n    VmathVector3 tmpV3_0;\n    vmathP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathV3Length( &tmpV3_0 );\n}\n\nstatic inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 )\n{\n    result->vec128 = spu_sel( pnt0->vec128, pnt1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathP3Print( const VmathPoint3 *pnt )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt->vec128;\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\nstatic inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt->vec128;\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vec_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_V_C_H\n#define _VECTORMATH_VEC_AOS_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_SHUF_X 0x00010203\n#define _VECTORMATH_SHUF_Y 0x04050607\n#define _VECTORMATH_SHUF_Z 0x08090a0b\n#define _VECTORMATH_SHUF_W 0x0c0d0e0f\n#define _VECTORMATH_SHUF_A 0x10111213\n#define _VECTORMATH_SHUF_B 0x14151617\n#define _VECTORMATH_SHUF_C 0x18191a1b\n#define _VECTORMATH_SHUF_D 0x1c1d1e1f\n#define _VECTORMATH_SHUF_0 0x80808080\n#define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A }\n#define _VECTORMATH_SHUF_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_W }\n#define _VECTORMATH_SHUF_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W }\n#define _VECTORMATH_SHUF_WABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C }\n#define _VECTORMATH_SHUF_ZWAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }\n#define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A }\n#define _VECTORMATH_SHUF_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }\n#define _VECTORMATH_SHUF_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C }\n#define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathVector3 vmathV3MakeFromElems_V( float _x, float _y, float _z )\n{\n    VmathVector3 result;\n    vmathV3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt )\n{\n    VmathVector3 result;\n    vmathV3MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFromScalar_V( float scalar )\n{\n    VmathVector3 result;\n    vmathV3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 )\n{\n    VmathVector3 result;\n    vmathV3MakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeXAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeYAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MakeZAxis_V( )\n{\n    VmathVector3 result;\n    vmathV3MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 )\n{\n    VmathVector3 result;\n    vmathV3Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathV3Get128_V( VmathVector3 vec )\n{\n    return vmathV3Get128(&vec);\n}\n\nstatic inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad )\n{\n    vmathV3StoreXYZ(&vec, quad);\n}\n\nstatic inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads )\n{\n    vmathV3LoadXYZArray(vec0, vec1, vec2, vec3, threeQuads);\n}\n\nstatic inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads )\n{\n    vmathV3StoreXYZArray(&vec0, &vec1, &vec2, &vec3, threeQuads);\n}\n\nstatic inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads )\n{\n    vmathV3StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, &vec4, &vec5, &vec6, &vec7, threeQuads);\n}\n\nstatic inline void vmathV3SetX_V( VmathVector3 *result, float _x )\n{\n    vmathV3SetX(result, _x);\n}\n\nstatic inline float vmathV3GetX_V( VmathVector3 vec )\n{\n    return vmathV3GetX(&vec);\n}\n\nstatic inline void vmathV3SetY_V( VmathVector3 *result, float _y )\n{\n    vmathV3SetY(result, _y);\n}\n\nstatic inline float vmathV3GetY_V( VmathVector3 vec )\n{\n    return vmathV3GetY(&vec);\n}\n\nstatic inline void vmathV3SetZ_V( VmathVector3 *result, float _z )\n{\n    vmathV3SetZ(result, _z);\n}\n\nstatic inline float vmathV3GetZ_V( VmathVector3 vec )\n{\n    return vmathV3GetZ(&vec);\n}\n\nstatic inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value )\n{\n    vmathV3SetElem(result, idx, value);\n}\n\nstatic inline float vmathV3GetElem_V( VmathVector3 vec, int idx )\n{\n    return vmathV3GetElem(&vec, idx);\n}\n\nstatic inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathV3AddP3(&result, &vec, &pnt1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar )\n{\n    VmathVector3 result;\n    vmathV3ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar )\n{\n    VmathVector3 result;\n    vmathV3ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Neg_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV3MaxElem_V( VmathVector3 vec )\n{\n    return vmathV3MaxElem(&vec);\n}\n\nstatic inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV3MinElem_V( VmathVector3 vec )\n{\n    return vmathV3MinElem(&vec);\n}\n\nstatic inline float vmathV3Sum_V( VmathVector3 vec )\n{\n    return vmathV3Sum(&vec);\n}\n\nstatic inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    return vmathV3Dot(&vec0, &vec1);\n}\n\nstatic inline float vmathV3LengthSqr_V( VmathVector3 vec )\n{\n    return vmathV3LengthSqr(&vec);\n}\n\nstatic inline float vmathV3Length_V( VmathVector3 vec )\n{\n    return vmathV3Length(&vec);\n}\n\nstatic inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec )\n{\n    VmathVector3 result;\n    vmathV3Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 )\n{\n    VmathVector3 result;\n    vmathV3Cross(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 )\n{\n    VmathVector3 result;\n    vmathV3Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV3Print_V( VmathVector3 vec )\n{\n    vmathV3Print(&vec);\n}\n\nstatic inline void vmathV3Prints_V( VmathVector3 vec, const char *name )\n{\n    vmathV3Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathVector4 vmathV4MakeFromElems_V( float _x, float _y, float _z, float _w )\n{\n    VmathVector4 result;\n    vmathV4MakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float _w )\n{\n    VmathVector4 result;\n    vmathV4MakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec )\n{\n    VmathVector4 result;\n    vmathV4MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt )\n{\n    VmathVector4 result;\n    vmathV4MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat )\n{\n    VmathVector4 result;\n    vmathV4MakeFromQ(&result, &quat);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFromScalar_V( float scalar )\n{\n    VmathVector4 result;\n    vmathV4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 )\n{\n    VmathVector4 result;\n    vmathV4MakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeXAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeYAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeZAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MakeWAxis_V( )\n{\n    VmathVector4 result;\n    vmathV4MakeWAxis(&result);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 )\n{\n    VmathVector4 result;\n    vmathV4Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathV4Get128_V( VmathVector4 vec )\n{\n    return vmathV4Get128(&vec);\n}\n\nstatic inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads )\n{\n    vmathV4StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, twoQuads);\n}\n\nstatic inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec )\n{\n    vmathV4SetXYZ(result, &vec);\n}\n\nstatic inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec )\n{\n    VmathVector3 result;\n    vmathV4GetXYZ(&result, &vec);\n    return result;\n}\n\nstatic inline void vmathV4SetX_V( VmathVector4 *result, float _x )\n{\n    vmathV4SetX(result, _x);\n}\n\nstatic inline float vmathV4GetX_V( VmathVector4 vec )\n{\n    return vmathV4GetX(&vec);\n}\n\nstatic inline void vmathV4SetY_V( VmathVector4 *result, float _y )\n{\n    vmathV4SetY(result, _y);\n}\n\nstatic inline float vmathV4GetY_V( VmathVector4 vec )\n{\n    return vmathV4GetY(&vec);\n}\n\nstatic inline void vmathV4SetZ_V( VmathVector4 *result, float _z )\n{\n    vmathV4SetZ(result, _z);\n}\n\nstatic inline float vmathV4GetZ_V( VmathVector4 vec )\n{\n    return vmathV4GetZ(&vec);\n}\n\nstatic inline void vmathV4SetW_V( VmathVector4 *result, float _w )\n{\n    vmathV4SetW(result, _w);\n}\n\nstatic inline float vmathV4GetW_V( VmathVector4 vec )\n{\n    return vmathV4GetW(&vec);\n}\n\nstatic inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value )\n{\n    vmathV4SetElem(result, idx, value);\n}\n\nstatic inline float vmathV4GetElem_V( VmathVector4 vec, int idx )\n{\n    return vmathV4GetElem(&vec, idx);\n}\n\nstatic inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar )\n{\n    VmathVector4 result;\n    vmathV4ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar )\n{\n    VmathVector4 result;\n    vmathV4ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Neg_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV4MaxElem_V( VmathVector4 vec )\n{\n    return vmathV4MaxElem(&vec);\n}\n\nstatic inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    VmathVector4 result;\n    vmathV4MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline float vmathV4MinElem_V( VmathVector4 vec )\n{\n    return vmathV4MinElem(&vec);\n}\n\nstatic inline float vmathV4Sum_V( VmathVector4 vec )\n{\n    return vmathV4Sum(&vec);\n}\n\nstatic inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 )\n{\n    return vmathV4Dot(&vec0, &vec1);\n}\n\nstatic inline float vmathV4LengthSqr_V( VmathVector4 vec )\n{\n    return vmathV4LengthSqr(&vec);\n}\n\nstatic inline float vmathV4Length_V( VmathVector4 vec )\n{\n    return vmathV4Length(&vec);\n}\n\nstatic inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec )\n{\n    VmathVector4 result;\n    vmathV4Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 )\n{\n    VmathVector4 result;\n    vmathV4Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathV4Print_V( VmathVector4 vec )\n{\n    vmathV4Print(&vec);\n}\n\nstatic inline void vmathV4Prints_V( VmathVector4 vec, const char *name )\n{\n    vmathV4Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathPoint3 vmathP3MakeFromElems_V( float _x, float _y, float _z )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar )\n{\n    VmathPoint3 result;\n    vmathP3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 )\n{\n    VmathPoint3 result;\n    vmathP3MakeFrom128(&result, vf4);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3Lerp(&result, t, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt )\n{\n    return vmathP3Get128(&pnt);\n}\n\nstatic inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad )\n{\n    vmathP3StoreXYZ(&pnt, quad);\n}\n\nstatic inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads )\n{\n    vmathP3LoadXYZArray(pnt0, pnt1, pnt2, pnt3, threeQuads);\n}\n\nstatic inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads )\n{\n    vmathP3StoreXYZArray(&pnt0, &pnt1, &pnt2, &pnt3, threeQuads);\n}\n\nstatic inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads )\n{\n    vmathP3StoreHalfFloats(&pnt0, &pnt1, &pnt2, &pnt3, &pnt4, &pnt5, &pnt6, &pnt7, threeQuads);\n}\n\nstatic inline void vmathP3SetX_V( VmathPoint3 *result, float _x )\n{\n    vmathP3SetX(result, _x);\n}\n\nstatic inline float vmathP3GetX_V( VmathPoint3 pnt )\n{\n    return vmathP3GetX(&pnt);\n}\n\nstatic inline void vmathP3SetY_V( VmathPoint3 *result, float _y )\n{\n    vmathP3SetY(result, _y);\n}\n\nstatic inline float vmathP3GetY_V( VmathPoint3 pnt )\n{\n    return vmathP3GetY(&pnt);\n}\n\nstatic inline void vmathP3SetZ_V( VmathPoint3 *result, float _z )\n{\n    vmathP3SetZ(result, _z);\n}\n\nstatic inline float vmathP3GetZ_V( VmathPoint3 pnt )\n{\n    return vmathP3GetZ(&pnt);\n}\n\nstatic inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value )\n{\n    vmathP3SetElem(result, idx, value);\n}\n\nstatic inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx )\n{\n    return vmathP3GetElem(&pnt, idx);\n}\n\nstatic inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathVector3 result;\n    vmathP3Sub(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec1 )\n{\n    VmathPoint3 result;\n    vmathP3AddV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec1 )\n{\n    VmathPoint3 result;\n    vmathP3SubV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MulPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3DivPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3RecipPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3SqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3RsqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt )\n{\n    VmathPoint3 result;\n    vmathP3AbsPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3CopySignPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MaxPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline float vmathP3MaxElem_V( VmathPoint3 pnt )\n{\n    return vmathP3MaxElem(&pnt);\n}\n\nstatic inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    VmathPoint3 result;\n    vmathP3MinPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline float vmathP3MinElem_V( VmathPoint3 pnt )\n{\n    return vmathP3MinElem(&pnt);\n}\n\nstatic inline float vmathP3Sum_V( VmathPoint3 pnt )\n{\n    return vmathP3Sum(&pnt);\n}\n\nstatic inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal )\n{\n    VmathPoint3 result;\n    vmathP3Scale(&result, &pnt, scaleVal);\n    return result;\n}\n\nstatic inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec )\n{\n    VmathPoint3 result;\n    vmathP3NonUniformScale(&result, &pnt, &scaleVec);\n    return result;\n}\n\nstatic inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec )\n{\n    return vmathP3Projection(&pnt, &unitVec);\n}\n\nstatic inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt )\n{\n    return vmathP3DistSqrFromOrigin(&pnt);\n}\n\nstatic inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt )\n{\n    return vmathP3DistFromOrigin(&pnt);\n}\n\nstatic inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    return vmathP3DistSqr(&pnt0, &pnt1);\n}\n\nstatic inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 )\n{\n    return vmathP3Dist(&pnt0, &pnt1);\n}\n\nstatic inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 )\n{\n    VmathPoint3 result;\n    vmathP3Select(&result, &pnt0, &pnt1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathP3Print_V( VmathPoint3 pnt )\n{\n    vmathP3Print(&pnt);\n}\n\nstatic inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name )\n{\n    vmathP3Prints(&pnt, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vec_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_SOA_C_H\n#define _VECTORMATH_VEC_SOA_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_SHUF_X 0x00010203\n#define _VECTORMATH_SHUF_Y 0x04050607\n#define _VECTORMATH_SHUF_Z 0x08090a0b\n#define _VECTORMATH_SHUF_W 0x0c0d0e0f\n#define _VECTORMATH_SHUF_A 0x10111213\n#define _VECTORMATH_SHUF_B 0x14151617\n#define _VECTORMATH_SHUF_C 0x18191a1b\n#define _VECTORMATH_SHUF_D 0x1c1d1e1f\n#define _VECTORMATH_SHUF_0 0x80808080\n#define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_ZDW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZDXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YAWC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XYCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n}\n\nstatic inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n}\n\nstatic inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n}\n\nstatic inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_float4 vec128 = vec->vec128;\n    result->x = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    result->y = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    result->z = spu_shuffle( vec128, vec128, shuffle_zzzz );\n}\n\nstatic inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_ZCWD );\n    result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n}\n\nstatic inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result )\n{\n    vmathSoaV3MakeFromElems( result, spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result )\n{\n    vmathSoaV3MakeFromElems( result, spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result )\n{\n    vmathSoaV3MakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vmathSoaV3Sub( &tmpV3_0, vec1, vec0 );\n    vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathSoaV3Add( result, vec0, &tmpV3_1 );\n}\n\nstatic inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = vmathSoaV3Dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = recipf4( sinf4( angle ) );\n    scale0 = spu_sel( spu_sub( spu_splats(1.0f), t ), spu_mul( sinf4( spu_mul( spu_sub( spu_splats(1.0f), t ), angle ) ), recipSinAngle ), selectMask );\n    scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask );\n    vmathSoaV3ScalarMul( &tmpV3_0, unitVec0, scale0 );\n    vmathSoaV3ScalarMul( &tmpV3_1, unitVec1, scale1 );\n    vmathSoaV3Add( result, &tmpV3_0, &tmpV3_1 );\n}\n\nstatic inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 )\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_ZCWD );\n    vmathV3MakeFrom128( result0, spu_shuffle( tmp0, vec->y, _VECTORMATH_SHUF_XAYB ) );\n    vmathV3MakeFrom128( result1, spu_shuffle( tmp0, vec->y, _VECTORMATH_SHUF_ZBW0 ) );\n    vmathV3MakeFrom128( result2, spu_shuffle( tmp1, vec->y, _VECTORMATH_SHUF_XCY0 ) );\n    vmathV3MakeFrom128( result3, spu_shuffle( tmp1, vec->y, _VECTORMATH_SHUF_ZDW0 ) );\n}\n\nstatic inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD );\n    zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD );\n    yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD );\n    vmathSoaV3SetX( vec, spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) );\n    vmathSoaV3SetY( vec, spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) );\n    vmathSoaV3SetZ( vec, spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) );\n}\n\nstatic inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = spu_shuffle( vec->x, vec->y, _VECTORMATH_SHUF_XAZC );\n    zxzx = spu_shuffle( vec->z, vec->x, _VECTORMATH_SHUF_ZDXB );\n    yzyz = spu_shuffle( vec->y, vec->z, _VECTORMATH_SHUF_YBWD );\n    xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD );\n    yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD );\n    zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathSoaV3StoreXYZArray( vec0, xyz0 );\n    vmathSoaV3StoreXYZArray( vec1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec )\n{\n    return vec->x;\n}\n\nstatic inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec )\n{\n    return vec->y;\n}\n\nstatic inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec )\n{\n    return vec->z;\n}\n\nstatic inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx )\n{\n    return *(&vec->x + idx);\n}\n\nstatic inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = spu_add( vec0->x, vec1->x );\n    result->y = spu_add( vec0->y, vec1->y );\n    result->z = spu_add( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = spu_sub( vec0->x, vec1->x );\n    result->y = spu_sub( vec0->y, vec1->y );\n    result->z = spu_sub( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = spu_add( vec->x, pnt1->x );\n    result->y = spu_add( vec->y, pnt1->y );\n    result->z = spu_add( vec->z, pnt1->z );\n}\n\nstatic inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar )\n{\n    result->x = spu_mul( vec->x, scalar );\n    result->y = spu_mul( vec->y, scalar );\n    result->z = spu_mul( vec->z, scalar );\n}\n\nstatic inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar )\n{\n    result->x = divf4( vec->x, scalar );\n    result->y = divf4( vec->y, scalar );\n    result->z = divf4( vec->z, scalar );\n}\n\nstatic inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = negatef4( vec->x );\n    result->y = negatef4( vec->y );\n    result->z = negatef4( vec->z );\n}\n\nstatic inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = spu_mul( vec0->x, vec1->x );\n    result->y = spu_mul( vec0->y, vec1->y );\n    result->z = spu_mul( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = divf4( vec0->x, vec1->x );\n    result->y = divf4( vec0->y, vec1->y );\n    result->z = divf4( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = recipf4( vec->x );\n    result->y = recipf4( vec->y );\n    result->z = recipf4( vec->z );\n}\n\nstatic inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = sqrtf4( vec->x );\n    result->y = sqrtf4( vec->y );\n    result->z = sqrtf4( vec->z );\n}\n\nstatic inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = rsqrtf4( vec->x );\n    result->y = rsqrtf4( vec->y );\n    result->z = rsqrtf4( vec->z );\n}\n\nstatic inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = fabsf4( vec->x );\n    result->y = fabsf4( vec->y );\n    result->z = fabsf4( vec->z );\n}\n\nstatic inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = copysignf4( vec0->x, vec1->x );\n    result->y = copysignf4( vec0->y, vec1->y );\n    result->z = copysignf4( vec0->z, vec1->z );\n}\n\nstatic inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = fmaxf4( vec0->x, vec1->x );\n    result->y = fmaxf4( vec0->y, vec1->y );\n    result->z = fmaxf4( vec0->z, vec1->z );\n}\n\nstatic inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec->x, vec->y );\n    result = fmaxf4( vec->z, result );\n    return result;\n}\n\nstatic inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    result->x = fminf4( vec0->x, vec1->x );\n    result->y = fminf4( vec0->y, vec1->y );\n    result->z = fminf4( vec0->z, vec1->z );\n}\n\nstatic inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = fminf4( vec->x, vec->y );\n    result = fminf4( vec->z, result );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = spu_add( vec->x, vec->y );\n    result = spu_add( result, vec->z );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0->x, vec1->x );\n    result = spu_add( result, spu_mul( vec0->y, vec1->y ) );\n    result = spu_add( result, spu_mul( vec0->z, vec1->z ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec )\n{\n    vec_float4 result;\n    result = spu_mul( vec->x, vec->x );\n    result = spu_add( result, spu_mul( vec->y, vec->y ) );\n    result = spu_add( result, spu_mul( vec->z, vec->z ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec )\n{\n    return sqrtf4( vmathSoaV3LengthSqr( vec ) );\n}\n\nstatic inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = vmathSoaV3LengthSqr( vec );\n    lenInv = rsqrtf4( lenSqr );\n    result->x = spu_mul( vec->x, lenInv );\n    result->y = spu_mul( vec->y, lenInv );\n    result->z = spu_mul( vec->z, lenInv );\n}\n\nstatic inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 )\n{\n    vec_float4 tmpX, tmpY, tmpZ;\n    tmpX = spu_sub( spu_mul( vec0->y, vec1->z ), spu_mul( vec0->z, vec1->y ) );\n    tmpY = spu_sub( spu_mul( vec0->z, vec1->x ), spu_mul( vec0->x, vec1->z ) );\n    tmpZ = spu_sub( spu_mul( vec0->x, vec1->y ), spu_mul( vec0->y, vec1->x ) );\n    vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ );\n}\n\nstatic inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 )\n{\n    result->x = spu_sel( vec0->x, vec1->x, select1 );\n    result->y = spu_sel( vec0->y, vec1->y, select1 );\n    result->z = spu_sel( vec0->z, vec1->z, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV3Print( const VmathSoaVector3 *vec )\n{\n    VmathVector3 vec0, vec1, vec2, vec3;\n    vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV3Print( &vec3 );\n}\n\nstatic inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name )\n{\n    VmathVector3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV3Print( &vec3 );\n}\n\n#endif\n\nstatic inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = vec->w;\n}\n\nstatic inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n    result->w = _w;\n}\n\nstatic inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 _w )\n{\n    vmathSoaV4SetXYZ( result, xyz );\n    vmathSoaV4SetW( result, _w );\n}\n\nstatic inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n    result->w = spu_splats(0.0f);\n}\n\nstatic inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n    result->w = spu_splats(1.0f);\n}\n\nstatic inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat )\n{\n    result->x = quat->x;\n    result->y = quat->y;\n    result->z = quat->z;\n    result->w = quat->w;\n}\n\nstatic inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n    result->w = scalar;\n}\n\nstatic inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    vec_float4 vec128 = vec->vec128;\n    result->x = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    result->y = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    result->z = spu_shuffle( vec128, vec128, shuffle_zzzz );\n    result->w = spu_shuffle( vec128, vec128, shuffle_wwww );\n}\n\nstatic inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_ZCWD );\n    result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n    result->w = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD );\n}\n\nstatic inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) );\n}\n\nstatic inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result )\n{\n    vmathSoaV4MakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) );\n}\n\nstatic inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    VmathSoaVector4 tmpV4_0, tmpV4_1;\n    vmathSoaV4Sub( &tmpV4_0, vec1, vec0 );\n    vmathSoaV4ScalarMul( &tmpV4_1, &tmpV4_0, t );\n    vmathSoaV4Add( result, vec0, &tmpV4_1 );\n}\n\nstatic inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 )\n{\n    VmathSoaVector4 tmpV4_0, tmpV4_1;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = vmathSoaV4Dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = recipf4( sinf4( angle ) );\n    scale0 = spu_sel( spu_sub( spu_splats(1.0f), t ), spu_mul( sinf4( spu_mul( spu_sub( spu_splats(1.0f), t ), angle ) ), recipSinAngle ), selectMask );\n    scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask );\n    vmathSoaV4ScalarMul( &tmpV4_0, unitVec0, scale0 );\n    vmathSoaV4ScalarMul( &tmpV4_1, unitVec1, scale1 );\n    vmathSoaV4Add( result, &tmpV4_0, &tmpV4_1 );\n}\n\nstatic inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( vec->y, vec->w, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( vec->y, vec->w, _VECTORMATH_SHUF_ZCWD );\n    vmathV4MakeFrom128( result0, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) );\n    vmathV4MakeFrom128( result1, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) );\n    vmathV4MakeFrom128( result2, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) );\n    vmathV4MakeFrom128( result3, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) );\n}\n\nstatic inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads )\n{\n    VmathVector4 v0, v1, v2, v3;\n    vmathSoaV4Get4Aos( vec, &v0, &v1, &v2, &v3 );\n    twoQuads[0] = _vmath2VfToHalfFloats(v0.vec128, v1.vec128);\n    twoQuads[1] = _vmath2VfToHalfFloats(v2.vec128, v3.vec128);\n}\n\nstatic inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec )\n{\n    vmathSoaV3MakeFromElems( result, vec->x, vec->y, vec->z );\n}\n\nstatic inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec )\n{\n    return vec->x;\n}\n\nstatic inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec )\n{\n    return vec->y;\n}\n\nstatic inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec )\n{\n    return vec->z;\n}\n\nstatic inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 _w )\n{\n    result->w = _w;\n}\n\nstatic inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec )\n{\n    return vec->w;\n}\n\nstatic inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx )\n{\n    return *(&vec->x + idx);\n}\n\nstatic inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = spu_add( vec0->x, vec1->x );\n    result->y = spu_add( vec0->y, vec1->y );\n    result->z = spu_add( vec0->z, vec1->z );\n    result->w = spu_add( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = spu_sub( vec0->x, vec1->x );\n    result->y = spu_sub( vec0->y, vec1->y );\n    result->z = spu_sub( vec0->z, vec1->z );\n    result->w = spu_sub( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar )\n{\n    result->x = spu_mul( vec->x, scalar );\n    result->y = spu_mul( vec->y, scalar );\n    result->z = spu_mul( vec->z, scalar );\n    result->w = spu_mul( vec->w, scalar );\n}\n\nstatic inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar )\n{\n    result->x = divf4( vec->x, scalar );\n    result->y = divf4( vec->y, scalar );\n    result->z = divf4( vec->z, scalar );\n    result->w = divf4( vec->w, scalar );\n}\n\nstatic inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = negatef4( vec->x );\n    result->y = negatef4( vec->y );\n    result->z = negatef4( vec->z );\n    result->w = negatef4( vec->w );\n}\n\nstatic inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = spu_mul( vec0->x, vec1->x );\n    result->y = spu_mul( vec0->y, vec1->y );\n    result->z = spu_mul( vec0->z, vec1->z );\n    result->w = spu_mul( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = divf4( vec0->x, vec1->x );\n    result->y = divf4( vec0->y, vec1->y );\n    result->z = divf4( vec0->z, vec1->z );\n    result->w = divf4( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = recipf4( vec->x );\n    result->y = recipf4( vec->y );\n    result->z = recipf4( vec->z );\n    result->w = recipf4( vec->w );\n}\n\nstatic inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = sqrtf4( vec->x );\n    result->y = sqrtf4( vec->y );\n    result->z = sqrtf4( vec->z );\n    result->w = sqrtf4( vec->w );\n}\n\nstatic inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = rsqrtf4( vec->x );\n    result->y = rsqrtf4( vec->y );\n    result->z = rsqrtf4( vec->z );\n    result->w = rsqrtf4( vec->w );\n}\n\nstatic inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    result->x = fabsf4( vec->x );\n    result->y = fabsf4( vec->y );\n    result->z = fabsf4( vec->z );\n    result->w = fabsf4( vec->w );\n}\n\nstatic inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = copysignf4( vec0->x, vec1->x );\n    result->y = copysignf4( vec0->y, vec1->y );\n    result->z = copysignf4( vec0->z, vec1->z );\n    result->w = copysignf4( vec0->w, vec1->w );\n}\n\nstatic inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = fmaxf4( vec0->x, vec1->x );\n    result->y = fmaxf4( vec0->y, vec1->y );\n    result->z = fmaxf4( vec0->z, vec1->z );\n    result->w = fmaxf4( vec0->w, vec1->w );\n}\n\nstatic inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec->x, vec->y );\n    result = fmaxf4( vec->z, result );\n    result = fmaxf4( vec->w, result );\n    return result;\n}\n\nstatic inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    result->x = fminf4( vec0->x, vec1->x );\n    result->y = fminf4( vec0->y, vec1->y );\n    result->z = fminf4( vec0->z, vec1->z );\n    result->w = fminf4( vec0->w, vec1->w );\n}\n\nstatic inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = fminf4( vec->x, vec->y );\n    result = fminf4( vec->z, result );\n    result = fminf4( vec->w, result );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = spu_add( vec->x, vec->y );\n    result = spu_add( result, vec->z );\n    result = spu_add( result, vec->w );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0->x, vec1->x );\n    result = spu_add( result, spu_mul( vec0->y, vec1->y ) );\n    result = spu_add( result, spu_mul( vec0->z, vec1->z ) );\n    result = spu_add( result, spu_mul( vec0->w, vec1->w ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec )\n{\n    vec_float4 result;\n    result = spu_mul( vec->x, vec->x );\n    result = spu_add( result, spu_mul( vec->y, vec->y ) );\n    result = spu_add( result, spu_mul( vec->z, vec->z ) );\n    result = spu_add( result, spu_mul( vec->w, vec->w ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec )\n{\n    return sqrtf4( vmathSoaV4LengthSqr( vec ) );\n}\n\nstatic inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = vmathSoaV4LengthSqr( vec );\n    lenInv = rsqrtf4( lenSqr );\n    result->x = spu_mul( vec->x, lenInv );\n    result->y = spu_mul( vec->y, lenInv );\n    result->z = spu_mul( vec->z, lenInv );\n    result->w = spu_mul( vec->w, lenInv );\n}\n\nstatic inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 )\n{\n    result->x = spu_sel( vec0->x, vec1->x, select1 );\n    result->y = spu_sel( vec0->y, vec1->y, select1 );\n    result->z = spu_sel( vec0->z, vec1->z, select1 );\n    result->w = spu_sel( vec0->w, vec1->w, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV4Print( const VmathSoaVector4 *vec )\n{\n    VmathVector4 vec0, vec1, vec2, vec3;\n    vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV4Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV4Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV4Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV4Print( &vec3 );\n}\n\nstatic inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name )\n{\n    VmathVector4 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathV4Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathV4Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathV4Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathV4Print( &vec3 );\n}\n\n#endif\n\nstatic inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = pnt->x;\n    result->y = pnt->y;\n    result->z = pnt->z;\n}\n\nstatic inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    result->x = _x;\n    result->y = _y;\n    result->z = _z;\n}\n\nstatic inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec )\n{\n    result->x = vec->x;\n    result->y = vec->y;\n    result->z = vec->z;\n}\n\nstatic inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar )\n{\n    result->x = scalar;\n    result->y = scalar;\n    result->z = scalar;\n}\n\nstatic inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_float4 vec128 = pnt->vec128;\n    result->x = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    result->y = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    result->z = spu_shuffle( vec128, vec128, shuffle_zzzz );\n}\n\nstatic inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( pnt0->vec128, pnt2->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( pnt1->vec128, pnt3->vec128, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( pnt0->vec128, pnt2->vec128, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( pnt1->vec128, pnt3->vec128, _VECTORMATH_SHUF_ZCWD );\n    result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n}\n\nstatic inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    VmathSoaVector3 tmpV3_0, tmpV3_1;\n    vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 );\n    vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t );\n    vmathSoaP3AddV3( result, pnt0, &tmpV3_1 );\n}\n\nstatic inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 )\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = spu_shuffle( pnt->x, pnt->z, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( pnt->x, pnt->z, _VECTORMATH_SHUF_ZCWD );\n    vmathP3MakeFrom128( result0, spu_shuffle( tmp0, pnt->y, _VECTORMATH_SHUF_XAYB ) );\n    vmathP3MakeFrom128( result1, spu_shuffle( tmp0, pnt->y, _VECTORMATH_SHUF_ZBW0 ) );\n    vmathP3MakeFrom128( result2, spu_shuffle( tmp1, pnt->y, _VECTORMATH_SHUF_XCY0 ) );\n    vmathP3MakeFrom128( result3, spu_shuffle( tmp1, pnt->y, _VECTORMATH_SHUF_ZDW0 ) );\n}\n\nstatic inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *vec, const vec_float4 *threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD );\n    zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD );\n    yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD );\n    vmathSoaP3SetX( vec, spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) );\n    vmathSoaP3SetY( vec, spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) );\n    vmathSoaP3SetZ( vec, spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) );\n}\n\nstatic inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *vec, vec_float4 *threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = spu_shuffle( vec->x, vec->y, _VECTORMATH_SHUF_XAZC );\n    zxzx = spu_shuffle( vec->z, vec->x, _VECTORMATH_SHUF_ZDXB );\n    yzyz = spu_shuffle( vec->y, vec->z, _VECTORMATH_SHUF_YBWD );\n    xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD );\n    yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD );\n    zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\nstatic inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    vmathSoaP3StoreXYZArray( pnt0, xyz0 );\n    vmathSoaP3StoreXYZArray( pnt1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\nstatic inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 _x )\n{\n    result->x = _x;\n}\n\nstatic inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt )\n{\n    return pnt->x;\n}\n\nstatic inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 _y )\n{\n    result->y = _y;\n}\n\nstatic inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt )\n{\n    return pnt->y;\n}\n\nstatic inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 _z )\n{\n    result->z = _z;\n}\n\nstatic inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt )\n{\n    return pnt->z;\n}\n\nstatic inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value )\n{\n    *(&result->x + idx) = value;\n}\n\nstatic inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx )\n{\n    return *(&pnt->x + idx);\n}\n\nstatic inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = spu_sub( pnt0->x, pnt1->x );\n    result->y = spu_sub( pnt0->y, pnt1->y );\n    result->z = spu_sub( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 )\n{\n    result->x = spu_add( pnt->x, vec1->x );\n    result->y = spu_add( pnt->y, vec1->y );\n    result->z = spu_add( pnt->z, vec1->z );\n}\n\nstatic inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 )\n{\n    result->x = spu_sub( pnt->x, vec1->x );\n    result->y = spu_sub( pnt->y, vec1->y );\n    result->z = spu_sub( pnt->z, vec1->z );\n}\n\nstatic inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = spu_mul( pnt0->x, pnt1->x );\n    result->y = spu_mul( pnt0->y, pnt1->y );\n    result->z = spu_mul( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = divf4( pnt0->x, pnt1->x );\n    result->y = divf4( pnt0->y, pnt1->y );\n    result->z = divf4( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = recipf4( pnt->x );\n    result->y = recipf4( pnt->y );\n    result->z = recipf4( pnt->z );\n}\n\nstatic inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = sqrtf4( pnt->x );\n    result->y = sqrtf4( pnt->y );\n    result->z = sqrtf4( pnt->z );\n}\n\nstatic inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = rsqrtf4( pnt->x );\n    result->y = rsqrtf4( pnt->y );\n    result->z = rsqrtf4( pnt->z );\n}\n\nstatic inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt )\n{\n    result->x = fabsf4( pnt->x );\n    result->y = fabsf4( pnt->y );\n    result->z = fabsf4( pnt->z );\n}\n\nstatic inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = copysignf4( pnt0->x, pnt1->x );\n    result->y = copysignf4( pnt0->y, pnt1->y );\n    result->z = copysignf4( pnt0->z, pnt1->z );\n}\n\nstatic inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = fmaxf4( pnt0->x, pnt1->x );\n    result->y = fmaxf4( pnt0->y, pnt1->y );\n    result->z = fmaxf4( pnt0->z, pnt1->z );\n}\n\nstatic inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( pnt->x, pnt->y );\n    result = fmaxf4( pnt->z, result );\n    return result;\n}\n\nstatic inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    result->x = fminf4( pnt0->x, pnt1->x );\n    result->y = fminf4( pnt0->y, pnt1->y );\n    result->z = fminf4( pnt0->z, pnt1->z );\n}\n\nstatic inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt )\n{\n    vec_float4 result;\n    result = fminf4( pnt->x, pnt->y );\n    result = fminf4( pnt->z, result );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt )\n{\n    vec_float4 result;\n    result = spu_add( pnt->x, pnt->y );\n    result = spu_add( result, pnt->z );\n    return result;\n}\n\nstatic inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal )\n{\n    VmathSoaPoint3 tmpP3_0;\n    vmathSoaP3MakeFromScalar( &tmpP3_0, scaleVal );\n    vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec )\n{\n    VmathSoaPoint3 tmpP3_0;\n    vmathSoaP3MakeFromV3( &tmpP3_0, scaleVec );\n    vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec )\n{\n    vec_float4 result;\n    result = spu_mul( pnt->x, unitVec->x );\n    result = spu_add( result, spu_mul( pnt->y, unitVec->y ) );\n    result = spu_add( result, spu_mul( pnt->z, unitVec->z ) );\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathSoaV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaV3MakeFromP3( &tmpV3_0, pnt );\n    return vmathSoaV3Length( &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathSoaV3LengthSqr( &tmpV3_0 );\n}\n\nstatic inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 )\n{\n    VmathSoaVector3 tmpV3_0;\n    vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 );\n    return vmathSoaV3Length( &tmpV3_0 );\n}\n\nstatic inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 )\n{\n    result->x = spu_sel( pnt0->x, pnt1->x, select1 );\n    result->y = spu_sel( pnt0->y, pnt1->y, select1 );\n    result->z = spu_sel( pnt0->z, pnt1->z, select1 );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt )\n{\n    VmathPoint3 vec0, vec1, vec2, vec3;\n    vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathP3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathP3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathP3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathP3Print( &vec3 );\n}\n\nstatic inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name )\n{\n    VmathPoint3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 );\n    printf(\"slot 0:\\n\");\n    vmathP3Print( &vec0 );\n    printf(\"slot 1:\\n\");\n    vmathP3Print( &vec1 );\n    printf(\"slot 2:\\n\");\n    vmathP3Print( &vec2 );\n    printf(\"slot 3:\\n\");\n    vmathP3Print( &vec3 );\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vec_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_SOA_V_C_H\n#define _VECTORMATH_VEC_SOA_V_C_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*-----------------------------------------------------------------------------\n * Constants\n * for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n */\n#define _VECTORMATH_SHUF_X 0x00010203\n#define _VECTORMATH_SHUF_Y 0x04050607\n#define _VECTORMATH_SHUF_Z 0x08090a0b\n#define _VECTORMATH_SHUF_W 0x0c0d0e0f\n#define _VECTORMATH_SHUF_A 0x10111213\n#define _VECTORMATH_SHUF_B 0x14151617\n#define _VECTORMATH_SHUF_C 0x18191a1b\n#define _VECTORMATH_SHUF_D 0x1c1d1e1f\n#define _VECTORMATH_SHUF_0 0x80808080\n#define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_ZDW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZDXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YAWC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XYCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n/*-----------------------------------------------------------------------------\n * Definitions\n */\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFromAos(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 )\n{\n    vmathSoaV3Get4Aos(&vec, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads )\n{\n    vmathSoaV3LoadXYZArray(vec, threeQuads);\n}\n\nstatic inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads )\n{\n    vmathSoaV3StoreXYZArray(&vec, threeQuads);\n}\n\nstatic inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads )\n{\n    vmathSoaV3StoreHalfFloats(&vec0, &vec1, threeQuads);\n}\n\nstatic inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 _x )\n{\n    vmathSoaV3SetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3GetX(&vec);\n}\n\nstatic inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 _y )\n{\n    vmathSoaV3SetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3GetY(&vec);\n}\n\nstatic inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 _z )\n{\n    vmathSoaV3SetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3GetZ(&vec);\n}\n\nstatic inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value )\n{\n    vmathSoaV3SetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx )\n{\n    return vmathSoaV3GetElem(&vec, idx);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaV3AddP3(&result, &vec, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3MaxElem(&vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3MinElem(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3Sum(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    return vmathSoaV3Dot(&vec0, &vec1);\n}\n\nstatic inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3LengthSqr(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec )\n{\n    return vmathSoaV3Length(&vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Cross(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaV3Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV3Print_V( VmathSoaVector3 vec )\n{\n    vmathSoaV3Print(&vec);\n}\n\nstatic inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name )\n{\n    vmathSoaV3Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromElems(&result, _x, _y, _z, _w);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromV3Scalar(&result, &xyz, _w);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromP3(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromQ(&result, &quat);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFromAos(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeXAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeYAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeZAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MakeWAxis(&result);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Lerp(&result, t, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Slerp(&result, t, &unitVec0, &unitVec1);\n    return result;\n}\n\nstatic inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 )\n{\n    vmathSoaV4Get4Aos(&vec, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads )\n{\n    vmathSoaV4StoreHalfFloats(&vec, twoQuads);\n}\n\nstatic inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec )\n{\n    vmathSoaV4SetXYZ(result, &vec);\n}\n\nstatic inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector3 result;\n    vmathSoaV4GetXYZ(&result, &vec);\n    return result;\n}\n\nstatic inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 _x )\n{\n    vmathSoaV4SetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetX(&vec);\n}\n\nstatic inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 _y )\n{\n    vmathSoaV4SetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetY(&vec);\n}\n\nstatic inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 _z )\n{\n    vmathSoaV4SetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetZ(&vec);\n}\n\nstatic inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 _w )\n{\n    vmathSoaV4SetW(result, _w);\n}\n\nstatic inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4GetW(&vec);\n}\n\nstatic inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value )\n{\n    vmathSoaV4SetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx )\n{\n    return vmathSoaV4GetElem(&vec, idx);\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Add(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Sub(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4ScalarMul(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4ScalarDiv(&result, &vec, scalar);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Neg(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MulPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4DivPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4RecipPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4SqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4RsqrtPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4AbsPerElem(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4CopySignPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MaxPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4MaxElem(&vec);\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4MinPerElem(&result, &vec0, &vec1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4MinElem(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4Sum(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 )\n{\n    return vmathSoaV4Dot(&vec0, &vec1);\n}\n\nstatic inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4LengthSqr(&vec);\n}\n\nstatic inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec )\n{\n    return vmathSoaV4Length(&vec);\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Normalize(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 )\n{\n    VmathSoaVector4 result;\n    vmathSoaV4Select(&result, &vec0, &vec1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaV4Print_V( VmathSoaVector4 vec )\n{\n    vmathSoaV4Print(&vec);\n}\n\nstatic inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name )\n{\n    vmathSoaV4Prints(&vec, name);\n}\n\n#endif\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromElems(&result, _x, _y, _z);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromV3(&result, &vec);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromScalar(&result, scalar);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFromAos(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MakeFrom4Aos(&result, &pnt0, &pnt1, &pnt2, &pnt3);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3Lerp(&result, t, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 )\n{\n    vmathSoaP3Get4Aos(&pnt, result0, result1, result2, result3);\n}\n\nstatic inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *vec, const vec_float4 *threeQuads )\n{\n    vmathSoaP3LoadXYZArray(vec, threeQuads);\n}\n\nstatic inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 vec, vec_float4 *threeQuads )\n{\n    vmathSoaP3StoreXYZArray(&vec, threeQuads);\n}\n\nstatic inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads )\n{\n    vmathSoaP3StoreHalfFloats(&pnt0, &pnt1, threeQuads);\n}\n\nstatic inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 _x )\n{\n    vmathSoaP3SetX(result, _x);\n}\n\nstatic inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3GetX(&pnt);\n}\n\nstatic inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 _y )\n{\n    vmathSoaP3SetY(result, _y);\n}\n\nstatic inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3GetY(&pnt);\n}\n\nstatic inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 _z )\n{\n    vmathSoaP3SetZ(result, _z);\n}\n\nstatic inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3GetZ(&pnt);\n}\n\nstatic inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value )\n{\n    vmathSoaP3SetElem(result, idx, value);\n}\n\nstatic inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx )\n{\n    return vmathSoaP3GetElem(&pnt, idx);\n}\n\nstatic inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaVector3 result;\n    vmathSoaP3Sub(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3AddV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3SubV3(&result, &pnt, &vec1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MulPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3DivPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3RecipPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3SqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3RsqrtPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3AbsPerElem(&result, &pnt);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3CopySignPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MaxPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3MaxElem(&pnt);\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3MinPerElem(&result, &pnt0, &pnt1);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3MinElem(&pnt);\n}\n\nstatic inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3Sum(&pnt);\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3Scale(&result, &pnt, scaleVal);\n    return result;\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3NonUniformScale(&result, &pnt, &scaleVec);\n    return result;\n}\n\nstatic inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec )\n{\n    return vmathSoaP3Projection(&pnt, &unitVec);\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3DistSqrFromOrigin(&pnt);\n}\n\nstatic inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt )\n{\n    return vmathSoaP3DistFromOrigin(&pnt);\n}\n\nstatic inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    return vmathSoaP3DistSqr(&pnt0, &pnt1);\n}\n\nstatic inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 )\n{\n    return vmathSoaP3Dist(&pnt0, &pnt1);\n}\n\nstatic inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 )\n{\n    VmathSoaPoint3 result;\n    vmathSoaP3Select(&result, &pnt0, &pnt1, select1);\n    return result;\n}\n\n#ifdef _VECTORMATH_DEBUG\n\nstatic inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt )\n{\n    vmathSoaP3Print(&pnt);\n}\n\nstatic inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name )\n{\n    vmathSoaP3Prints(&pnt, name);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_SPU_H\n#define _VECTORMATH_AOS_C_SPU_H\n\n#include <math.h>\n#include <simdmath.h>\n#include <stdio.h>\n\n#ifdef _VECTORMATH_DEBUG\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_AOS_C_TYPES_H\n#define _VECTORMATH_AOS_C_TYPES_H\n\n/* A 3-D vector in array-of-structures format\n */\ntypedef struct _VmathVector3\n{\n    vec_float4 vec128;\n} VmathVector3;\n\n/* A 4-D vector in array-of-structures format\n */\ntypedef struct _VmathVector4\n{\n    vec_float4 vec128;\n} VmathVector4;\n\n/* A 3-D point in array-of-structures format\n */\ntypedef struct _VmathPoint3\n{\n    vec_float4 vec128;\n} VmathPoint3;\n\n/* A quaternion in array-of-structures format\n */\ntypedef struct _VmathQuat\n{\n    vec_float4 vec128;\n} VmathQuat;\n\n/* A 3x3 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n} VmathMatrix3;\n\n/* A 4x4 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix4\n{\n    VmathVector4 col0;\n    VmathVector4 col1;\n    VmathVector4 col2;\n    VmathVector4 col3;\n} VmathMatrix4;\n\n/* A 3x4 transformation matrix in array-of-structures format\n */\ntypedef struct _VmathTransform3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n    VmathVector3 col3;\n} VmathTransform3;\n\n#endif\n\n/*\n * Copy a 3-D vector\n */\nstatic inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline void vmathV3MakeFromElems( VmathVector3 *result, float x, float y, float z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar );\n\n/*\n * Set vector float data in a 3-D vector\n */\nstatic inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D vector\n */\nstatic inline vec_float4 vmathV3Get128( const VmathVector3 *vec );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathV3SetX( VmathVector3 *result, float x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathV3SetY( VmathVector3 *result, float y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathV3SetZ( VmathVector3 *result, float z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline float vmathV3GetX( const VmathVector3 *vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline float vmathV3GetY( const VmathVector3 *vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline float vmathV3GetZ( const VmathVector3 *vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathV3SetElem( VmathVector3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline float vmathV3GetElem( const VmathVector3 *vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathV3MakeXAxis( VmathVector3 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathV3MakeYAxis( VmathVector3 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathV3MakeZAxis( VmathVector3 *result );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline float vmathV3MaxElem( const VmathVector3 *vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline float vmathV3MinElem( const VmathVector3 *vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline float vmathV3Sum( const VmathVector3 *vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline float vmathV3LengthSqr( const VmathVector3 *vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline float vmathV3Length( const VmathVector3 *vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n * NOTE: \n * Slower than column post-multiply.\n */\nstatic inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D vector in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D vectors in three quadwords\n */\nstatic inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D vectors as half-floats\n */\nstatic inline void vmathV3StoreHalfFloats( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, const VmathVector3 *vec4, const VmathVector3 *vec5, const VmathVector3 *vec6, const VmathVector3 *vec7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Print( const VmathVector3 *vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Prints( const VmathVector3 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 4-D vector\n */\nstatic inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline void vmathV4MakeFromElems( VmathVector4 *result, float x, float y, float z, float w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar );\n\n/*\n * Set vector float data in a 4-D vector\n */\nstatic inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a 4-D vector\n */\nstatic inline vec_float4 vmathV4Get128( const VmathVector4 *vec );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathV4SetX( VmathVector4 *result, float x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathV4SetY( VmathVector4 *result, float y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathV4SetZ( VmathVector4 *result, float z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathV4SetW( VmathVector4 *result, float w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline float vmathV4GetX( const VmathVector4 *vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline float vmathV4GetY( const VmathVector4 *vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline float vmathV4GetZ( const VmathVector4 *vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline float vmathV4GetW( const VmathVector4 *vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathV4SetElem( VmathVector4 *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline float vmathV4GetElem( const VmathVector4 *vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathV4MakeXAxis( VmathVector4 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathV4MakeYAxis( VmathVector4 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathV4MakeZAxis( VmathVector4 *result );\n\n/*\n * Construct w axis\n */\nstatic inline void vmathV4MakeWAxis( VmathVector4 *result );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline float vmathV4MaxElem( const VmathVector4 *vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline float vmathV4MinElem( const VmathVector4 *vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline float vmathV4Sum( const VmathVector4 *vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline float vmathV4LengthSqr( const VmathVector4 *vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline float vmathV4Length( const VmathVector4 *vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 );\n\n/*\n * Store four 4-D vectors as half-floats\n */\nstatic inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Print( const VmathVector4 *vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Prints( const VmathVector4 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 3-D point\n */\nstatic inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline void vmathP3MakeFromElems( VmathPoint3 *result, float x, float y, float z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar );\n\n/*\n * Set vector float data in a 3-D point\n */\nstatic inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D point\n */\nstatic inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathP3SetX( VmathPoint3 *result, float x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathP3SetY( VmathPoint3 *result, float y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathP3SetZ( VmathPoint3 *result, float z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline float vmathP3GetX( const VmathPoint3 *pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline float vmathP3GetY( const VmathPoint3 *pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline float vmathP3GetZ( const VmathPoint3 *pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline float vmathP3MaxElem( const VmathPoint3 *pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline float vmathP3MinElem( const VmathPoint3 *pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline float vmathP3Sum( const VmathPoint3 *pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D point in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D points in three quadwords\n */\nstatic inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D points as half-floats\n */\nstatic inline void vmathP3StoreHalfFloats( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, const VmathPoint3 *pnt4, const VmathPoint3 *pnt5, const VmathPoint3 *pnt6, const VmathPoint3 *pnt7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Print( const VmathPoint3 *pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name );\n\n#endif\n\n/*\n * Copy a quaternion\n */\nstatic inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline void vmathQMakeFromElems( VmathQuat *result, float x, float y, float z, float w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline void vmathQMakeFromScalar( VmathQuat *result, float scalar );\n\n/*\n * Set vector float data in a quaternion\n */\nstatic inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 );\n\n/*\n * Get vector float data from a quaternion\n */\nstatic inline vec_float4 vmathQGet128( const VmathQuat *quat );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathQSetX( VmathQuat *result, float x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathQSetY( VmathQuat *result, float y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathQSetZ( VmathQuat *result, float z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathQSetW( VmathQuat *result, float w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline float vmathQGetX( const VmathQuat *quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline float vmathQGetY( const VmathQuat *quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline float vmathQGetZ( const VmathQuat *quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline float vmathQGetW( const VmathQuat *quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathQSetElem( VmathQuat *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline float vmathQGetElem( const VmathQuat *quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline void vmathQMakeIdentity( VmathQuat *result );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline void vmathQMakeRotationX( VmathQuat *result, float radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline void vmathQMakeRotationY( VmathQuat *result, float radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline void vmathQMakeRotationZ( VmathQuat *result, float radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline void vmathQConj( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline void vmathQRotate( VmathVector3 *result, const VmathQuat *unitQuat, const VmathVector3 *vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline float vmathQNorm( const VmathQuat *quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline float vmathQLength( const VmathQuat *quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrint( const VmathQuat *quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrints( const VmathQuat *quat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x3 matrix\n */\nstatic inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline void vmathM3MakeIdentity( VmathMatrix3 *result );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline float vmathM3Determinant( const VmathMatrix3 *mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Print( const VmathMatrix3 *mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 4x4 matrix\n */\nstatic inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *col0, const VmathVector4 *col1, const VmathVector4 *col2, const VmathVector4 *col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline void vmathM4MakeIdentity( VmathMatrix4 *result );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline float vmathM4Determinant( const VmathMatrix4 *mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Print( const VmathMatrix4 *mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x4 transformation matrix\n */\nstatic inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2, const VmathVector3 *col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline void vmathT3MakeIdentity( VmathTransform3 *result );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Print( const VmathTransform3 *tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vectormath_aos_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_C_V_SPU_H\n#define _VECTORMATH_AOS_C_V_SPU_H\n\n#include <math.h>\n#include <spu_intrinsics.h>\n\n#ifdef _VECTORMATH_DEBUG\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_AOS_C_TYPES_H\n#define _VECTORMATH_AOS_C_TYPES_H\n\n/* A 3-D vector in array-of-structures format\n */\ntypedef struct _VmathVector3\n{\n    vec_float4 vec128;\n} VmathVector3;\n\n/* A 4-D vector in array-of-structures format\n */\ntypedef struct _VmathVector4\n{\n    vec_float4 vec128;\n} VmathVector4;\n\n/* A 3-D point in array-of-structures format\n */\ntypedef struct _VmathPoint3\n{\n    vec_float4 vec128;\n} VmathPoint3;\n\n/* A quaternion in array-of-structures format\n */\ntypedef struct _VmathQuat\n{\n    vec_float4 vec128;\n} VmathQuat;\n\n/* A 3x3 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n} VmathMatrix3;\n\n/* A 4x4 matrix in array-of-structures format\n */\ntypedef struct _VmathMatrix4\n{\n    VmathVector4 col0;\n    VmathVector4 col1;\n    VmathVector4 col2;\n    VmathVector4 col3;\n} VmathMatrix4;\n\n/* A 3x4 transformation matrix in array-of-structures format\n */\ntypedef struct _VmathTransform3\n{\n    VmathVector3 col0;\n    VmathVector3 col1;\n    VmathVector3 col2;\n    VmathVector3 col3;\n} VmathTransform3;\n\n#endif\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline VmathVector3 vmathV3MakeFromElems_V( float x, float y, float z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline VmathVector3 vmathV3MakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a 3-D vector\n */\nstatic inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D vector\n */\nstatic inline vec_float4 vmathV3Get128_V( VmathVector3 vec );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathV3SetX_V( VmathVector3 *result, float x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathV3SetY_V( VmathVector3 *result, float y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathV3SetZ_V( VmathVector3 *result, float z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline float vmathV3GetX_V( VmathVector3 vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline float vmathV3GetY_V( VmathVector3 vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline float vmathV3GetZ_V( VmathVector3 vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline float vmathV3GetElem_V( VmathVector3 vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline VmathVector3 vmathV3Neg_V( VmathVector3 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathVector3 vmathV3MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathVector3 vmathV3MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathVector3 vmathV3MakeZAxis_V( );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline float vmathV3MaxElem_V( VmathVector3 vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline float vmathV3MinElem_V( VmathVector3 vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline float vmathV3Sum_V( VmathVector3 vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline float vmathV3LengthSqr_V( VmathVector3 vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline float vmathV3Length_V( VmathVector3 vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline VmathMatrix3 vmathV3Outer_V( VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n * NOTE: \n * Slower than column post-multiply.\n */\nstatic inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D vector in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D vectors in three quadwords\n */\nstatic inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D vectors as half-floats\n */\nstatic inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Print_V( VmathVector3 vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV3Prints_V( VmathVector3 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline VmathVector4 vmathV4MakeFromElems_V( float x, float y, float z, float w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline VmathVector4 vmathV4MakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a 4-D vector\n */\nstatic inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a 4-D vector\n */\nstatic inline vec_float4 vmathV4Get128_V( VmathVector4 vec );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathV4SetX_V( VmathVector4 *result, float x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathV4SetY_V( VmathVector4 *result, float y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathV4SetZ_V( VmathVector4 *result, float z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathV4SetW_V( VmathVector4 *result, float w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline float vmathV4GetX_V( VmathVector4 vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline float vmathV4GetY_V( VmathVector4 vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline float vmathV4GetZ_V( VmathVector4 vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline float vmathV4GetW_V( VmathVector4 vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline float vmathV4GetElem_V( VmathVector4 vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline VmathVector4 vmathV4Neg_V( VmathVector4 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathVector4 vmathV4MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathVector4 vmathV4MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathVector4 vmathV4MakeZAxis_V( );\n\n/*\n * Construct w axis\n */\nstatic inline VmathVector4 vmathV4MakeWAxis_V( );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline float vmathV4MaxElem_V( VmathVector4 vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline float vmathV4MinElem_V( VmathVector4 vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline float vmathV4Sum_V( VmathVector4 vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline float vmathV4LengthSqr_V( VmathVector4 vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline float vmathV4Length_V( VmathVector4 vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline VmathMatrix4 vmathV4Outer_V( VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 );\n\n/*\n * Store four 4-D vectors as half-floats\n */\nstatic inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Print_V( VmathVector4 vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathV4Prints_V( VmathVector4 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline VmathPoint3 vmathP3MakeFromElems_V( float x, float y, float z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a 3-D point\n */\nstatic inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a 3-D point\n */\nstatic inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathP3SetX_V( VmathPoint3 *result, float x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathP3SetY_V( VmathPoint3 *result, float y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathP3SetZ_V( VmathPoint3 *result, float z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline float vmathP3GetX_V( VmathPoint3 pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline float vmathP3GetY_V( VmathPoint3 pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline float vmathP3GetZ_V( VmathPoint3 pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline float vmathP3MaxElem_V( VmathPoint3 pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline float vmathP3MinElem_V( VmathPoint3 pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline float vmathP3Sum_V( VmathPoint3 pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 );\n\n/*\n * Store x, y, and z elements of a 3-D point in the first three words of a quadword.\n * The value of the fourth word (the word with the highest address) remains unchanged\n */\nstatic inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads );\n\n/*\n * Store four 3-D points in three quadwords\n */\nstatic inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads );\n\n/*\n * Store eight 3-D points as half-floats\n */\nstatic inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Print_V( VmathPoint3 pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name );\n\n#endif\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline VmathQuat vmathQMakeFromElems_V( float x, float y, float z, float w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline VmathQuat vmathQMakeFromScalar_V( float scalar );\n\n/*\n * Set vector float data in a quaternion\n */\nstatic inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 );\n\n/*\n * Get vector float data from a quaternion\n */\nstatic inline vec_float4 vmathQGet128_V( VmathQuat quat );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathQSetX_V( VmathQuat *result, float x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathQSetY_V( VmathQuat *result, float y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathQSetZ_V( VmathQuat *result, float z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathQSetW_V( VmathQuat *result, float w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline float vmathQGetX_V( VmathQuat quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline float vmathQGetY_V( VmathQuat quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline float vmathQGetZ_V( VmathQuat quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline float vmathQGetW_V( VmathQuat quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathQSetElem_V( VmathQuat *result, int idx, float value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline float vmathQGetElem_V( VmathQuat quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline VmathQuat vmathQNeg_V( VmathQuat quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline VmathQuat vmathQMakeIdentity_V( );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline VmathQuat vmathQMakeRotationX_V( float radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline VmathQuat vmathQMakeRotationY_V( float radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline VmathQuat vmathQMakeRotationZ_V( float radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline VmathQuat vmathQConj_V( VmathQuat quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline VmathVector3 vmathQRotate_V( VmathQuat unitQuat, VmathVector3 vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline float vmathQNorm_V( VmathQuat quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline float vmathQLength_V( VmathQuat quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline VmathQuat vmathQNormalize_V( VmathQuat quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrint_V( VmathQuat quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathQPrints_V( VmathQuat quat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3MakeIdentity_V( );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationX_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationY_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline float vmathM3Determinant_V( VmathMatrix3 mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Print_V( VmathMatrix3 mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 col0, VmathVector4 col1, VmathVector4 col2, VmathVector4 col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeIdentity_V( );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationX_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationY_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline float vmathM4Determinant_V( VmathMatrix4 mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Print_V( VmathMatrix4 mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2, VmathVector3 col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline VmathTransform3 vmathT3MakeIdentity_V( );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationX_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationY_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline VmathTransform3 vmathT3MakeRotationZ_V( float radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Print_V( VmathTransform3 tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vectormath_aos.h\"\n#include \"vec_aos_v.h\"\n#include \"quat_aos_v.h\"\n#include \"mat_aos_v.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vectormath_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_C_SPU_H\n#define _VECTORMATH_SOA_C_SPU_H\n\n#include <math.h>\n#include <spu_intrinsics.h>\n#include \"vectormath_aos.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_SOA_C_TYPES_H\n#define _VECTORMATH_SOA_C_TYPES_H\n\n/* A set of four 3-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaVector3;\n\n/* A set of four 4-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector4\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaVector4;\n\n/* A set of four 3-D points in structure-of-arrays format\n */\ntypedef struct _VmathSoaPoint3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaPoint3;\n\n/* A set of four quaternions in structure-of-arrays format\n */\ntypedef struct _VmathSoaQuat\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaQuat;\n\n/* A set of four 3x3 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n} VmathSoaMatrix3;\n\n/* A set of four 4x4 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix4\n{\n    VmathSoaVector4 col0;\n    VmathSoaVector4 col1;\n    VmathSoaVector4 col2;\n    VmathSoaVector4 col3;\n} VmathSoaMatrix4;\n\n/* A set of four 3x4 transformation matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaTransform3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n    VmathSoaVector3 col3;\n} VmathSoaTransform3;\n\n#endif\n\n/*\n * Copy a 3-D vector\n */\nstatic inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D vector\n */\nstatic inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec );\n\n/*\n * Insert four AoS 3-D vectors\n */\nstatic inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 );\n\n/*\n * Extract four AoS 3-D vectors\n */\nstatic inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n */\nstatic inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D vector in three quadwords\n */\nstatic inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D vectors as half-floats\n */\nstatic inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Print( const VmathSoaVector3 *vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 4-D vector\n */\nstatic inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 4-D vector\n */\nstatic inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec );\n\n/*\n * Insert four AoS 4-D vectors\n */\nstatic inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 );\n\n/*\n * Extract four AoS 4-D vectors\n */\nstatic inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Construct x axis\n */\nstatic inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result );\n\n/*\n * Construct y axis\n */\nstatic inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result );\n\n/*\n * Construct z axis\n */\nstatic inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result );\n\n/*\n * Construct w axis\n */\nstatic inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 );\n\n/*\n * Store four slots of an SoA 4-D vector as half-floats\n */\nstatic inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Print( const VmathSoaVector4 *vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name );\n\n#endif\n\n/*\n * Copy a 3-D point\n */\nstatic inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D point\n */\nstatic inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt );\n\n/*\n * Insert four AoS 3-D points\n */\nstatic inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 );\n\n/*\n * Extract four AoS 3-D points\n */\nstatic inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D point in three quadwords\n */\nstatic inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *pnt, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D points as half-floats\n */\nstatic inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name );\n\n#endif\n\n/*\n * Copy a quaternion\n */\nstatic inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS quaternion\n */\nstatic inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat );\n\n/*\n * Insert four AoS quaternions\n */\nstatic inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 );\n\n/*\n * Extract four AoS quaternions\n */\nstatic inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline void vmathSoaQMakeIdentity( VmathSoaQuat *result );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrint( const VmathSoaQuat *quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x3 matrix\n */\nstatic inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x3 matrix\n */\nstatic inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat );\n\n/*\n * Insert four AoS 3x3 matrices\n */\nstatic inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 );\n\n/*\n * Extract four AoS 3x3 matrices\n */\nstatic inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 4x4 matrix\n */\nstatic inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0, const VmathSoaVector4 *col1, const VmathSoaVector4 *col2, const VmathSoaVector4 *col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 4x4 matrix\n */\nstatic inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat );\n\n/*\n * Insert four AoS 4x4 matrices\n */\nstatic inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 );\n\n/*\n * Extract four AoS 4x4 matrices\n */\nstatic inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name );\n\n#endif\n\n/*\n * Copy a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2, const VmathSoaVector3 *col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm );\n\n/*\n * Insert four AoS 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 );\n\n/*\n * Extract four AoS 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vec_soa.h\"\n#include \"quat_soa.h\"\n#include \"mat_soa.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/c/vectormath_soa_v.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_C_V_SPU_H\n#define _VECTORMATH_SOA_C_V_SPU_H\n\n#include <math.h>\n#include <spu_intrinsics.h>\n#include \"vectormath_aos_v.h\"\n\n#ifdef _VECTORMATH_DEBUG\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef _VECTORMATH_SOA_C_TYPES_H\n#define _VECTORMATH_SOA_C_TYPES_H\n\n/* A set of four 3-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaVector3;\n\n/* A set of four 4-D vectors in structure-of-arrays format\n */\ntypedef struct _VmathSoaVector4\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaVector4;\n\n/* A set of four 3-D points in structure-of-arrays format\n */\ntypedef struct _VmathSoaPoint3\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n} VmathSoaPoint3;\n\n/* A set of four quaternions in structure-of-arrays format\n */\ntypedef struct _VmathSoaQuat\n{\n    vec_float4 x;\n    vec_float4 y;\n    vec_float4 z;\n    vec_float4 w;\n} VmathSoaQuat;\n\n/* A set of four 3x3 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n} VmathSoaMatrix3;\n\n/* A set of four 4x4 matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaMatrix4\n{\n    VmathSoaVector4 col0;\n    VmathSoaVector4 col1;\n    VmathSoaVector4 col2;\n    VmathSoaVector4 col3;\n} VmathSoaMatrix4;\n\n/* A set of four 3x4 transformation matrices in structure-of-arrays format\n */\ntypedef struct _VmathSoaTransform3\n{\n    VmathSoaVector3 col0;\n    VmathSoaVector3 col1;\n    VmathSoaVector3 col2;\n    VmathSoaVector3 col3;\n} VmathSoaTransform3;\n\n#endif\n\n/*\n * Construct a 3-D vector from x, y, and z elements\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D point into a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt );\n\n/*\n * Set all elements of a 3-D vector to the same scalar value\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec );\n\n/*\n * Insert four AoS 3-D vectors\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 );\n\n/*\n * Extract four AoS 3-D vectors\n */\nstatic inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 );\n\n/*\n * Set the x element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D vector\n */\nstatic inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec );\n\n/*\n * Get the y element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec );\n\n/*\n * Get the z element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec );\n\n/*\n * Set an x, y, or z element of a 3-D vector by index\n */\nstatic inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D vector by index\n */\nstatic inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx );\n\n/*\n * Add two 3-D vectors\n */\nstatic inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Subtract a 3-D vector from another 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Add a 3-D vector to a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt );\n\n/*\n * Multiply a 3-D vector by a scalar\n */\nstatic inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar );\n\n/*\n * Divide a 3-D vector by a scalar\n */\nstatic inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( );\n\n/*\n * Multiply two 3-D vectors per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Divide two 3-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Compute the reciprocal of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the reciprocal square root of a 3-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the absolute value of a 3-D vector per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec );\n\n/*\n * Copy sign from one 3-D vector to another, per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Maximum of two 3-D vectors per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Minimum of two 3-D vectors per element\n */\nstatic inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Maximum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec );\n\n/*\n * Minimum element of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec );\n\n/*\n * Compute the sum of all elements of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec );\n\n/*\n * Compute the dot product of two 3-D vectors\n */\nstatic inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Compute the square of the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec );\n\n/*\n * Compute the length of a 3-D vector\n */\nstatic inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec );\n\n/*\n * Normalize a 3-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec );\n\n/*\n * Compute cross product of two 3-D vectors\n */\nstatic inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Outer product of two 3-D vectors\n */\nstatic inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Pre-multiply a row vector by a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat );\n\n/*\n * Cross-product matrix of a 3-D vector\n */\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec );\n\n/*\n * Create cross-product matrix and multiply\n * NOTE: \n * Faster than separately creating a cross-product matrix and multiplying.\n */\nstatic inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat );\n\n/*\n * Linear interpolation between two 3-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 );\n\n/*\n * Spherical linear interpolation between two 3-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 );\n\n/*\n * Conditionally select between two 3-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D vectors, stored in three quadwords\n */\nstatic inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D vector in three quadwords\n */\nstatic inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D vectors as half-floats\n */\nstatic inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Print_V( VmathSoaVector3 vec );\n\n/*\n * Print a 3-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 4-D vector from x, y, z, and w elements\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a 4-D vector from a 3-D vector and a scalar\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w );\n\n/*\n * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec );\n\n/*\n * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt );\n\n/*\n * Copy elements from a quaternion into a 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat );\n\n/*\n * Set all elements of a 4-D vector to the same scalar value\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec );\n\n/*\n * Insert four AoS 4-D vectors\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 );\n\n/*\n * Extract four AoS 4-D vectors\n */\nstatic inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 );\n\n/*\n * Set the x, y, and z elements of a 4-D vector\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec );\n\n/*\n * Get the x, y, and z elements of a 4-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec );\n\n/*\n * Set the x element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 x );\n\n/*\n * Set the y element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 y );\n\n/*\n * Set the z element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 z );\n\n/*\n * Set the w element of a 4-D vector\n */\nstatic inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 w );\n\n/*\n * Get the x element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec );\n\n/*\n * Get the y element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec );\n\n/*\n * Get the z element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec );\n\n/*\n * Get the w element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec );\n\n/*\n * Set an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a 4-D vector by index\n */\nstatic inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx );\n\n/*\n * Add two 4-D vectors\n */\nstatic inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Subtract a 4-D vector from another 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Multiply a 4-D vector by a scalar\n */\nstatic inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar );\n\n/*\n * Divide a 4-D vector by a scalar\n */\nstatic inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar );\n\n/*\n * Negate all elements of a 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec );\n\n/*\n * Construct x axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( );\n\n/*\n * Construct y axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( );\n\n/*\n * Construct z axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( );\n\n/*\n * Construct w axis\n */\nstatic inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( );\n\n/*\n * Multiply two 4-D vectors per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Divide two 4-D vectors per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Compute the reciprocal of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the reciprocal square root of a 4-D vector per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the absolute value of a 4-D vector per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec );\n\n/*\n * Copy sign from one 4-D vector to another, per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Maximum of two 4-D vectors per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Minimum of two 4-D vectors per element\n */\nstatic inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Maximum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec );\n\n/*\n * Minimum element of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec );\n\n/*\n * Compute the sum of all elements of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec );\n\n/*\n * Compute the dot product of two 4-D vectors\n */\nstatic inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Compute the square of the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec );\n\n/*\n * Compute the length of a 4-D vector\n */\nstatic inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec );\n\n/*\n * Normalize a 4-D vector\n * NOTE: \n * The result is unpredictable when all elements of vec are at or near zero.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec );\n\n/*\n * Outer product of two 4-D vectors\n */\nstatic inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Linear interpolation between two 4-D vectors\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 );\n\n/*\n * Spherical linear interpolation between two 4-D vectors\n * NOTE: \n * The result is unpredictable if the vectors point in opposite directions.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 );\n\n/*\n * Conditionally select between two 4-D vectors\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 );\n\n/*\n * Store four slots of an SoA 4-D vector as half-floats\n */\nstatic inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4-D vector\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Print_V( VmathSoaVector4 vec );\n\n/*\n * Print a 4-D vector and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name );\n\n#endif\n\n/*\n * Construct a 3-D point from x, y, and z elements\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z );\n\n/*\n * Copy elements from a 3-D vector into a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec );\n\n/*\n * Set all elements of a 3-D point to the same scalar value\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt );\n\n/*\n * Insert four AoS 3-D points\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 );\n\n/*\n * Extract four AoS 3-D points\n */\nstatic inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 );\n\n/*\n * Set the x element of a 3-D point\n */\nstatic inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 x );\n\n/*\n * Set the y element of a 3-D point\n */\nstatic inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 y );\n\n/*\n * Set the z element of a 3-D point\n */\nstatic inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 z );\n\n/*\n * Get the x element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt );\n\n/*\n * Get the y element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt );\n\n/*\n * Get the z element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt );\n\n/*\n * Set an x, y, or z element of a 3-D point by index\n */\nstatic inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, or z element of a 3-D point by index\n */\nstatic inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx );\n\n/*\n * Subtract a 3-D point from another 3-D point\n */\nstatic inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Add a 3-D point to a 3-D vector\n */\nstatic inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec );\n\n/*\n * Subtract a 3-D vector from a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec );\n\n/*\n * Multiply two 3-D points per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Divide two 3-D points per element\n * NOTE: \n * Floating-point behavior matches standard library function divf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Compute the reciprocal of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function recipf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function sqrtf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the reciprocal square root of a 3-D point per element\n * NOTE: \n * Floating-point behavior matches standard library function rsqrtf4.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the absolute value of a 3-D point per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Copy sign from one 3-D point to another, per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Maximum of two 3-D points per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Minimum of two 3-D points per element\n */\nstatic inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Maximum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Minimum element of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the sum of all elements of a 3-D point\n */\nstatic inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt );\n\n/*\n * Apply uniform scale to a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal );\n\n/*\n * Apply non-uniform scale to a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec );\n\n/*\n * Scalar projection of a 3-D point on a unit-length 3-D vector\n */\nstatic inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec );\n\n/*\n * Compute the square of the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the distance of a 3-D point from the coordinate-system origin\n */\nstatic inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt );\n\n/*\n * Compute the square of the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Compute the distance between two 3-D points\n */\nstatic inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Linear interpolation between two 3-D points\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 );\n\n/*\n * Conditionally select between two 3-D points\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 );\n\n/*\n * Load four three-float 3-D points, stored in three quadwords\n */\nstatic inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads );\n\n/*\n * Store four slots of an SoA 3-D point in three quadwords\n */\nstatic inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 pnt, vec_float4 *threeQuads );\n\n/*\n * Store eight slots of two SoA 3-D points as half-floats\n */\nstatic inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3-D point\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt );\n\n/*\n * Print a 3-D point and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name );\n\n#endif\n\n/*\n * Construct a quaternion from x, y, z, and w elements\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n/*\n * Construct a quaternion from a 3-D vector and a scalar\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w );\n\n/*\n * Copy elements from a 4-D vector into a quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec );\n\n/*\n * Convert a rotation matrix to a unit-length quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 rotMat );\n\n/*\n * Set all elements of a quaternion to the same scalar value\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat );\n\n/*\n * Insert four AoS quaternions\n */\nstatic inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 );\n\n/*\n * Extract four AoS quaternions\n */\nstatic inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 );\n\n/*\n * Set the x, y, and z elements of a quaternion\n * NOTE: \n * This function does not change the w element.\n */\nstatic inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec );\n\n/*\n * Get the x, y, and z elements of a quaternion\n */\nstatic inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat );\n\n/*\n * Set the x element of a quaternion\n */\nstatic inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 x );\n\n/*\n * Set the y element of a quaternion\n */\nstatic inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 y );\n\n/*\n * Set the z element of a quaternion\n */\nstatic inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 z );\n\n/*\n * Set the w element of a quaternion\n */\nstatic inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 w );\n\n/*\n * Get the x element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat );\n\n/*\n * Get the y element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat );\n\n/*\n * Get the z element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat );\n\n/*\n * Get the w element of a quaternion\n */\nstatic inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat );\n\n/*\n * Set an x, y, z, or w element of a quaternion by index\n */\nstatic inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value );\n\n/*\n * Get an x, y, z, or w element of a quaternion by index\n */\nstatic inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx );\n\n/*\n * Add two quaternions\n */\nstatic inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Subtract a quaternion from another quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Multiply two quaternions\n */\nstatic inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Multiply a quaternion by a scalar\n */\nstatic inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar );\n\n/*\n * Divide a quaternion by a scalar\n */\nstatic inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar );\n\n/*\n * Negate all elements of a quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat );\n\n/*\n * Construct an identity quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQMakeIdentity_V( );\n\n/*\n * Construct a quaternion to rotate between two unit-length 3-D vectors\n * NOTE: \n * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 );\n\n/*\n * Construct a quaternion to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a quaternion to rotate around the x axis\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the y axis\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a quaternion to rotate around the z axis\n */\nstatic inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians );\n\n/*\n * Compute the conjugate of a quaternion\n */\nstatic inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat );\n\n/*\n * Use a unit-length quaternion to rotate a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat unitQuat, VmathSoaVector3 vec );\n\n/*\n * Compute the dot product of two quaternions\n */\nstatic inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Compute the norm of a quaternion\n */\nstatic inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat );\n\n/*\n * Compute the length of a quaternion\n */\nstatic inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat );\n\n/*\n * Normalize a quaternion\n * NOTE: \n * The result is unpredictable when all elements of quat are at or near zero.\n */\nstatic inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat );\n\n/*\n * Linear interpolation between two quaternions\n * NOTE: \n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 );\n\n/*\n * Spherical linear interpolation between two quaternions\n * NOTE: \n * Interpolates along the shortest path between orientations.\n * Does not clamp t between 0 and 1.\n */\nstatic inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 );\n\n/*\n * Spherical quadrangle interpolation\n */\nstatic inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 );\n\n/*\n * Conditionally select between two quaternions\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a quaternion\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrint_V( VmathSoaQuat quat );\n\n/*\n * Print a quaternion and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x3 matrix containing the specified columns\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2 );\n\n/*\n * Construct a 3x3 rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Set all elements of a 3x3 matrix to the same scalar value\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat );\n\n/*\n * Insert four AoS 3x3 matrices\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 );\n\n/*\n * Extract four AoS 3x3 matrices\n */\nstatic inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 );\n\n/*\n * Set column 0 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 col0 );\n\n/*\n * Set column 1 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 col1 );\n\n/*\n * Set column 2 of a 3x3 matrix\n */\nstatic inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 col2 );\n\n/*\n * Get column 0 of a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat );\n\n/*\n * Get column 1 of a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat );\n\n/*\n * Get column 2 of a 3x3 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat );\n\n/*\n * Set the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec );\n\n/*\n * Set the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec );\n\n/*\n * Get the column of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col );\n\n/*\n * Get the row of a 3x3 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row );\n\n/*\n * Set the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x3 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row );\n\n/*\n * Add two 3x3 matrices\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Subtract a 3x3 matrix from another 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Negate all elements of a 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat );\n\n/*\n * Multiply a 3x3 matrix by a scalar\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar );\n\n/*\n * Multiply a 3x3 matrix by a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec );\n\n/*\n * Multiply two 3x3 matrices\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Construct an identity 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( );\n\n/*\n * Construct a 3x3 matrix to rotate around the x axis\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the y axis\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the z axis\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians );\n\n/*\n * Construct a 3x3 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ );\n\n/*\n * Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Construct a 3x3 matrix to perform scaling\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat );\n\n/*\n * Multiply two 3x3 matrices per element\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 );\n\n/*\n * Compute the absolute value of a 3x3 matrix per element\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat );\n\n/*\n * Transpose of a 3x3 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat );\n\n/*\n * Compute the inverse of a 3x3 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat );\n\n/*\n * Determinant of a 3x3 matrix\n */\nstatic inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat );\n\n/*\n * Conditionally select between two 3x3 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x3 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat );\n\n/*\n * Print a 3x3 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 4x4 matrix containing the specified columns\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 col0, VmathSoaVector4 col1, VmathSoaVector4 col2, VmathSoaVector4 col3 );\n\n/*\n * Construct a 4x4 matrix from a 3x4 transformation matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat );\n\n/*\n * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec );\n\n/*\n * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec );\n\n/*\n * Set all elements of a 4x4 matrix to the same scalar value\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat );\n\n/*\n * Insert four AoS 4x4 matrices\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 );\n\n/*\n * Extract four AoS 4x4 matrices\n */\nstatic inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 4x4 matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat );\n\n/*\n * Set translation component\n * NOTE: \n * This function does not change the bottom row elements.\n */\nstatic inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec );\n\n/*\n * Get the translation component of a 4x4 matrix\n */\nstatic inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat );\n\n/*\n * Set column 0 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 col0 );\n\n/*\n * Set column 1 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 col1 );\n\n/*\n * Set column 2 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 col2 );\n\n/*\n * Set column 3 of a 4x4 matrix\n */\nstatic inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 col3 );\n\n/*\n * Get column 0 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat );\n\n/*\n * Get column 1 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat );\n\n/*\n * Get column 2 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat );\n\n/*\n * Get column 3 of a 4x4 matrix\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat );\n\n/*\n * Set the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec );\n\n/*\n * Set the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec );\n\n/*\n * Get the column of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col );\n\n/*\n * Get the row of a 4x4 matrix referred to by the specified index\n */\nstatic inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row );\n\n/*\n * Set the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 4x4 matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row );\n\n/*\n * Add two 4x4 matrices\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Subtract a 4x4 matrix from another 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Negate all elements of a 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat );\n\n/*\n * Multiply a 4x4 matrix by a scalar\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar );\n\n/*\n * Multiply a 4x4 matrix by a 4-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D vector\n */\nstatic inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec );\n\n/*\n * Multiply a 4x4 matrix by a 3-D point\n */\nstatic inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt );\n\n/*\n * Multiply two 4x4 matrices\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Multiply a 4x4 matrix by a 3x4 transformation matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm );\n\n/*\n * Construct an identity 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( );\n\n/*\n * Construct a 4x4 matrix to rotate around the x axis\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the y axis\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the z axis\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians );\n\n/*\n * Construct a 4x4 matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ );\n\n/*\n * Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Construct a 4x4 matrix to perform scaling\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec );\n\n/*\n * Construct a 4x4 matrix to perform translation\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec );\n\n/*\n * Construct viewing matrix based on eye position, position looked at, and up direction\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec );\n\n/*\n * Construct a perspective projection matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct a perspective projection matrix based on frustum\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Construct an orthographic projection matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n/*\n * Append (post-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat );\n\n/*\n * Multiply two 4x4 matrices per element\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 );\n\n/*\n * Compute the absolute value of a 4x4 matrix per element\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat );\n\n/*\n * Transpose of a 4x4 matrix\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix\n * NOTE: \n * Result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat );\n\n/*\n * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat );\n\n/*\n * Determinant of a 4x4 matrix\n */\nstatic inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat );\n\n/*\n * Conditionally select between two 4x4 matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 4x4 matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat );\n\n/*\n * Print a 4x4 matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name );\n\n#endif\n\n/*\n * Construct a 3x4 transformation matrix containing the specified columns\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2, VmathSoaVector3 col3 );\n\n/*\n * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec );\n\n/*\n * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec );\n\n/*\n * Set all elements of a 3x4 transformation matrix to the same scalar value\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar );\n\n/*\n * Replicate an AoS 3x4 transformation matrix\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm );\n\n/*\n * Insert four AoS 3x4 transformation matrices\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 );\n\n/*\n * Extract four AoS 3x4 transformation matrices\n */\nstatic inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 );\n\n/*\n * Set the upper-left 3x3 submatrix\n */\nstatic inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 mat3 );\n\n/*\n * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n */\nstatic inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm );\n\n/*\n * Set translation component\n */\nstatic inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec );\n\n/*\n * Get the translation component of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm );\n\n/*\n * Set column 0 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 col0 );\n\n/*\n * Set column 1 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 col1 );\n\n/*\n * Set column 2 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 col2 );\n\n/*\n * Set column 3 of a 3x4 transformation matrix\n */\nstatic inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 col3 );\n\n/*\n * Get column 0 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm );\n\n/*\n * Get column 1 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm );\n\n/*\n * Get column 2 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm );\n\n/*\n * Get column 3 of a 3x4 transformation matrix\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm );\n\n/*\n * Set the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec );\n\n/*\n * Set the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec );\n\n/*\n * Get the column of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col );\n\n/*\n * Get the row of a 3x4 transformation matrix referred to by the specified index\n */\nstatic inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row );\n\n/*\n * Set the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val );\n\n/*\n * Get the element of a 3x4 transformation matrix referred to by column and row indices\n */\nstatic inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D vector\n */\nstatic inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec );\n\n/*\n * Multiply a 3x4 transformation matrix by a 3-D point\n */\nstatic inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt );\n\n/*\n * Multiply two 3x4 transformation matrices\n */\nstatic inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 );\n\n/*\n * Construct an identity 3x4 transformation matrix\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x axis\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the y axis\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the z axis\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ );\n\n/*\n * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec );\n\n/*\n * Construct a rotation matrix from a unit-length quaternion\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat );\n\n/*\n * Construct a 3x4 transformation matrix to perform scaling\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec );\n\n/*\n * Construct a 3x4 transformation matrix to perform translation\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec );\n\n/*\n * Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec );\n\n/*\n * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n * NOTE: \n * Faster than creating and multiplying a scale transformation matrix.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm );\n\n/*\n * Multiply two 3x4 transformation matrices per element\n */\nstatic inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 );\n\n/*\n * Compute the absolute value of a 3x4 transformation matrix per element\n */\nstatic inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm );\n\n/*\n * Inverse of a 3x4 transformation matrix\n * NOTE: \n * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm );\n\n/*\n * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n * NOTE: \n * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm );\n\n/*\n * Conditionally select between two 3x4 transformation matrices\n * NOTE: \n * This function uses a conditional select instruction to avoid a branch.\n */\nstatic inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n/*\n * Print a 3x4 transformation matrix\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm );\n\n/*\n * Print a 3x4 transformation matrix and an associated string identifier\n * NOTE: \n * Function is only defined when _VECTORMATH_DEBUG is defined.\n */\nstatic inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#include \"vectormath_soa.h\"\n#include \"vec_soa_v.h\"\n#include \"quat_soa_v.h\"\n#include \"mat_soa_v.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/boolInVec.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _BOOLINVEC_H\n#define _BOOLINVEC_H\n\n#include <spu_intrinsics.h>\n\nnamespace Vectormath {\n\nclass floatInVec;\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec class\n//\n\nclass boolInVec\n{\n    private:\n        vec_uint4 mData;\n\n        inline boolInVec(vec_uint4 vec);\n    public:\n        inline boolInVec() {}\n\n        // matches standard type conversions\n        //\n        inline boolInVec(floatInVec vec);\n\n        // explicit cast from bool\n        //\n        explicit inline boolInVec(bool scalar);\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n        // explicit cast to bool\n        // \n        inline bool getAsBool() const;\n#else\n        // implicit cast to bool\n        // \n        inline operator bool() const;\n#endif\n    \n        // get vector data\n        // bool value is in the 0 word slot of vector as 0 (false) or -1 (true)\n        //\n        inline vec_uint4 get128() const;\n\n        // operators\n        //\n        inline const boolInVec operator ! () const;\n        inline boolInVec& operator = (boolInVec vec);\n        inline boolInVec& operator &= (boolInVec vec);\n        inline boolInVec& operator ^= (boolInVec vec);\n        inline boolInVec& operator |= (boolInVec vec);\n\n        // friend functions\n        //\n        friend inline const boolInVec operator == (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator != (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator < (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator > (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator == (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator != (floatInVec vec0, floatInVec vec1);\n        friend inline const boolInVec operator & (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec operator | (boolInVec vec0, boolInVec vec1);\n        friend inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1);\n};\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec functions\n//\n\n// operators\n//\ninline const boolInVec operator == (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator != (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator & (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1);\ninline const boolInVec operator | (boolInVec vec0, boolInVec vec1);\n\n// select between vec0 and vec1 using boolInVec.\n// false selects vec0, true selects vec1\n//\ninline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1);\n\n} // namespace Vectormath\n\n//--------------------------------------------------------------------------------------------------\n// boolInVec implementation\n//\n\n#include \"floatInVec.h\"\n\nnamespace Vectormath {\n\ninline\nboolInVec::boolInVec(vec_uint4 vec)\n{\n    mData = vec;\n}\n\ninline\nboolInVec::boolInVec(floatInVec vec)\n{\n    *this = (vec != floatInVec(0.0f));\n}\n\ninline\nboolInVec::boolInVec(bool scalar)\n{\n    mData = spu_promote((unsigned int)-scalar, 0);\n}\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline\nbool\nboolInVec::getAsBool() const\n#else\ninline\nboolInVec::operator bool() const\n#endif\n{\n    return (bool)spu_extract(mData, 0);\n}\n\ninline\nvec_uint4\nboolInVec::get128() const\n{\n    return mData;\n}\n\ninline\nconst boolInVec\nboolInVec::operator ! () const\n{\n    return boolInVec(spu_nor(mData, mData));\n}\n\ninline\nboolInVec&\nboolInVec::operator = (boolInVec vec)\n{\n    mData = vec.mData;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator &= (boolInVec vec)\n{\n    *this = *this & vec;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator ^= (boolInVec vec)\n{\n    *this = *this ^ vec;\n    return *this;\n}\n\ninline\nboolInVec&\nboolInVec::operator |= (boolInVec vec)\n{\n    *this = *this | vec;\n    return *this;\n}\n\ninline\nconst boolInVec\noperator == (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(spu_cmpeq(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator != (boolInVec vec0, boolInVec vec1)\n{\n    return !(vec0 == vec1);\n}\n    \ninline\nconst boolInVec\noperator & (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(spu_and(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator | (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(spu_or(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator ^ (boolInVec vec0, boolInVec vec1)\n{\n    return boolInVec(spu_xor(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\nselect(boolInVec vec0, boolInVec vec1, boolInVec select_vec1)\n{\n    return boolInVec(spu_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));\n}\n \n} // namespace Vectormath\n\n#endif // boolInVec_h\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/floatInVec.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _FLOATINVEC_H\n#define _FLOATINVEC_H\n\n#include <math.h>\n#include <spu_intrinsics.h>\n#include <simdmath.h>\n#undef bool\n\nnamespace Vectormath {\n\nclass boolInVec;\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec class\n//\n\nclass floatInVec\n{\n    private:\n        vec_float4 mData;\n\n        inline floatInVec(vec_float4 vec);\n    public:\n        inline floatInVec() {}\n\n        // matches standard type conversions\n        //\n        inline floatInVec(boolInVec vec);\n\n        // construct from a slot of vec_float4\n        //\n        inline floatInVec(vec_float4 vec, int slot);\n        \n        // explicit cast from float\n        //\n        explicit inline floatInVec(float scalar);\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\n        // explicit cast to float\n        // \n        inline float getAsFloat() const;\n#else\n        // implicit cast to float\n        //\n        inline operator float() const;\n#endif\n\n        // get vector data\n        // float value is in 0 word slot of vector\n        //\n        inline vec_float4 get128() const;\n\n        // operators\n        // \n        inline const floatInVec operator ++ (int);\n        inline const floatInVec operator -- (int);\n        inline floatInVec& operator ++ ();\n        inline floatInVec& operator -- ();\n        inline const floatInVec operator - () const;\n        inline floatInVec& operator = (floatInVec vec);\n        inline floatInVec& operator *= (floatInVec vec);\n        inline floatInVec& operator /= (floatInVec vec);\n        inline floatInVec& operator += (floatInVec vec);\n        inline floatInVec& operator -= (floatInVec vec);\n\n        // friend functions\n        //\n        friend inline const floatInVec operator * (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec operator / (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec operator + (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec operator - (floatInVec vec0, floatInVec vec1);\n        friend inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1);\n};\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec functions\n//\n\n// operators\n// \ninline const floatInVec operator * (floatInVec vec0, floatInVec vec1);\ninline const floatInVec operator / (floatInVec vec0, floatInVec vec1);\ninline const floatInVec operator + (floatInVec vec0, floatInVec vec1);\ninline const floatInVec operator - (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator < (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator <= (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator > (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator >= (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator == (floatInVec vec0, floatInVec vec1);\ninline const boolInVec operator != (floatInVec vec0, floatInVec vec1);\n\n// select between vec0 and vec1 using boolInVec.\n// false selects vec0, true selects vec1\n//\ninline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1);\n\n} // namespace Vectormath\n\n//--------------------------------------------------------------------------------------------------\n// floatInVec implementation\n//\n\n#include \"boolInVec.h\"\n\nnamespace Vectormath {\n\ninline\nfloatInVec::floatInVec(vec_float4 vec)\n{\n    mData = vec;\n}\n\ninline\nfloatInVec::floatInVec(boolInVec vec)\n{\n    mData = spu_sel(spu_splats(0.0f), spu_splats(1.0f), vec.get128());\n}\n\ninline\nfloatInVec::floatInVec(vec_float4 vec, int slot)\n{\n    mData = spu_promote(spu_extract(vec, slot), 0);\n}\n\ninline\nfloatInVec::floatInVec(float scalar)\n{\n    mData = spu_promote(scalar, 0);\n}\n\n#ifdef _VECTORMATH_NO_SCALAR_CAST\ninline\nfloat\nfloatInVec::getAsFloat() const\n#else\ninline\nfloatInVec::operator float() const\n#endif\n{\n    return spu_extract(mData,0);\n}\n\ninline\nvec_float4\nfloatInVec::get128() const\n{\n    return mData;\n}\n\ninline\nconst floatInVec\nfloatInVec::operator ++ (int)\n{\n    vec_float4 olddata = mData;\n    operator ++();\n    return floatInVec(olddata);\n}\n\ninline\nconst floatInVec\nfloatInVec::operator -- (int)\n{\n    vec_float4 olddata = mData;\n    operator --();\n    return floatInVec(olddata);\n}\n\ninline\nfloatInVec&\nfloatInVec::operator ++ ()\n{\n    *this += floatInVec(1.0f);\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator -- ()\n{\n    *this -= floatInVec(1.0f);\n    return *this;\n}\n\ninline\nconst floatInVec\nfloatInVec::operator - () const\n{\n    return floatInVec((vec_float4)spu_xor((vec_uint4)mData, spu_splats(0x80000000)));\n}\n\ninline\nfloatInVec&\nfloatInVec::operator = (floatInVec vec)\n{\n    mData = vec.mData;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator *= (floatInVec vec)\n{\n    *this = *this * vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator /= (floatInVec vec)\n{\n    *this = *this / vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator += (floatInVec vec)\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline\nfloatInVec&\nfloatInVec::operator -= (floatInVec vec)\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline\nconst floatInVec\noperator * (floatInVec vec0, floatInVec vec1)\n{\n    return floatInVec(spu_mul(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst floatInVec\noperator / (floatInVec num, floatInVec den)\n{\n    return floatInVec(divf4(num.get128(), den.get128()));\n}\n\ninline\nconst floatInVec\noperator + (floatInVec vec0, floatInVec vec1)\n{\n    return floatInVec(spu_add(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst floatInVec\noperator - (floatInVec vec0, floatInVec vec1)\n{\n    return floatInVec(spu_sub(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator < (floatInVec vec0, floatInVec vec1)\n{\n    return boolInVec(spu_cmpgt(vec1.get128(), vec0.get128()));\n}\n\ninline\nconst boolInVec\noperator <= (floatInVec vec0, floatInVec vec1)\n{\n    return !(vec0 > vec1);\n}\n\ninline\nconst boolInVec\noperator > (floatInVec vec0, floatInVec vec1)\n{\n    return boolInVec(spu_cmpgt(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator >= (floatInVec vec0, floatInVec vec1)\n{\n    return !(vec0 < vec1);\n}\n\ninline\nconst boolInVec\noperator == (floatInVec vec0, floatInVec vec1)\n{\n    return boolInVec(spu_cmpeq(vec0.get128(), vec1.get128()));\n}\n\ninline\nconst boolInVec\noperator != (floatInVec vec0, floatInVec vec1)\n{\n    return !(vec0 == vec1);\n}\n    \ninline\nconst floatInVec\nselect(floatInVec vec0, floatInVec vec1, boolInVec select_vec1)\n{\n    return floatInVec(spu_sel(vec0.get128(), vec1.get128(), select_vec1.get128()));\n}\n\n} // namespace Vectormath\n\n#endif // floatInVec_h\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/mat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_AOS_CPP_H\n#define _VECTORMATH_MAT_AOS_CPP_H\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Constants\n// for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_0ZB0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_0 })     \n#define _VECTORMATH_SHUF_C0X0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_YA00 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_Z })\n#define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X })\n#define _VECTORMATH_SHUF_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y })\n#define _VECTORMATH_SHUF_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZAY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_BZX0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_0ZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A })\n#define _VECTORMATH_SHUF_Z0XB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YX0C ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_CZD0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_BBY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\ninline Matrix3::Matrix3( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n}\n\ninline Matrix3::Matrix3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( Quat unitQuat )\n{\n    vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    vec_uint4 select_x = (vec_uint4)spu_maskb(0xf000);\n    vec_uint4 select_z = (vec_uint4)spu_maskb(0x00f0);\n    xyzw_2 = spu_add( unitQuat.get128(), unitQuat.get128() );\n    wwww = spu_shuffle( unitQuat.get128(), unitQuat.get128(), shuffle_wwww );\n    yzxw = spu_shuffle( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_SHUF_YZXW );\n    zxyw = spu_shuffle( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_SHUF_ZXYW );\n    yzxw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_YZXW );\n    zxyw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_ZXYW );\n    tmp0 = spu_mul( yzxw_2, wwww );\n    tmp1 = spu_nmsub( yzxw, yzxw_2, spu_splats(1.0f) );\n    tmp2 = spu_mul( yzxw, xyzw_2 );\n    tmp0 = spu_madd( zxyw, xyzw_2, tmp0 );\n    tmp1 = spu_nmsub( zxyw, zxyw_2, tmp1 );\n    tmp2 = spu_nmsub( zxyw_2, wwww, tmp2 );\n    tmp3 = spu_sel( tmp0, tmp1, select_x );\n    tmp4 = spu_sel( tmp1, tmp2, select_x );\n    tmp5 = spu_sel( tmp2, tmp0, select_x );\n    mCol0 = Vector3( spu_sel( tmp3, tmp2, select_z ) );\n    mCol1 = Vector3( spu_sel( tmp4, tmp0, select_z ) );\n    mCol2 = Vector3( spu_sel( tmp5, tmp1, select_z ) );\n}\n\ninline Matrix3::Matrix3( Vector3 _col0, Vector3 _col1, Vector3 _col2 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n}\n\ninline Matrix3 & Matrix3::setCol0( Vector3 _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol1( Vector3 _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol2( Vector3 _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol( int col, Vector3 vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setRow( int row, Vector3 vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline float Matrix3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Matrix3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Matrix3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Matrix3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Matrix3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::getRow( int row ) const\n{\n    return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) );\n}\n\ninline Vector3 & Matrix3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix3 & Matrix3::operator =( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    return *this;\n}\n\ninline const Matrix3 transpose( const Matrix3 & mat )\n{\n    vec_float4 tmp0, tmp1, res0, res1, res2;\n    tmp0 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_ZCWD );\n    res0 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_XAYB );\n    res1 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_ZBW0 );\n    res2 = spu_shuffle( tmp1, mat.getCol1().get128(), _VECTORMATH_SHUF_XCY0 );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 inverse( const Matrix3 & mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2;\n    tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() );\n    tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() );\n    tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() );\n    dot = _vmathVfDot3( tmp2, mat.getCol2().get128() );\n    dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) );\n    invdet = recipf4( dot );\n    tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB );\n    tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD );\n    inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB );\n    inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 );\n    inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 );\n    inv0 = spu_mul( inv0, invdet );\n    inv1 = spu_mul( inv1, invdet );\n    inv2 = spu_mul( inv2, invdet );\n    return Matrix3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 )\n    );\n}\n\ninline float determinant( const Matrix3 & mat )\n{\n    return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) );\n}\n\ninline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 )\n    );\n}\n\ninline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator +=( const Matrix3 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::operator -=( const Matrix3 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix3 Matrix3::operator -( ) const\n{\n    return Matrix3(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 )\n    );\n}\n\ninline const Matrix3 absPerElem( const Matrix3 & mat )\n{\n    return Matrix3(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( float scalar ) const\n{\n    return Matrix3(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix3 operator *( float scalar, const Matrix3 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector3 Matrix3::operator *( Vector3 vec ) const\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx );\n    yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy );\n    zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz );\n    res = spu_mul( mCol0.get128(), xxxx );\n    res = spu_madd( mCol1.get128(), yyyy, res );\n    res = spu_madd( mCol2.get128(), zzzz, res );\n    return Vector3( res );\n}\n\ninline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( const Matrix3 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 )\n{\n    return Matrix3(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::identity( )\n{\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationX( float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res1 = spu_sel( zero, c, select_y );\n    res1 = spu_sel( res1, s, select_z );\n    res2 = spu_sel( zero, negatef4(s), select_y );\n    res2 = spu_sel( res2, c, select_z );\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationY( float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, negatef4(s), select_z );\n    res2 = spu_sel( zero, s, select_x );\n    res2 = spu_sel( res2, c, select_z );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3::yAxis( ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZ( float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, s, select_y );\n    res1 = spu_sel( zero, negatef4(s), select_x );\n    res1 = spu_sel( res1, c, select_y );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZYX( Vector3 radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    angles = radiansXYZ.get128();\n    angles = spu_insert( 0.0f, angles, 3 );\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 );\n    Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 );\n    Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 );\n    Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 );\n    X0 = spu_shuffle( s, s, shuffle_xxxx );\n    X1 = spu_shuffle( c, c, shuffle_xxxx );\n    tmp = spu_mul( Z0, Y1 );\n    return Matrix3(\n        Vector3( spu_mul( Z0, Y0 ) ),\n        Vector3( spu_madd( Z1, X1, spu_mul( tmp, X0 ) ) ),\n        Vector3( spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( float radians, Vector3 unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    axis = unitVec.get128();\n    sincosf4( spu_splats( radians ), &s, &c );\n    xxxx = spu_shuffle( axis, axis, shuffle_xxxx );\n    yyyy = spu_shuffle( axis, axis, shuffle_yyyy );\n    zzzz = spu_shuffle( axis, axis, shuffle_zzzz );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    axisS = spu_mul( axis, s );\n    negAxisS = negatef4( axisS );\n    tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 );\n    tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 );\n    tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 );\n    tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) );\n    tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) );\n    tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) );\n    return Matrix3(\n        Vector3( spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 ) ),\n        Vector3( spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 ) ),\n        Vector3( spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( Quat unitQuat )\n{\n    return Matrix3( unitQuat );\n}\n\ninline const Matrix3 Matrix3::scale( Vector3 scaleVec )\n{\n    vec_float4 zero = spu_splats(0.0f);\n    return Matrix3(\n        Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0xf000) ) ),\n        Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x0f00) ) ),\n        Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x00f0) ) )\n    );\n}\n\ninline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec )\n{\n    return Matrix3(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) )\n    );\n}\n\ninline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat )\n{\n    return Matrix3(\n        mulPerElem( mat.getCol0(), scaleVec ),\n        mulPerElem( mat.getCol1(), scaleVec ),\n        mulPerElem( mat.getCol2(), scaleVec )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix3 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n}\n\ninline void print( const Matrix3 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Matrix4::Matrix4( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n}\n\ninline Matrix4::Matrix4( float scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const Transform3 & mat )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( mat.getCol3(), 1.0f );\n}\n\ninline Matrix4::Matrix4( Vector4 _col0, Vector4 _col1, Vector4 _col2, Vector4 _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Matrix4::Matrix4( const Matrix3 & mat, Vector3 translateVec )\n{\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4::Matrix4( Quat unitQuat, Vector3 translateVec )\n{\n    Matrix3 mat;\n    mat = Matrix3( unitQuat );\n    mCol0 = Vector4( mat.getCol0(), 0.0f );\n    mCol1 = Vector4( mat.getCol1(), 0.0f );\n    mCol2 = Vector4( mat.getCol2(), 0.0f );\n    mCol3 = Vector4( translateVec, 1.0f );\n}\n\ninline Matrix4 & Matrix4::setCol0( Vector4 _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol1( Vector4 _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol2( Vector4 _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol3( Vector4 _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol( int col, Vector4 vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setRow( int row, Vector4 vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline float Matrix4::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector4 Matrix4::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector4 Matrix4::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector4 Matrix4::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector4 Matrix4::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector4 Matrix4::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector4 & Matrix4::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix4 & Matrix4::operator =( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n    return *this;\n}\n\ninline const Matrix4 transpose( const Matrix4 & mat )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3;\n    tmp0 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mat.getCol1().get128(), mat.getCol3().get128(), _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( mat.getCol1().get128(), mat.getCol3().get128(), _VECTORMATH_SHUF_ZCWD );\n    res0 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    res1 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    res2 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n    res3 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4( res1 ),\n        Vector4( res2 ),\n        Vector4( res3 )\n    );\n}\n\ninline const Matrix4 inverse( const Matrix4 & mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 in0, in1, in2, in3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    vec_float4 cof0, cof1, cof2, cof3;\n    vec_float4 t0, t1, t2, t3;\n    vec_float4 t01, t02, t03, t12, t23;\n    vec_float4 t1r, t2r;\n    vec_float4 t01r, t02r, t03r, t12r, t23r;\n    vec_float4 t1r3, t1r3r;\n    vec_float4 det, det1, det2, det3, invdet;\n    in0 = mat.getCol0().get128();\n    in1 = mat.getCol1().get128();\n    in2 = mat.getCol2().get128();\n    in3 = mat.getCol3().get128();\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC);    /* A E C G */\n    tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC);    /* I M K O */\n    tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD);    /* B F D H */\n    tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD);    /* J N L P */\n    t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB);    /* A E I M */\n    t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB);    /* J N B F */\n    t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD);    /* C G K O */\n    t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD);    /* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = spu_mul(t2, t3);                        /* CL GP KD OH */\n    t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ);     /* GP CL OH KD */\n    cof0 = spu_mul(t1, t23);                      /* JGP NCL BOH FKD */\n    cof1 = spu_mul(t0, t23);                      /* AGP ECL IOH MKD */\n    t23r = spu_rlqwbyte(t23, 8);                  /* OH KD GP CL */\n    cof0 = spu_msub(t1, t23r, cof0);              /* JOH NKD BGP FCL  - cof0 */\n    cof1 = spu_msub(t0, t23r, cof1);              /* AOH EKD IGP MCL  - cof1 */\n    cof1 = spu_rlqwbyte(cof1, 8);                 /* IGP MCL AOH EKD - IOH MKD AGP ECL */\n\n    t12 = spu_mul(t1, t2);                        /* JC NG BK FO */\n    t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ);     /* NG JC FO BK */\n    cof0 = spu_madd(t3, t12, cof0);               /* LNG PJC DFO HBK + cof0 */\n    cof3 = spu_mul(t0, t12);                      /* ANG EJC IFO MBK */\n    t12r = spu_rlqwbyte(t12, 8);                  /* FO BK NG JC */\n    cof0 = spu_nmsub(t3, t12r, cof0);             /* cof0 - LFO PBK DNG HJC */\n    cof3 = spu_msub(t0, t12r, cof3);              /* AFO EBK ING MJC - cof3 */\n    cof3 = spu_rlqwbyte(cof3, 8);                 /* ING MJC AFO EBK - IFO MBK ANG EJC */\n    t1r = spu_rlqwbyte(t1, 8);                    /* B F J N */\n    t2r = spu_rlqwbyte(t2, 8);                    /* K O C G */\n    t1r3 = spu_mul(t1r, t3);                      /* BL FP JD NH */\n    t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ);  /* FP BL NH JD */\n    cof0 = spu_madd(t2r, t1r3, cof0);             /* KFP OBL CNH GJD + cof0 */\n    cof2 = spu_mul(t0, t1r3);                     /* AFP EBL INH MJD */\n    t1r3r = spu_rlqwbyte(t1r3, 8);                /* NH JD FP BL */\n    cof0 = spu_nmsub(t2r, t1r3r, cof0);           /* cof0 - KNH OJD CFP GBL */\n    cof2 = spu_msub(t0, t1r3r, cof2);             /* ANH EJD IFP MBL - cof2 */\n    cof2 = spu_rlqwbyte(cof2, 8);                 /* IFP MBL ANH EJD - INH MJD AFP EBL */\n    t01 = spu_mul(t0, t1);                                /* AJ EN IB MF */\n    t01 = spu_shuffle(t01, t01, _VECTORMATH_SHUF_YXWZ);     /* EN AJ MF IB */\n    cof2 = spu_madd(t3, t01, cof2);               /* LEN PAJ DMF HIB + cof2 */\n    cof3 = spu_msub(t2r, t01, cof3);              /* KEN OAJ CMF GIB - cof3 */\n    t01r = spu_rlqwbyte(t01, 8);                  /* MF IB EN AJ */\n    cof2 = spu_msub(t3, t01r, cof2);              /* LMF PIB DEN HAJ - cof2 */\n    cof3 = spu_nmsub(t2r, t01r, cof3);            /* cof3 - KMF OIB CEN GAJ */\n    t03 = spu_mul(t0, t3);                                /* AL EP ID MH */\n    t03 = spu_shuffle(t03, t03, _VECTORMATH_SHUF_YXWZ);     /* EP AL MH ID */\n    cof1 = spu_nmsub(t2r, t03, cof1);             /* cof1 - KEP OAL CMH GID */\n    cof2 = spu_madd(t1, t03, cof2);               /* JEP NAL BMH FID + cof2 */\n    t03r = spu_rlqwbyte(t03, 8);                  /* MH ID EP AL */\n    cof1 = spu_madd(t2r, t03r, cof1);             /* KMH OID CEP GAL + cof1 */\n    cof2 = spu_nmsub(t1, t03r, cof2);             /* cof2 - JMH NID BEP FAL */\n    t02 = spu_mul(t0, t2r);                       /* AK EO IC MG */\n    t02 = spu_shuffle(t02, t02, _VECTORMATH_SHUF_YXWZ);     /* E0 AK MG IC */\n    cof1 = spu_madd(t3, t02, cof1);               /* LEO PAK DMG HIC + cof1 */\n    cof3 = spu_nmsub(t1, t02, cof3);              /* cof3 - JEO NAK BMG FIC */\n    t02r = spu_rlqwbyte(t02, 8);                  /* MG IC EO AK */\n    cof1 = spu_nmsub(t3, t02r, cof1);             /* cof1 - LMG PIC DEO HAK */\n    cof3 = spu_madd(t1, t02r, cof3);              /* JMG NIC BEO FAK + cof3 */\n    /* Compute the determinant of the matrix\n     *\n     * det = sum_across(t0 * cof0);\n     *\n     * We perform a sum across the entire vector so that\n     * we don't have to splat the result when multiplying the\n     * cofactors by the inverse of the determinant.\n     */\n    det  = spu_mul(t0, cof0);\n    det1 = spu_rlqwbyte(det, 4);\n    det2 = spu_rlqwbyte(det, 8);\n    det3 = spu_rlqwbyte(det, 12);\n    det  = spu_add(det, det1);\n    det2 = spu_add(det2, det3);\n    det  = spu_add(det, det2);\n    /* Compute the reciprocal of the determinant.\n     */\n    invdet = recipf4(det);\n    /* Multiply the cofactors by the reciprocal of the determinant.\n     */\n    return Matrix4(\n        Vector4( spu_mul(cof0, invdet) ),\n        Vector4( spu_mul(cof1, invdet) ),\n        Vector4( spu_mul(cof2, invdet) ),\n        Vector4( spu_mul(cof3, invdet) )\n    );\n}\n\ninline const Matrix4 affineInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( inverse( affineMat ) );\n}\n\ninline const Matrix4 orthoInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( orthoInverse( affineMat ) );\n}\n\ninline float determinant( const Matrix4 & mat )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 in0, in1, in2, in3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    vec_float4 cof0;\n    vec_float4 t0, t1, t2, t3;\n    vec_float4 t12, t23;\n    vec_float4 t1r, t2r;\n    vec_float4 t12r, t23r;\n    vec_float4 t1r3, t1r3r;\n    in0 = mat.getCol0().get128();\n    in1 = mat.getCol1().get128();\n    in2 = mat.getCol2().get128();\n    in3 = mat.getCol3().get128();\n    /* Perform transform of the input matrix of the form:\n     *    A B C D\n     *    E F G H\n     *    I J K L\n     *    M N O P\n     *\n     * The pseudo transpose of the input matrix is trans:\n     *    A E I M\n     *    J N B F\n     *    C G K O\n     *    L P D H\n     */\n    tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC);    /* A E C G */\n    tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC);    /* I M K O */\n    tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD);    /* B F D H */\n    tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD);    /* J N L P */\n    t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB);    /* A E I M */\n    t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB);    /* J N B F */\n    t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD);    /* C G K O */\n    t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD);    /* L P D H */\n    /* Generate a cofactor matrix. The computed cofactors reside in\n     * cof0, cof1, cof2, cof3.\n     */\n    t23 = spu_mul(t2, t3);                        /* CL GP KD OH */\n    t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ);     /* GP CL OH KD */\n    cof0 = spu_mul(t1, t23);                      /* JGP NCL BOH FKD */\n    t23r = spu_rlqwbyte(t23, 8);                  /* OH KD GP CL */\n    cof0 = spu_msub(t1, t23r, cof0);              /* JOH NKD BGP FCL  - cof0 */\n\n    t12 = spu_mul(t1, t2);                        /* JC NG BK FO */\n    t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ);     /* NG JC FO BK */\n    cof0 = spu_madd(t3, t12, cof0);               /* LNG PJC DFO HBK + cof0 */\n    t12r = spu_rlqwbyte(t12, 8);                  /* FO BK NG JC */\n    cof0 = spu_nmsub(t3, t12r, cof0);             /* cof0 - LFO PBK DNG HJC */\n    t1r = spu_rlqwbyte(t1, 8);                    /* B F J N */\n    t2r = spu_rlqwbyte(t2, 8);                    /* K O C G */\n    t1r3 = spu_mul(t1r, t3);                      /* BL FP JD NH */\n    t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ);  /* FP BL NH JD */\n    cof0 = spu_madd(t2r, t1r3, cof0);             /* KFP OBL CNH GJD + cof0 */\n    t1r3r = spu_rlqwbyte(t1r3, 8);                /* NH JD FP BL */\n    cof0 = spu_nmsub(t2r, t1r3r, cof0);           /* cof0 - KNH OJD CFP GBL */\n    return spu_extract( _vmathVfDot4(t0,cof0), 0 );\n}\n\ninline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 ),\n        ( mCol3 + mat.mCol3 )\n    );\n}\n\ninline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 ),\n        ( mCol3 - mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator +=( const Matrix4 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::operator -=( const Matrix4 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator -( ) const\n{\n    return Matrix4(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 ),\n        ( -mCol3 )\n    );\n}\n\ninline const Matrix4 absPerElem( const Matrix4 & mat )\n{\n    return Matrix4(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() ),\n        absPerElem( mat.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( float scalar ) const\n{\n    return Matrix4(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar ),\n        ( mCol3 * scalar )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix4 operator *( float scalar, const Matrix4 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector4 Matrix4::operator *( Vector4 vec ) const\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz, wwww;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx );\n    yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy );\n    zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz );\n    wwww = spu_shuffle( vec.get128(), vec.get128(), shuffle_wwww );\n    tmp0 = spu_mul( mCol0.get128(), xxxx );\n    tmp1 = spu_mul( mCol1.get128(), yyyy );\n    tmp0 = spu_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = spu_madd( mCol3.get128(), wwww, tmp1 );\n    res = spu_add( tmp0, tmp1 );\n    return Vector4( res );\n}\n\ninline const Vector4 Matrix4::operator *( Vector3 vec ) const\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx );\n    yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy );\n    zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz );\n    res = spu_mul( mCol0.get128(), xxxx );\n    res = spu_madd( mCol1.get128(), yyyy, res );\n    res = spu_madd( mCol2.get128(), zzzz, res );\n    return Vector4( res );\n}\n\ninline const Vector4 Matrix4::operator *( Point3 pnt ) const\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_xxxx );\n    yyyy = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_yyyy );\n    zzzz = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_zzzz );\n    tmp0 = spu_mul( mCol0.get128(), xxxx );\n    tmp1 = spu_mul( mCol1.get128(), yyyy );\n    tmp0 = spu_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = spu_add( mCol3.get128(), tmp1 );\n    res = spu_add( tmp0, tmp1 );\n    return Vector4( res );\n}\n\ninline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 ),\n        ( *this * mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Matrix4 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const\n{\n    return Matrix4(\n        ( *this * tfrm.getCol0() ),\n        ( *this * tfrm.getCol1() ),\n        ( *this * tfrm.getCol2() ),\n        ( *this * Point3( tfrm.getCol3() ) )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 )\n{\n    return Matrix4(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() ),\n        mulPerElem( mat0.getCol3(), mat1.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::identity( )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 )\n{\n    mCol0.setXYZ( mat3.getCol0() );\n    mCol1.setXYZ( mat3.getCol1() );\n    mCol2.setXYZ( mat3.getCol2() );\n    return *this;\n}\n\ninline const Matrix3 Matrix4::getUpper3x3( ) const\n{\n    return Matrix3(\n        mCol0.getXYZ( ),\n        mCol1.getXYZ( ),\n        mCol2.getXYZ( )\n    );\n}\n\ninline Matrix4 & Matrix4::setTranslation( Vector3 translateVec )\n{\n    mCol3.setXYZ( translateVec );\n    return *this;\n}\n\ninline const Vector3 Matrix4::getTranslation( ) const\n{\n    return mCol3.getXYZ( );\n}\n\ninline const Matrix4 Matrix4::rotationX( float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res1 = spu_sel( zero, c, select_y );\n    res1 = spu_sel( res1, s, select_z );\n    res2 = spu_sel( zero, negatef4(s), select_y );\n    res2 = spu_sel( res2, c, select_z );\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4( res1 ),\n        Vector4( res2 ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationY( float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, negatef4(s), select_z );\n    res2 = spu_sel( zero, s, select_x );\n    res2 = spu_sel( res2, c, select_z );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4::yAxis( ),\n        Vector4( res2 ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZ( float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, s, select_y );\n    res1 = spu_sel( zero, negatef4(s), select_x );\n    res1 = spu_sel( res1, c, select_y );\n    return Matrix4(\n        Vector4( res0 ),\n        Vector4( res1 ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZYX( Vector3 radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    angles = radiansXYZ.get128();\n    angles = spu_insert( 0.0f, angles, 3 );\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 );\n    Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 );\n    Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 );\n    Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 );\n    X0 = spu_shuffle( s, s, shuffle_xxxx );\n    X1 = spu_shuffle( c, c, shuffle_xxxx );\n    tmp = spu_mul( Z0, Y1 );\n    return Matrix4(\n        Vector4( spu_mul( Z0, Y0 ) ),\n        Vector4( spu_madd( Z1, X1, spu_mul( tmp, X0 ) ) ),\n        Vector4( spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( float radians, Vector3 unitVec )\n{\n    vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    axis = unitVec.get128();\n    sincosf4( spu_splats( radians ), &s, &c );\n    xxxx = spu_shuffle( axis, axis, shuffle_xxxx );\n    yyyy = spu_shuffle( axis, axis, shuffle_yyyy );\n    zzzz = spu_shuffle( axis, axis, shuffle_zzzz );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    axisS = spu_mul( axis, s );\n    negAxisS = negatef4( axisS );\n    tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 );\n    tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 );\n    tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 );\n    tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) );\n    tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) );\n    tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) );\n    zeroW = (vec_float4)spu_maskb(0x000f);\n    axis = spu_andc( axis, zeroW );\n    return Matrix4(\n        Vector4( spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 ) ),\n        Vector4( spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 ) ),\n        Vector4( spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( Quat unitQuat )\n{\n    return Matrix4( Transform3::rotation( unitQuat ) );\n}\n\ninline const Matrix4 Matrix4::scale( Vector3 scaleVec )\n{\n    vec_float4 zero = spu_splats(0.0f);\n    return Matrix4(\n        Vector4( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0xf000) ) ),\n        Vector4( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x0f00) ) ),\n        Vector4( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x00f0) ) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec )\n{\n    return Matrix4(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) ),\n        mat.getCol3()\n    );\n}\n\ninline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat )\n{\n    Vector4 scale4;\n    scale4 = Vector4( scaleVec, 1.0f );\n    return Matrix4(\n        mulPerElem( mat.getCol0(), scale4 ),\n        mulPerElem( mat.getCol1(), scale4 ),\n        mulPerElem( mat.getCol2(), scale4 ),\n        mulPerElem( mat.getCol3(), scale4 )\n    );\n}\n\ninline const Matrix4 Matrix4::translation( Vector3 translateVec )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4( translateVec, 1.0f )\n    );\n}\n\ninline const Matrix4 Matrix4::lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec )\n{\n    Matrix4 m4EyeFrame;\n    Vector3 v3X, v3Y, v3Z;\n    v3Y = normalize( upVec );\n    v3Z = normalize( ( eyePos - lookAtPos ) );\n    v3X = normalize( cross( v3Y, v3Z ) );\n    v3Y = cross( v3Z, v3X );\n    m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) );\n    return orthoInverse( m4EyeFrame );\n}\n\ninline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar )\n{\n    float f, rangeInv;\n    vec_float4 zero, col0, col1, col2, col3;\n    f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f );\n    rangeInv = 1.0f / ( zNear - zFar );\n    zero = spu_splats(0.0f);\n    col0 = zero;\n    col1 = zero;\n    col2 = zero;\n    col3 = zero;\n    col0 = spu_insert( f / aspect, col0, 0 );\n    col1 = spu_insert( f, col1, 1 );\n    col2 = spu_insert( ( zNear + zFar ) * rangeInv, col2, 2 );\n    col2 = spu_insert( -1.0f, col2, 3 );\n    col3 = spu_insert( zNear * zFar * rangeInv * 2.0f, col3, 2 );\n    return Matrix4(\n        Vector4( col0 ),\n        Vector4( col1 ),\n        Vector4( col2 ),\n        Vector4( col3 )\n    );\n}\n\ninline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff;\n    vec_float4 diagonal, column, near2;\n    vec_float4 zero = spu_splats(0.0f);\n    lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB );\n    lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB );\n    diff = spu_sub( rtn, lbf );\n    sum  = spu_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    near2 = spu_splats( zNear );\n    near2 = spu_add( near2, near2 );\n    diagonal = spu_mul( near2, inv_diff );\n    column = spu_mul( sum, inv_diff );\n    return Matrix4(\n        Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) ) ),\n        Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) ) ),\n        Vector4( spu_sel( column, spu_splats(-1.0f), (vec_uint4)spu_maskb(0x000f) ) ),\n        Vector4( spu_sel( zero, spu_mul( diagonal, spu_splats(zFar) ), (vec_uint4)spu_maskb(0x00f0) ) )\n    );\n}\n\ninline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar )\n{\n    /* function implementation based on code from STIDC SDK:           */\n    /* --------------------------------------------------------------  */\n    /* PLEASE DO NOT MODIFY THIS SECTION                               */\n    /* This prolog section is automatically generated.                 */\n    /*                                                                 */\n    /* (C)Copyright                                                    */\n    /* Sony Computer Entertainment, Inc.,                              */\n    /* Toshiba Corporation,                                            */\n    /* International Business Machines Corporation,                    */\n    /* 2001,2002.                                                      */\n    /* S/T/I Confidential Information                                  */\n    /* --------------------------------------------------------------  */\n    vec_float4 lbf, rtn;\n    vec_float4 diff, sum, inv_diff, neg_inv_diff;\n    vec_float4 diagonal, column;\n    vec_float4 zero = spu_splats(0.0f);\n    lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB );\n    lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB );\n    rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB );\n    diff = spu_sub( rtn, lbf );\n    sum  = spu_add( rtn, lbf );\n    inv_diff = recipf4( diff );\n    neg_inv_diff = negatef4( inv_diff );\n    diagonal = spu_add( inv_diff, inv_diff );\n    column = spu_mul( sum, spu_sel( neg_inv_diff, inv_diff, (vec_uint4)spu_maskb(0x00f0) ) );\n    return Matrix4(\n        Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) ) ),\n        Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) ) ),\n        Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x00f0) ) ),\n        Vector4( spu_sel( column, spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) ) )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix4 & mat )\n{\n    print( mat.getRow( 0 ) );\n    print( mat.getRow( 1 ) );\n    print( mat.getRow( 2 ) );\n    print( mat.getRow( 3 ) );\n}\n\ninline void print( const Matrix4 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Transform3::Transform3( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n}\n\ninline Transform3::Transform3( float scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( Vector3 _col0, Vector3 _col1, Vector3 _col2, Vector3 _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Transform3::Transform3( const Matrix3 & tfrm, Vector3 translateVec )\n{\n    this->setUpper3x3( tfrm );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( Quat unitQuat, Vector3 translateVec )\n{\n    this->setUpper3x3( Matrix3( unitQuat ) );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3 & Transform3::setCol0( Vector3 _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol1( Vector3 _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol2( Vector3 _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol3( Vector3 _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol( int col, Vector3 vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Transform3 & Transform3::setRow( int row, Vector4 vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, float val )\n{\n    (*this)[col].setElem(row, val);\n    return *this;\n}\n\ninline float Transform3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Transform3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Transform3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Transform3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Transform3::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector3 Transform3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Transform3::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector3 & Transform3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Transform3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Transform3 & Transform3::operator =( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n    return *this;\n}\n\ninline const Transform3 inverse( const Transform3 & tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() );\n    tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() );\n    tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() );\n    inv3 = negatef4( tfrm.getCol3().get128() );\n    dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() );\n    dot = spu_shuffle( dot, dot, shuffle_xxxx );\n    invdet = recipf4( dot );\n    tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB );\n    tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD );\n    inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB );\n    xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx );\n    inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 );\n    inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 );\n    yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy );\n    zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz );\n    inv3 = spu_mul( inv0, xxxx );\n    inv3 = spu_madd( inv1, yyyy, inv3 );\n    inv3 = spu_madd( inv2, zzzz, inv3 );\n    inv0 = spu_mul( inv0, invdet );\n    inv1 = spu_mul( inv1, invdet );\n    inv2 = spu_mul( inv2, invdet );\n    inv3 = spu_mul( inv3, invdet );\n    return Transform3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 ),\n        Vector3( inv3 )\n    );\n}\n\ninline const Transform3 orthoInverse( const Transform3 & tfrm )\n{\n    vec_float4 inv0, inv1, inv2, inv3;\n    vec_float4 tmp0, tmp1;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    tmp0 = spu_shuffle( tfrm.getCol0().get128(), tfrm.getCol2().get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( tfrm.getCol0().get128(), tfrm.getCol2().get128(), _VECTORMATH_SHUF_ZCWD );\n    inv3 = negatef4( tfrm.getCol3().get128() );\n    inv0 = spu_shuffle( tmp0, tfrm.getCol1().get128(), _VECTORMATH_SHUF_XAYB );\n    xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx );\n    inv1 = spu_shuffle( tmp0, tfrm.getCol1().get128(), _VECTORMATH_SHUF_ZBW0 );\n    inv2 = spu_shuffle( tmp1, tfrm.getCol1().get128(), _VECTORMATH_SHUF_XCY0 );\n    yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy );\n    zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz );\n    inv3 = spu_mul( inv0, xxxx );\n    inv3 = spu_madd( inv1, yyyy, inv3 );\n    inv3 = spu_madd( inv2, zzzz, inv3 );\n    return Transform3(\n        Vector3( inv0 ),\n        Vector3( inv1 ),\n        Vector3( inv2 ),\n        Vector3( inv3 )\n    );\n}\n\ninline const Transform3 absPerElem( const Transform3 & tfrm )\n{\n    return Transform3(\n        absPerElem( tfrm.getCol0() ),\n        absPerElem( tfrm.getCol1() ),\n        absPerElem( tfrm.getCol2() ),\n        absPerElem( tfrm.getCol3() )\n    );\n}\n\ninline const Vector3 Transform3::operator *( Vector3 vec ) const\n{\n    vec_float4 res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx );\n    yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy );\n    zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz );\n    res = spu_mul( mCol0.get128(), xxxx );\n    res = spu_madd( mCol1.get128(), yyyy, res );\n    res = spu_madd( mCol2.get128(), zzzz, res );\n    return Vector3( res );\n}\n\ninline const Point3 Transform3::operator *( Point3 pnt ) const\n{\n    vec_float4 tmp0, tmp1, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    xxxx = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_xxxx );\n    yyyy = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_yyyy );\n    zzzz = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_zzzz );\n    tmp0 = spu_mul( mCol0.get128(), xxxx );\n    tmp1 = spu_mul( mCol1.get128(), yyyy );\n    tmp0 = spu_madd( mCol2.get128(), zzzz, tmp0 );\n    tmp1 = spu_add( mCol3.get128(), tmp1 );\n    res = spu_add( tmp0, tmp1 );\n    return Point3( res );\n}\n\ninline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const\n{\n    return Transform3(\n        ( *this * tfrm.mCol0 ),\n        ( *this * tfrm.mCol1 ),\n        ( *this * tfrm.mCol2 ),\n        Vector3( ( *this * Point3( tfrm.mCol3 ) ) )\n    );\n}\n\ninline Transform3 & Transform3::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 )\n{\n    return Transform3(\n        mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ),\n        mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ),\n        mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ),\n        mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() )\n    );\n}\n\ninline const Transform3 Transform3::identity( )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm )\n{\n    mCol0 = tfrm.getCol0();\n    mCol1 = tfrm.getCol1();\n    mCol2 = tfrm.getCol2();\n    return *this;\n}\n\ninline const Matrix3 Transform3::getUpper3x3( ) const\n{\n    return Matrix3( mCol0, mCol1, mCol2 );\n}\n\ninline Transform3 & Transform3::setTranslation( Vector3 translateVec )\n{\n    mCol3 = translateVec;\n    return *this;\n}\n\ninline const Vector3 Transform3::getTranslation( ) const\n{\n    return mCol3;\n}\n\ninline const Transform3 Transform3::rotationX( float radians )\n{\n    vec_float4 s, c, res1, res2;\n    vec_uint4 select_y, select_z;\n    vec_float4 zero;\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res1 = spu_sel( zero, c, select_y );\n    res1 = spu_sel( res1, s, select_z );\n    res2 = spu_sel( zero, negatef4(s), select_y );\n    res2 = spu_sel( res2, c, select_z );\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3( res1 ),\n        Vector3( res2 ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationY( float radians )\n{\n    vec_float4 s, c, res0, res2;\n    vec_uint4 select_x, select_z;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_z = (vec_uint4)spu_maskb(0x00f0);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, negatef4(s), select_z );\n    res2 = spu_sel( zero, s, select_x );\n    res2 = spu_sel( res2, c, select_z );\n    return Transform3(\n        Vector3( res0 ),\n        Vector3::yAxis( ),\n        Vector3( res2 ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZ( float radians )\n{\n    vec_float4 s, c, res0, res1;\n    vec_uint4 select_x, select_y;\n    vec_float4 zero;\n    select_x = (vec_uint4)spu_maskb(0xf000);\n    select_y = (vec_uint4)spu_maskb(0x0f00);\n    zero = spu_splats(0.0f);\n    sincosf4( spu_splats(radians), &s, &c );\n    res0 = spu_sel( zero, c, select_x );\n    res0 = spu_sel( res0, s, select_y );\n    res1 = spu_sel( zero, negatef4(s), select_x );\n    res1 = spu_sel( res1, c, select_y );\n    return Transform3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3::zAxis( ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotationZYX( Vector3 radiansXYZ )\n{\n    vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    angles = radiansXYZ.get128();\n    angles = spu_insert( 0.0f, angles, 3 );\n    sincosf4( angles, &s, &c );\n    negS = negatef4( s );\n    Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 );\n    Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 );\n    Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 );\n    Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 );\n    X0 = spu_shuffle( s, s, shuffle_xxxx );\n    X1 = spu_shuffle( c, c, shuffle_xxxx );\n    tmp = spu_mul( Z0, Y1 );\n    return Transform3(\n        Vector3( spu_mul( Z0, Y0 ) ),\n        Vector3( spu_madd( Z1, X1, spu_mul( tmp, X0 ) ) ),\n        Vector3( spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 Transform3::rotation( float radians, Vector3 unitVec )\n{\n    return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::rotation( Quat unitQuat )\n{\n    return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) );\n}\n\ninline const Transform3 Transform3::scale( Vector3 scaleVec )\n{\n    vec_float4 zero = spu_splats(0.0f);\n    return Transform3(\n        Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0xf000) ) ),\n        Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x0f00) ) ),\n        Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x00f0) ) ),\n        Vector3( 0.0f )\n    );\n}\n\ninline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec )\n{\n    return Transform3(\n        ( tfrm.getCol0() * scaleVec.getX( ) ),\n        ( tfrm.getCol1() * scaleVec.getY( ) ),\n        ( tfrm.getCol2() * scaleVec.getZ( ) ),\n        tfrm.getCol3()\n    );\n}\n\ninline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm )\n{\n    return Transform3(\n        mulPerElem( tfrm.getCol0(), scaleVec ),\n        mulPerElem( tfrm.getCol1(), scaleVec ),\n        mulPerElem( tfrm.getCol2(), scaleVec ),\n        mulPerElem( tfrm.getCol3(), scaleVec )\n    );\n}\n\ninline const Transform3 Transform3::translation( Vector3 translateVec )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        translateVec\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Transform3 & tfrm )\n{\n    print( tfrm.getRow( 0 ) );\n    print( tfrm.getRow( 1 ) );\n    print( tfrm.getRow( 2 ) );\n}\n\ninline void print( const Transform3 & tfrm, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( tfrm );\n}\n\n#endif\n\ninline Quat::Quat( const Matrix3 & tfrm )\n{\n    vec_float4 res;\n    vec_float4 col0, col1, col2;\n    vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff;\n    vec_float4 zy_xz_yx, yz_zx_xy, sum, diff;\n    vec_float4 radicand, invSqrt, scale;\n    vec_float4 res0, res1, res2, res3;\n    vec_float4 xx, yy, zz;\n    vec_uint4 select_x = (vec_uint4)spu_maskb( 0xf000 );\n    vec_uint4 select_y = (vec_uint4)spu_maskb( 0x0f00 );\n    vec_uint4 select_z = (vec_uint4)spu_maskb( 0x00f0 );\n    vec_uint4 select_w = (vec_uint4)spu_maskb( 0x000f );\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((unsigned int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((unsigned int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((unsigned int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((unsigned int)0x0c0d0e0f);\n\n    col0 = tfrm.getCol0().get128();\n    col1 = tfrm.getCol1().get128();\n    col2 = tfrm.getCol2().get128();\n\n    /* four cases: */\n    /* trace > 0 */\n    /* else */\n    /*    xx largest diagonal element */\n    /*    yy largest diagonal element */\n    /*    zz largest diagonal element */\n\n    /* compute quaternion for each case */\n\n    xx_yy = spu_sel( col0, col1, select_y );\n    xx_yy_zz_xx = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_XYCX );\n    yy_zz_xx_yy = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_YCXY );\n    zz_xx_yy_zz = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_CXYC );\n\n    diagSum = spu_add( spu_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    diagDiff = spu_sub( spu_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz );\n    radicand = spu_add( spu_sel( diagDiff, diagSum, select_w ), spu_splats(1.0f) );\n    invSqrt = rsqrtf4( radicand );\n\n    zy_xz_yx = spu_sel( col0, col1, select_z );\n    zy_xz_yx = spu_shuffle( zy_xz_yx, col2, _VECTORMATH_SHUF_ZAY0 );\n    yz_zx_xy = spu_sel( col0, col1, select_x );\n    yz_zx_xy = spu_shuffle( yz_zx_xy, col2, _VECTORMATH_SHUF_BZX0 );\n\n    sum = spu_add( zy_xz_yx, yz_zx_xy );\n    diff = spu_sub( zy_xz_yx, yz_zx_xy );\n\n    scale = spu_mul( invSqrt, spu_splats(0.5f) );\n    res0 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_0ZYA );\n    res1 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_Z0XB );\n    res2 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_YX0C );\n    res3 = diff;\n    res0 = spu_sel( res0, radicand, select_x );\n    res1 = spu_sel( res1, radicand, select_y );\n    res2 = spu_sel( res2, radicand, select_z );\n    res3 = spu_sel( res3, radicand, select_w );\n    res0 = spu_mul( res0, spu_shuffle( scale, scale, shuffle_xxxx ) );\n    res1 = spu_mul( res1, spu_shuffle( scale, scale, shuffle_yyyy ) );\n    res2 = spu_mul( res2, spu_shuffle( scale, scale, shuffle_zzzz ) );\n    res3 = spu_mul( res3, spu_shuffle( scale, scale, shuffle_wwww ) );\n\n    /* determine case and select answer */\n\n    xx = spu_shuffle( col0, col0, shuffle_xxxx );\n    yy = spu_shuffle( col1, col1, shuffle_yyyy );\n    zz = spu_shuffle( col2, col2, shuffle_zzzz );\n    res = spu_sel( res0, res1, spu_cmpgt( yy, xx ) );\n    res = spu_sel( res, res2, spu_and( spu_cmpgt( zz, xx ), spu_cmpgt( zz, yy ) ) );\n    res = spu_sel( res, res3, spu_cmpgt( spu_shuffle( diagSum, diagSum, shuffle_xxxx ), spu_splats(0.0f) ) );\n    mVec128 = res;\n}\n\ninline const Matrix3 outer( Vector3 tfrm0, Vector3 tfrm1 )\n{\n    return Matrix3(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) )\n    );\n}\n\ninline const Matrix4 outer( Vector4 tfrm0, Vector4 tfrm1 )\n{\n    return Matrix4(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) ),\n        ( tfrm0 * tfrm1.getW( ) )\n    );\n}\n\ninline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat )\n{\n    vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res;\n    vec_float4 xxxx, yyyy, zzzz;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    tmp0 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_ZCWD );\n    xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx );\n    mcol0 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_XAYB );\n    mcol1 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_ZBW0 );\n    mcol2 = spu_shuffle( tmp1, mat.getCol1().get128(), _VECTORMATH_SHUF_XCY0 );\n    yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy );\n    res = spu_mul( mcol0, xxxx );\n    zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz );\n    res = spu_madd( mcol1, yyyy, res );\n    res = spu_madd( mcol2, zzzz, res );\n    return Vector3( res );\n}\n\ninline const Matrix3 crossMatrix( Vector3 vec )\n{\n    vec_float4 neg, res0, res1, res2;\n    neg = negatef4( vec.get128() );\n    res0 = spu_shuffle( vec.get128(), neg, _VECTORMATH_SHUF_0ZB0 );\n    res1 = spu_shuffle( vec.get128(), neg, _VECTORMATH_SHUF_C0X0 );\n    res2 = spu_shuffle( vec.get128(), neg, _VECTORMATH_SHUF_YA00 );\n    return Matrix3(\n        Vector3( res0 ),\n        Vector3( res1 ),\n        Vector3( res2 )\n    );\n}\n\ninline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat )\n{\n    return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) );\n}\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/mat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_MAT_SOA_CPP_H\n#define _VECTORMATH_MAT_SOA_CPP_H\n\nnamespace Vectormath {\nnamespace Soa {\n\n//-----------------------------------------------------------------------------\n// Constants\n\n#define _VECTORMATH_PI_OVER_2 1.570796327f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\ninline Matrix3::Matrix3( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n}\n\ninline Matrix3::Matrix3( vec_float4 scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n}\n\ninline Matrix3::Matrix3( const Quat & unitQuat )\n{\n    vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2;\n    qx = unitQuat.getX();\n    qy = unitQuat.getY();\n    qz = unitQuat.getZ();\n    qw = unitQuat.getW();\n    qx2 = spu_add( qx, qx );\n    qy2 = spu_add( qy, qy );\n    qz2 = spu_add( qz, qz );\n    qxqx2 = spu_mul( qx, qx2 );\n    qxqy2 = spu_mul( qx, qy2 );\n    qxqz2 = spu_mul( qx, qz2 );\n    qxqw2 = spu_mul( qw, qx2 );\n    qyqy2 = spu_mul( qy, qy2 );\n    qyqz2 = spu_mul( qy, qz2 );\n    qyqw2 = spu_mul( qw, qy2 );\n    qzqz2 = spu_mul( qz, qz2 );\n    qzqw2 = spu_mul( qw, qz2 );\n    mCol0 = Vector3( spu_sub( spu_sub( spu_splats(1.0f), qyqy2 ), qzqz2 ), spu_add( qxqy2, qzqw2 ), spu_sub( qxqz2, qyqw2 ) );\n    mCol1 = Vector3( spu_sub( qxqy2, qzqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qzqz2 ), spu_add( qyqz2, qxqw2 ) );\n    mCol2 = Vector3( spu_add( qxqz2, qyqw2 ), spu_sub( qyqz2, qxqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qyqy2 ) );\n}\n\ninline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n}\n\ninline Matrix3::Matrix3( const Aos::Matrix3 & mat )\n{\n    mCol0 = Vector3( mat.getCol0() );\n    mCol1 = Vector3( mat.getCol1() );\n    mCol2 = Vector3( mat.getCol2() );\n}\n\ninline Matrix3::Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 )\n{\n    mCol0 = Vector3( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() );\n    mCol1 = Vector3( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() );\n    mCol2 = Vector3( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() );\n}\n\ninline void Matrix3::get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const\n{\n    Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol0( tmpV3_0 );\n    result1.setCol0( tmpV3_1 );\n    result2.setCol0( tmpV3_2 );\n    result3.setCol0( tmpV3_3 );\n    mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol1( tmpV3_0 );\n    result1.setCol1( tmpV3_1 );\n    result2.setCol1( tmpV3_2 );\n    result3.setCol1( tmpV3_3 );\n    mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol2( tmpV3_0 );\n    result1.setCol2( tmpV3_1 );\n    result2.setCol2( tmpV3_2 );\n    result3.setCol2( tmpV3_3 );\n}\n\ninline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    return *this;\n}\n\ninline Matrix3 & Matrix3::setElem( int col, int row, vec_float4 val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline vec_float4 Matrix3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Matrix3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Matrix3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Matrix3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Matrix3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::getRow( int row ) const\n{\n    return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) );\n}\n\ninline Vector3 & Matrix3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Matrix3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix3 & Matrix3::operator =( const Matrix3 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    return *this;\n}\n\ninline const Matrix3 transpose( const Matrix3 & mat )\n{\n    return Matrix3(\n        Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ),\n        Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ),\n        Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() )\n    );\n}\n\ninline const Matrix3 inverse( const Matrix3 & mat )\n{\n    Vector3 tmp0, tmp1, tmp2;\n    vec_float4 detinv;\n    tmp0 = cross( mat.getCol1(), mat.getCol2() );\n    tmp1 = cross( mat.getCol2(), mat.getCol0() );\n    tmp2 = cross( mat.getCol0(), mat.getCol1() );\n    detinv = recipf4( dot( mat.getCol2(), tmp2 ) );\n    return Matrix3(\n        Vector3( spu_mul( tmp0.getX(), detinv ), spu_mul( tmp1.getX(), detinv ), spu_mul( tmp2.getX(), detinv ) ),\n        Vector3( spu_mul( tmp0.getY(), detinv ), spu_mul( tmp1.getY(), detinv ), spu_mul( tmp2.getY(), detinv ) ),\n        Vector3( spu_mul( tmp0.getZ(), detinv ), spu_mul( tmp1.getZ(), detinv ), spu_mul( tmp2.getZ(), detinv ) )\n    );\n}\n\ninline vec_float4 determinant( const Matrix3 & mat )\n{\n    return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) );\n}\n\ninline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 )\n    );\n}\n\ninline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator +=( const Matrix3 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix3 & Matrix3::operator -=( const Matrix3 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix3 Matrix3::operator -( ) const\n{\n    return Matrix3(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 )\n    );\n}\n\ninline const Matrix3 absPerElem( const Matrix3 & mat )\n{\n    return Matrix3(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( vec_float4 scalar ) const\n{\n    return Matrix3(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector3 Matrix3::operator *( const Vector3 & vec ) const\n{\n    return Vector3(\n        spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) )\n    );\n}\n\ninline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const\n{\n    return Matrix3(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 )\n    );\n}\n\ninline Matrix3 & Matrix3::operator *=( const Matrix3 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 )\n{\n    return Matrix3(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() )\n    );\n}\n\ninline const Matrix3 Matrix3::identity( )\n{\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix3(\n        Vector3::xAxis( ),\n        Vector3( spu_splats(0.0f), c, s ),\n        Vector3( spu_splats(0.0f), negatef4( s ), c )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix3(\n        Vector3( c, spu_splats(0.0f), negatef4( s ) ),\n        Vector3::yAxis( ),\n        Vector3( s, spu_splats(0.0f), c )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix3(\n        Vector3( c, s, spu_splats(0.0f) ),\n        Vector3( negatef4( s ), c, spu_splats(0.0f) ),\n        Vector3::zAxis( )\n    );\n}\n\ninline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ.getX(), &sX, &cX );\n    sincosf4( radiansXYZ.getY(), &sY, &cY );\n    sincosf4( radiansXYZ.getZ(), &sZ, &cZ );\n    tmp0 = spu_mul( cZ, sY );\n    tmp1 = spu_mul( sZ, sY );\n    return Matrix3(\n        Vector3( spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) ),\n        Vector3( spu_sub( spu_mul( tmp0, sX ), spu_mul( sZ, cX ) ), spu_add( spu_mul( tmp1, sX ), spu_mul( cZ, cX ) ), spu_mul( cY, sX ) ),\n        Vector3( spu_add( spu_mul( tmp0, cX ), spu_mul( sZ, sX ) ), spu_sub( spu_mul( tmp1, cX ), spu_mul( cZ, sX ) ), spu_mul( cY, cX ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec.getX();\n    y = unitVec.getY();\n    z = unitVec.getZ();\n    xy = spu_mul( x, y );\n    yz = spu_mul( y, z );\n    zx = spu_mul( z, x );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    return Matrix3(\n        Vector3( spu_add( spu_mul( spu_mul( x, x ), oneMinusC ), c ), spu_add( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_sub( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ) ),\n        Vector3( spu_sub( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_add( spu_mul( spu_mul( y, y ), oneMinusC ), c ), spu_add( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ) ),\n        Vector3( spu_add( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ), spu_sub( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ), spu_add( spu_mul( spu_mul( z, z ), oneMinusC ), c ) )\n    );\n}\n\ninline const Matrix3 Matrix3::rotation( const Quat & unitQuat )\n{\n    return Matrix3( unitQuat );\n}\n\ninline const Matrix3 Matrix3::scale( const Vector3 & scaleVec )\n{\n    return Matrix3(\n        Vector3( scaleVec.getX(), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector3( spu_splats(0.0f), scaleVec.getY(), spu_splats(0.0f) ),\n        Vector3( spu_splats(0.0f), spu_splats(0.0f), scaleVec.getZ() )\n    );\n}\n\ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec )\n{\n    return Matrix3(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) )\n    );\n}\n\ninline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat )\n{\n    return Matrix3(\n        mulPerElem( mat.getCol0(), scaleVec ),\n        mulPerElem( mat.getCol1(), scaleVec ),\n        mulPerElem( mat.getCol2(), scaleVec )\n    );\n}\n\ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 )\n{\n    return Matrix3(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix3 & mat )\n{\n    Aos::Matrix3 mat0, mat1, mat2, mat3;\n    mat.get4Aos( mat0, mat1, mat2, mat3 );\n    printf(\"slot 0:\\n\");\n    print( mat0 );\n    printf(\"slot 1:\\n\");\n    print( mat1 );\n    printf(\"slot 2:\\n\");\n    print( mat2 );\n    printf(\"slot 3:\\n\");\n    print( mat3 );\n}\n\ninline void print( const Matrix3 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Matrix4::Matrix4( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n}\n\ninline Matrix4::Matrix4( vec_float4 scalar )\n{\n    mCol0 = Vector4( scalar );\n    mCol1 = Vector4( scalar );\n    mCol2 = Vector4( scalar );\n    mCol3 = Vector4( scalar );\n}\n\ninline Matrix4::Matrix4( const Transform3 & mat )\n{\n    mCol0 = Vector4( mat.getCol0(), spu_splats(0.0f) );\n    mCol1 = Vector4( mat.getCol1(), spu_splats(0.0f) );\n    mCol2 = Vector4( mat.getCol2(), spu_splats(0.0f) );\n    mCol3 = Vector4( mat.getCol3(), spu_splats(1.0f) );\n}\n\ninline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec )\n{\n    mCol0 = Vector4( mat.getCol0(), spu_splats(0.0f) );\n    mCol1 = Vector4( mat.getCol1(), spu_splats(0.0f) );\n    mCol2 = Vector4( mat.getCol2(), spu_splats(0.0f) );\n    mCol3 = Vector4( translateVec, spu_splats(1.0f) );\n}\n\ninline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec )\n{\n    Matrix3 mat;\n    mat = Matrix3( unitQuat );\n    mCol0 = Vector4( mat.getCol0(), spu_splats(0.0f) );\n    mCol1 = Vector4( mat.getCol1(), spu_splats(0.0f) );\n    mCol2 = Vector4( mat.getCol2(), spu_splats(0.0f) );\n    mCol3 = Vector4( translateVec, spu_splats(1.0f) );\n}\n\ninline Matrix4::Matrix4( const Aos::Matrix4 & mat )\n{\n    mCol0 = Vector4( mat.getCol0() );\n    mCol1 = Vector4( mat.getCol1() );\n    mCol2 = Vector4( mat.getCol2() );\n    mCol3 = Vector4( mat.getCol3() );\n}\n\ninline Matrix4::Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 )\n{\n    mCol0 = Vector4( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() );\n    mCol1 = Vector4( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() );\n    mCol2 = Vector4( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() );\n    mCol3 = Vector4( mat0.getCol3(), mat1.getCol3(), mat2.getCol3(), mat3.getCol3() );\n}\n\ninline void Matrix4::get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const\n{\n    Aos::Vector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3;\n    mCol0.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol0( tmpV4_0 );\n    result1.setCol0( tmpV4_1 );\n    result2.setCol0( tmpV4_2 );\n    result3.setCol0( tmpV4_3 );\n    mCol1.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol1( tmpV4_0 );\n    result1.setCol1( tmpV4_1 );\n    result2.setCol1( tmpV4_2 );\n    result3.setCol1( tmpV4_3 );\n    mCol2.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol2( tmpV4_0 );\n    result1.setCol2( tmpV4_1 );\n    result2.setCol2( tmpV4_2 );\n    result3.setCol2( tmpV4_3 );\n    mCol3.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 );\n    result0.setCol3( tmpV4_0 );\n    result1.setCol3( tmpV4_1 );\n    result2.setCol3( tmpV4_2 );\n    result3.setCol3( tmpV4_3 );\n}\n\ninline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Matrix4 & Matrix4::setElem( int col, int row, vec_float4 val )\n{\n    Vector4 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline vec_float4 Matrix4::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector4 Matrix4::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector4 Matrix4::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector4 Matrix4::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector4 Matrix4::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector4 Matrix4::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector4 & Matrix4::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Matrix4::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Matrix4 & Matrix4::operator =( const Matrix4 & mat )\n{\n    mCol0 = mat.mCol0;\n    mCol1 = mat.mCol1;\n    mCol2 = mat.mCol2;\n    mCol3 = mat.mCol3;\n    return *this;\n}\n\ninline const Matrix4 transpose( const Matrix4 & mat )\n{\n    return Matrix4(\n        Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ),\n        Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ),\n        Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ),\n        Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() )\n    );\n}\n\ninline const Matrix4 inverse( const Matrix4 & mat )\n{\n    Vector4 res0, res1, res2, res3;\n    vec_float4 mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv;\n    mA = mat.getCol0().getX();\n    mB = mat.getCol0().getY();\n    mC = mat.getCol0().getZ();\n    mD = mat.getCol0().getW();\n    mE = mat.getCol1().getX();\n    mF = mat.getCol1().getY();\n    mG = mat.getCol1().getZ();\n    mH = mat.getCol1().getW();\n    mI = mat.getCol2().getX();\n    mJ = mat.getCol2().getY();\n    mK = mat.getCol2().getZ();\n    mL = mat.getCol2().getW();\n    mM = mat.getCol3().getX();\n    mN = mat.getCol3().getY();\n    mO = mat.getCol3().getZ();\n    mP = mat.getCol3().getW();\n    tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) );\n    tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) );\n    tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) );\n    tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) );\n    tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) );\n    tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) );\n    res0.setX( spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) ) );\n    res0.setY( spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) ) );\n    res0.setZ( spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) ) );\n    res0.setW( spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) ) );\n    detInv = recipf4( spu_add( spu_add( spu_add( spu_mul( mA, res0.getX() ), spu_mul( mE, res0.getY() ) ), spu_mul( mI, res0.getZ() ) ), spu_mul( mM, res0.getW() ) ) );\n    res1.setX( spu_mul( mI, tmp1 ) );\n    res1.setY( spu_mul( mM, tmp0 ) );\n    res1.setZ( spu_mul( mA, tmp1 ) );\n    res1.setW( spu_mul( mE, tmp0 ) );\n    res3.setX( spu_mul( mI, tmp3 ) );\n    res3.setY( spu_mul( mM, tmp2 ) );\n    res3.setZ( spu_mul( mA, tmp3 ) );\n    res3.setW( spu_mul( mE, tmp2 ) );\n    res2.setX( spu_mul( mI, tmp5 ) );\n    res2.setY( spu_mul( mM, tmp4 ) );\n    res2.setZ( spu_mul( mA, tmp5 ) );\n    res2.setW( spu_mul( mE, tmp4 ) );\n    tmp0 = spu_sub( spu_mul( mI, mB ), spu_mul( mA, mJ ) );\n    tmp1 = spu_sub( spu_mul( mM, mF ), spu_mul( mE, mN ) );\n    tmp2 = spu_sub( spu_mul( mI, mD ), spu_mul( mA, mL ) );\n    tmp3 = spu_sub( spu_mul( mM, mH ), spu_mul( mE, mP ) );\n    tmp4 = spu_sub( spu_mul( mI, mC ), spu_mul( mA, mK ) );\n    tmp5 = spu_sub( spu_mul( mM, mG ), spu_mul( mE, mO ) );\n    res2.setX( spu_add( spu_sub( spu_mul( mL, tmp1 ), spu_mul( mJ, tmp3 ) ), res2.getX() ) );\n    res2.setY( spu_add( spu_sub( spu_mul( mP, tmp0 ), spu_mul( mN, tmp2 ) ), res2.getY() ) );\n    res2.setZ( spu_sub( spu_sub( spu_mul( mB, tmp3 ), spu_mul( mD, tmp1 ) ), res2.getZ() ) );\n    res2.setW( spu_sub( spu_sub( spu_mul( mF, tmp2 ), spu_mul( mH, tmp0 ) ), res2.getW() ) );\n    res3.setX( spu_add( spu_sub( spu_mul( mJ, tmp5 ), spu_mul( mK, tmp1 ) ), res3.getX() ) );\n    res3.setY( spu_add( spu_sub( spu_mul( mN, tmp4 ), spu_mul( mO, tmp0 ) ), res3.getY() ) );\n    res3.setZ( spu_sub( spu_sub( spu_mul( mC, tmp1 ), spu_mul( mB, tmp5 ) ), res3.getZ() ) );\n    res3.setW( spu_sub( spu_sub( spu_mul( mG, tmp0 ), spu_mul( mF, tmp4 ) ), res3.getW() ) );\n    res1.setX( spu_sub( spu_sub( spu_mul( mK, tmp3 ), spu_mul( mL, tmp5 ) ), res1.getX() ) );\n    res1.setY( spu_sub( spu_sub( spu_mul( mO, tmp2 ), spu_mul( mP, tmp4 ) ), res1.getY() ) );\n    res1.setZ( spu_add( spu_sub( spu_mul( mD, tmp5 ), spu_mul( mC, tmp3 ) ), res1.getZ() ) );\n    res1.setW( spu_add( spu_sub( spu_mul( mH, tmp4 ), spu_mul( mG, tmp2 ) ), res1.getW() ) );\n    return Matrix4(\n        ( res0 * detInv ),\n        ( res1 * detInv ),\n        ( res2 * detInv ),\n        ( res3 * detInv )\n    );\n}\n\ninline const Matrix4 affineInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( inverse( affineMat ) );\n}\n\ninline const Matrix4 orthoInverse( const Matrix4 & mat )\n{\n    Transform3 affineMat;\n    affineMat.setCol0( mat.getCol0().getXYZ( ) );\n    affineMat.setCol1( mat.getCol1().getXYZ( ) );\n    affineMat.setCol2( mat.getCol2().getXYZ( ) );\n    affineMat.setCol3( mat.getCol3().getXYZ( ) );\n    return Matrix4( orthoInverse( affineMat ) );\n}\n\ninline vec_float4 determinant( const Matrix4 & mat )\n{\n    vec_float4 dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;\n    mA = mat.getCol0().getX();\n    mB = mat.getCol0().getY();\n    mC = mat.getCol0().getZ();\n    mD = mat.getCol0().getW();\n    mE = mat.getCol1().getX();\n    mF = mat.getCol1().getY();\n    mG = mat.getCol1().getZ();\n    mH = mat.getCol1().getW();\n    mI = mat.getCol2().getX();\n    mJ = mat.getCol2().getY();\n    mK = mat.getCol2().getZ();\n    mL = mat.getCol2().getW();\n    mM = mat.getCol3().getX();\n    mN = mat.getCol3().getY();\n    mO = mat.getCol3().getZ();\n    mP = mat.getCol3().getW();\n    tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) );\n    tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) );\n    tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) );\n    tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) );\n    tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) );\n    tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) );\n    dx = spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) );\n    dy = spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) );\n    dz = spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) );\n    dw = spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) );\n    return spu_add( spu_add( spu_add( spu_mul( mA, dx ), spu_mul( mE, dy ) ), spu_mul( mI, dz ) ), spu_mul( mM, dw ) );\n}\n\ninline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 + mat.mCol0 ),\n        ( mCol1 + mat.mCol1 ),\n        ( mCol2 + mat.mCol2 ),\n        ( mCol3 + mat.mCol3 )\n    );\n}\n\ninline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( mCol0 - mat.mCol0 ),\n        ( mCol1 - mat.mCol1 ),\n        ( mCol2 - mat.mCol2 ),\n        ( mCol3 - mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator +=( const Matrix4 & mat )\n{\n    *this = *this + mat;\n    return *this;\n}\n\ninline Matrix4 & Matrix4::operator -=( const Matrix4 & mat )\n{\n    *this = *this - mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator -( ) const\n{\n    return Matrix4(\n        ( -mCol0 ),\n        ( -mCol1 ),\n        ( -mCol2 ),\n        ( -mCol3 )\n    );\n}\n\ninline const Matrix4 absPerElem( const Matrix4 & mat )\n{\n    return Matrix4(\n        absPerElem( mat.getCol0() ),\n        absPerElem( mat.getCol1() ),\n        absPerElem( mat.getCol2() ),\n        absPerElem( mat.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( vec_float4 scalar ) const\n{\n    return Matrix4(\n        ( mCol0 * scalar ),\n        ( mCol1 * scalar ),\n        ( mCol2 * scalar ),\n        ( mCol3 * scalar )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat )\n{\n    return mat * scalar;\n}\n\ninline const Vector4 Matrix4::operator *( const Vector4 & vec ) const\n{\n    return Vector4(\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ), spu_mul( mCol3.getX(), vec.getW() ) ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ), spu_mul( mCol3.getY(), vec.getW() ) ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) ), spu_mul( mCol3.getZ(), vec.getW() ) ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getW(), vec.getX() ), spu_mul( mCol1.getW(), vec.getY() ) ), spu_mul( mCol2.getW(), vec.getZ() ) ), spu_mul( mCol3.getW(), vec.getW() ) )\n    );\n}\n\ninline const Vector4 Matrix4::operator *( const Vector3 & vec ) const\n{\n    return Vector4(\n        spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getW(), vec.getX() ), spu_mul( mCol1.getW(), vec.getY() ) ), spu_mul( mCol2.getW(), vec.getZ() ) )\n    );\n}\n\ninline const Vector4 Matrix4::operator *( const Point3 & pnt ) const\n{\n    return Vector4(\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getX(), pnt.getX() ), spu_mul( mCol1.getX(), pnt.getY() ) ), spu_mul( mCol2.getX(), pnt.getZ() ) ), mCol3.getX() ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getY(), pnt.getX() ), spu_mul( mCol1.getY(), pnt.getY() ) ), spu_mul( mCol2.getY(), pnt.getZ() ) ), mCol3.getY() ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getZ(), pnt.getX() ), spu_mul( mCol1.getZ(), pnt.getY() ) ), spu_mul( mCol2.getZ(), pnt.getZ() ) ), mCol3.getZ() ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getW(), pnt.getX() ), spu_mul( mCol1.getW(), pnt.getY() ) ), spu_mul( mCol2.getW(), pnt.getZ() ) ), mCol3.getW() )\n    );\n}\n\ninline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const\n{\n    return Matrix4(\n        ( *this * mat.mCol0 ),\n        ( *this * mat.mCol1 ),\n        ( *this * mat.mCol2 ),\n        ( *this * mat.mCol3 )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Matrix4 & mat )\n{\n    *this = *this * mat;\n    return *this;\n}\n\ninline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const\n{\n    return Matrix4(\n        ( *this * tfrm.getCol0() ),\n        ( *this * tfrm.getCol1() ),\n        ( *this * tfrm.getCol2() ),\n        ( *this * Point3( tfrm.getCol3() ) )\n    );\n}\n\ninline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 )\n{\n    return Matrix4(\n        mulPerElem( mat0.getCol0(), mat1.getCol0() ),\n        mulPerElem( mat0.getCol1(), mat1.getCol1() ),\n        mulPerElem( mat0.getCol2(), mat1.getCol2() ),\n        mulPerElem( mat0.getCol3(), mat1.getCol3() )\n    );\n}\n\ninline const Matrix4 Matrix4::identity( )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 )\n{\n    mCol0.setXYZ( mat3.getCol0() );\n    mCol1.setXYZ( mat3.getCol1() );\n    mCol2.setXYZ( mat3.getCol2() );\n    return *this;\n}\n\ninline const Matrix3 Matrix4::getUpper3x3( ) const\n{\n    return Matrix3(\n        mCol0.getXYZ( ),\n        mCol1.getXYZ( ),\n        mCol2.getXYZ( )\n    );\n}\n\ninline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec )\n{\n    mCol3.setXYZ( translateVec );\n    return *this;\n}\n\ninline const Vector3 Matrix4::getTranslation( ) const\n{\n    return mCol3.getXYZ( );\n}\n\ninline const Matrix4 Matrix4::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4( spu_splats(0.0f), c, s, spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), negatef4( s ), c, spu_splats(0.0f) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix4(\n        Vector4( c, spu_splats(0.0f), negatef4( s ), spu_splats(0.0f) ),\n        Vector4::yAxis( ),\n        Vector4( s, spu_splats(0.0f), c, spu_splats(0.0f) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Matrix4(\n        Vector4( c, s, spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( negatef4( s ), c, spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4::zAxis( ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ.getX(), &sX, &cX );\n    sincosf4( radiansXYZ.getY(), &sY, &cY );\n    sincosf4( radiansXYZ.getZ(), &sZ, &cZ );\n    tmp0 = spu_mul( cZ, sY );\n    tmp1 = spu_mul( sZ, sY );\n    return Matrix4(\n        Vector4( spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ), spu_splats(0.0f) ),\n        Vector4( spu_sub( spu_mul( tmp0, sX ), spu_mul( sZ, cX ) ), spu_add( spu_mul( tmp1, sX ), spu_mul( cZ, cX ) ), spu_mul( cY, sX ), spu_splats(0.0f) ),\n        Vector4( spu_add( spu_mul( tmp0, cX ), spu_mul( sZ, sX ) ), spu_sub( spu_mul( tmp1, cX ), spu_mul( cZ, sX ) ), spu_mul( cY, cX ), spu_splats(0.0f) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx;\n    sincosf4( radians, &s, &c );\n    x = unitVec.getX();\n    y = unitVec.getY();\n    z = unitVec.getZ();\n    xy = spu_mul( x, y );\n    yz = spu_mul( y, z );\n    zx = spu_mul( z, x );\n    oneMinusC = spu_sub( spu_splats(1.0f), c );\n    return Matrix4(\n        Vector4( spu_add( spu_mul( spu_mul( x, x ), oneMinusC ), c ), spu_add( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_sub( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ), spu_splats(0.0f) ),\n        Vector4( spu_sub( spu_mul( xy, oneMinusC ), spu_mul( z, s ) ), spu_add( spu_mul( spu_mul( y, y ), oneMinusC ), c ), spu_add( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ), spu_splats(0.0f) ),\n        Vector4( spu_add( spu_mul( zx, oneMinusC ), spu_mul( y, s ) ), spu_sub( spu_mul( yz, oneMinusC ), spu_mul( x, s ) ), spu_add( spu_mul( spu_mul( z, z ), oneMinusC ), c ), spu_splats(0.0f) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 Matrix4::rotation( const Quat & unitQuat )\n{\n    return Matrix4( Transform3::rotation( unitQuat ) );\n}\n\ninline const Matrix4 Matrix4::scale( const Vector3 & scaleVec )\n{\n    return Matrix4(\n        Vector4( scaleVec.getX(), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), scaleVec.getY(), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), spu_splats(0.0f), scaleVec.getZ(), spu_splats(0.0f) ),\n        Vector4::wAxis( )\n    );\n}\n\ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec )\n{\n    return Matrix4(\n        ( mat.getCol0() * scaleVec.getX( ) ),\n        ( mat.getCol1() * scaleVec.getY( ) ),\n        ( mat.getCol2() * scaleVec.getZ( ) ),\n        mat.getCol3()\n    );\n}\n\ninline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat )\n{\n    Vector4 scale4;\n    scale4 = Vector4( scaleVec, spu_splats(1.0f) );\n    return Matrix4(\n        mulPerElem( mat.getCol0(), scale4 ),\n        mulPerElem( mat.getCol1(), scale4 ),\n        mulPerElem( mat.getCol2(), scale4 ),\n        mulPerElem( mat.getCol3(), scale4 )\n    );\n}\n\ninline const Matrix4 Matrix4::translation( const Vector3 & translateVec )\n{\n    return Matrix4(\n        Vector4::xAxis( ),\n        Vector4::yAxis( ),\n        Vector4::zAxis( ),\n        Vector4( translateVec, spu_splats(1.0f) )\n    );\n}\n\ninline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec )\n{\n    Matrix4 m4EyeFrame;\n    Vector3 v3X, v3Y, v3Z;\n    v3Y = normalize( upVec );\n    v3Z = normalize( ( eyePos - lookAtPos ) );\n    v3X = normalize( cross( v3Y, v3Z ) );\n    v3Y = cross( v3Z, v3X );\n    m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) );\n    return orthoInverse( m4EyeFrame );\n}\n\ninline const Matrix4 Matrix4::perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 f, rangeInv;\n    f = tanf4( spu_sub( spu_splats( _VECTORMATH_PI_OVER_2 ), spu_mul( spu_splats(0.5f), fovyRadians ) ) );\n    rangeInv = recipf4( spu_sub( zNear, zFar ) );\n    return Matrix4(\n        Vector4( divf4( f, aspect ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), f, spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_add( zNear, zFar ), rangeInv ), spu_splats(-1.0f) ),\n        Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_mul( spu_mul( zNear, zFar ), rangeInv ), spu_splats(2.0f) ), spu_splats(0.0f) )\n    );\n}\n\ninline const Matrix4 Matrix4::frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2;\n    sum_rl = spu_add( right, left );\n    sum_tb = spu_add( top, bottom );\n    sum_nf = spu_add( zNear, zFar );\n    inv_rl = recipf4( spu_sub( right, left ) );\n    inv_tb = recipf4( spu_sub( top, bottom ) );\n    inv_nf = recipf4( spu_sub( zNear, zFar ) );\n    n2 = spu_add( zNear, zNear );\n    return Matrix4(\n        Vector4( spu_mul( n2, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), spu_mul( n2, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_mul( sum_rl, inv_rl ), spu_mul( sum_tb, inv_tb ), spu_mul( sum_nf, inv_nf ), spu_splats(-1.0f) ),\n        Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_mul( n2, inv_nf ), zFar ), spu_splats(0.0f) )\n    );\n}\n\ninline const Matrix4 Matrix4::orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar )\n{\n    vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf;\n    sum_rl = spu_add( right, left );\n    sum_tb = spu_add( top, bottom );\n    sum_nf = spu_add( zNear, zFar );\n    inv_rl = recipf4( spu_sub( right, left ) );\n    inv_tb = recipf4( spu_sub( top, bottom ) );\n    inv_nf = recipf4( spu_sub( zNear, zFar ) );\n    return Matrix4(\n        Vector4( spu_add( inv_rl, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), spu_add( inv_tb, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_add( inv_nf, inv_nf ), spu_splats(0.0f) ),\n        Vector4( spu_mul( negatef4( sum_rl ), inv_rl ), spu_mul( negatef4( sum_tb ), inv_tb ), spu_mul( sum_nf, inv_nf ), spu_splats(1.0f) )\n    );\n}\n\ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 )\n{\n    return Matrix4(\n        select( mat0.getCol0(), mat1.getCol0(), select1 ),\n        select( mat0.getCol1(), mat1.getCol1(), select1 ),\n        select( mat0.getCol2(), mat1.getCol2(), select1 ),\n        select( mat0.getCol3(), mat1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Matrix4 & mat )\n{\n    Aos::Matrix4 mat0, mat1, mat2, mat3;\n    mat.get4Aos( mat0, mat1, mat2, mat3 );\n    printf(\"slot 0:\\n\");\n    print( mat0 );\n    printf(\"slot 1:\\n\");\n    print( mat1 );\n    printf(\"slot 2:\\n\");\n    print( mat2 );\n    printf(\"slot 3:\\n\");\n    print( mat3 );\n}\n\ninline void print( const Matrix4 & mat, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( mat );\n}\n\n#endif\n\ninline Transform3::Transform3( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n}\n\ninline Transform3::Transform3( vec_float4 scalar )\n{\n    mCol0 = Vector3( scalar );\n    mCol1 = Vector3( scalar );\n    mCol2 = Vector3( scalar );\n    mCol3 = Vector3( scalar );\n}\n\ninline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 )\n{\n    mCol0 = _col0;\n    mCol1 = _col1;\n    mCol2 = _col2;\n    mCol3 = _col3;\n}\n\ninline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec )\n{\n    this->setUpper3x3( tfrm );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec )\n{\n    this->setUpper3x3( Matrix3( unitQuat ) );\n    this->setTranslation( translateVec );\n}\n\ninline Transform3::Transform3( const Aos::Transform3 & tfrm )\n{\n    mCol0 = Vector3( tfrm.getCol0() );\n    mCol1 = Vector3( tfrm.getCol1() );\n    mCol2 = Vector3( tfrm.getCol2() );\n    mCol3 = Vector3( tfrm.getCol3() );\n}\n\ninline Transform3::Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 )\n{\n    mCol0 = Vector3( tfrm0.getCol0(), tfrm1.getCol0(), tfrm2.getCol0(), tfrm3.getCol0() );\n    mCol1 = Vector3( tfrm0.getCol1(), tfrm1.getCol1(), tfrm2.getCol1(), tfrm3.getCol1() );\n    mCol2 = Vector3( tfrm0.getCol2(), tfrm1.getCol2(), tfrm2.getCol2(), tfrm3.getCol2() );\n    mCol3 = Vector3( tfrm0.getCol3(), tfrm1.getCol3(), tfrm2.getCol3(), tfrm3.getCol3() );\n}\n\ninline void Transform3::get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const\n{\n    Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3;\n    mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol0( tmpV3_0 );\n    result1.setCol0( tmpV3_1 );\n    result2.setCol0( tmpV3_2 );\n    result3.setCol0( tmpV3_3 );\n    mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol1( tmpV3_0 );\n    result1.setCol1( tmpV3_1 );\n    result2.setCol1( tmpV3_2 );\n    result3.setCol1( tmpV3_3 );\n    mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol2( tmpV3_0 );\n    result1.setCol2( tmpV3_1 );\n    result2.setCol2( tmpV3_2 );\n    result3.setCol2( tmpV3_3 );\n    mCol3.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 );\n    result0.setCol3( tmpV3_0 );\n    result1.setCol3( tmpV3_1 );\n    result2.setCol3( tmpV3_2 );\n    result3.setCol3( tmpV3_3 );\n}\n\ninline Transform3 & Transform3::setCol0( const Vector3 & _col0 )\n{\n    mCol0 = _col0;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol1( const Vector3 & _col1 )\n{\n    mCol1 = _col1;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol2( const Vector3 & _col2 )\n{\n    mCol2 = _col2;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol3( const Vector3 & _col3 )\n{\n    mCol3 = _col3;\n    return *this;\n}\n\ninline Transform3 & Transform3::setCol( int col, const Vector3 & vec )\n{\n    *(&mCol0 + col) = vec;\n    return *this;\n}\n\ninline Transform3 & Transform3::setRow( int row, const Vector4 & vec )\n{\n    mCol0.setElem( row, vec.getElem( 0 ) );\n    mCol1.setElem( row, vec.getElem( 1 ) );\n    mCol2.setElem( row, vec.getElem( 2 ) );\n    mCol3.setElem( row, vec.getElem( 3 ) );\n    return *this;\n}\n\ninline Transform3 & Transform3::setElem( int col, int row, vec_float4 val )\n{\n    Vector3 tmpV3_0;\n    tmpV3_0 = this->getCol( col );\n    tmpV3_0.setElem( row, val );\n    this->setCol( col, tmpV3_0 );\n    return *this;\n}\n\ninline vec_float4 Transform3::getElem( int col, int row ) const\n{\n    return this->getCol( col ).getElem( row );\n}\n\ninline const Vector3 Transform3::getCol0( ) const\n{\n    return mCol0;\n}\n\ninline const Vector3 Transform3::getCol1( ) const\n{\n    return mCol1;\n}\n\ninline const Vector3 Transform3::getCol2( ) const\n{\n    return mCol2;\n}\n\ninline const Vector3 Transform3::getCol3( ) const\n{\n    return mCol3;\n}\n\ninline const Vector3 Transform3::getCol( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector4 Transform3::getRow( int row ) const\n{\n    return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) );\n}\n\ninline Vector3 & Transform3::operator []( int col )\n{\n    return *(&mCol0 + col);\n}\n\ninline const Vector3 Transform3::operator []( int col ) const\n{\n    return *(&mCol0 + col);\n}\n\ninline Transform3 & Transform3::operator =( const Transform3 & tfrm )\n{\n    mCol0 = tfrm.mCol0;\n    mCol1 = tfrm.mCol1;\n    mCol2 = tfrm.mCol2;\n    mCol3 = tfrm.mCol3;\n    return *this;\n}\n\ninline const Transform3 inverse( const Transform3 & tfrm )\n{\n    Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2;\n    vec_float4 detinv;\n    tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() );\n    tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() );\n    tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() );\n    detinv = recipf4( dot( tfrm.getCol2(), tmp2 ) );\n    inv0 = Vector3( spu_mul( tmp0.getX(), detinv ), spu_mul( tmp1.getX(), detinv ), spu_mul( tmp2.getX(), detinv ) );\n    inv1 = Vector3( spu_mul( tmp0.getY(), detinv ), spu_mul( tmp1.getY(), detinv ), spu_mul( tmp2.getY(), detinv ) );\n    inv2 = Vector3( spu_mul( tmp0.getZ(), detinv ), spu_mul( tmp1.getZ(), detinv ), spu_mul( tmp2.getZ(), detinv ) );\n    return Transform3(\n        inv0,\n        inv1,\n        inv2,\n        Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) )\n    );\n}\n\ninline const Transform3 orthoInverse( const Transform3 & tfrm )\n{\n    Vector3 inv0, inv1, inv2;\n    inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() );\n    inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() );\n    inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() );\n    return Transform3(\n        inv0,\n        inv1,\n        inv2,\n        Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) )\n    );\n}\n\ninline const Transform3 absPerElem( const Transform3 & tfrm )\n{\n    return Transform3(\n        absPerElem( tfrm.getCol0() ),\n        absPerElem( tfrm.getCol1() ),\n        absPerElem( tfrm.getCol2() ),\n        absPerElem( tfrm.getCol3() )\n    );\n}\n\ninline const Vector3 Transform3::operator *( const Vector3 & vec ) const\n{\n    return Vector3(\n        spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ),\n        spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) )\n    );\n}\n\ninline const Point3 Transform3::operator *( const Point3 & pnt ) const\n{\n    return Point3(\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getX(), pnt.getX() ), spu_mul( mCol1.getX(), pnt.getY() ) ), spu_mul( mCol2.getX(), pnt.getZ() ) ), mCol3.getX() ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getY(), pnt.getX() ), spu_mul( mCol1.getY(), pnt.getY() ) ), spu_mul( mCol2.getY(), pnt.getZ() ) ), mCol3.getY() ),\n        spu_add( spu_add( spu_add( spu_mul( mCol0.getZ(), pnt.getX() ), spu_mul( mCol1.getZ(), pnt.getY() ) ), spu_mul( mCol2.getZ(), pnt.getZ() ) ), mCol3.getZ() )\n    );\n}\n\ninline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const\n{\n    return Transform3(\n        ( *this * tfrm.mCol0 ),\n        ( *this * tfrm.mCol1 ),\n        ( *this * tfrm.mCol2 ),\n        Vector3( ( *this * Point3( tfrm.mCol3 ) ) )\n    );\n}\n\ninline Transform3 & Transform3::operator *=( const Transform3 & tfrm )\n{\n    *this = *this * tfrm;\n    return *this;\n}\n\ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 )\n{\n    return Transform3(\n        mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ),\n        mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ),\n        mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ),\n        mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() )\n    );\n}\n\ninline const Transform3 Transform3::identity( )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        Vector3( spu_splats(0.0f) )\n    );\n}\n\ninline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm )\n{\n    mCol0 = tfrm.getCol0();\n    mCol1 = tfrm.getCol1();\n    mCol2 = tfrm.getCol2();\n    return *this;\n}\n\ninline const Matrix3 Transform3::getUpper3x3( ) const\n{\n    return Matrix3( mCol0, mCol1, mCol2 );\n}\n\ninline Transform3 & Transform3::setTranslation( const Vector3 & translateVec )\n{\n    mCol3 = translateVec;\n    return *this;\n}\n\ninline const Vector3 Transform3::getTranslation( ) const\n{\n    return mCol3;\n}\n\ninline const Transform3 Transform3::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3( spu_splats(0.0f), c, s ),\n        Vector3( spu_splats(0.0f), negatef4( s ), c ),\n        Vector3( spu_splats(0.0f) )\n    );\n}\n\ninline const Transform3 Transform3::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Transform3(\n        Vector3( c, spu_splats(0.0f), negatef4( s ) ),\n        Vector3::yAxis( ),\n        Vector3( s, spu_splats(0.0f), c ),\n        Vector3( spu_splats(0.0f) )\n    );\n}\n\ninline const Transform3 Transform3::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c;\n    sincosf4( radians, &s, &c );\n    return Transform3(\n        Vector3( c, s, spu_splats(0.0f) ),\n        Vector3( negatef4( s ), c, spu_splats(0.0f) ),\n        Vector3::zAxis( ),\n        Vector3( spu_splats(0.0f) )\n    );\n}\n\ninline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ )\n{\n    vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1;\n    sincosf4( radiansXYZ.getX(), &sX, &cX );\n    sincosf4( radiansXYZ.getY(), &sY, &cY );\n    sincosf4( radiansXYZ.getZ(), &sZ, &cZ );\n    tmp0 = spu_mul( cZ, sY );\n    tmp1 = spu_mul( sZ, sY );\n    return Transform3(\n        Vector3( spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) ),\n        Vector3( spu_sub( spu_mul( tmp0, sX ), spu_mul( sZ, cX ) ), spu_add( spu_mul( tmp1, sX ), spu_mul( cZ, cX ) ), spu_mul( cY, sX ) ),\n        Vector3( spu_add( spu_mul( tmp0, cX ), spu_mul( sZ, sX ) ), spu_sub( spu_mul( tmp1, cX ), spu_mul( cZ, sX ) ), spu_mul( cY, cX ) ),\n        Vector3( spu_splats(0.0f) )\n    );\n}\n\ninline const Transform3 Transform3::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( spu_splats(0.0f) ) );\n}\n\ninline const Transform3 Transform3::rotation( const Quat & unitQuat )\n{\n    return Transform3( Matrix3( unitQuat ), Vector3( spu_splats(0.0f) ) );\n}\n\ninline const Transform3 Transform3::scale( const Vector3 & scaleVec )\n{\n    return Transform3(\n        Vector3( scaleVec.getX(), spu_splats(0.0f), spu_splats(0.0f) ),\n        Vector3( spu_splats(0.0f), scaleVec.getY(), spu_splats(0.0f) ),\n        Vector3( spu_splats(0.0f), spu_splats(0.0f), scaleVec.getZ() ),\n        Vector3( spu_splats(0.0f) )\n    );\n}\n\ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec )\n{\n    return Transform3(\n        ( tfrm.getCol0() * scaleVec.getX( ) ),\n        ( tfrm.getCol1() * scaleVec.getY( ) ),\n        ( tfrm.getCol2() * scaleVec.getZ( ) ),\n        tfrm.getCol3()\n    );\n}\n\ninline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm )\n{\n    return Transform3(\n        mulPerElem( tfrm.getCol0(), scaleVec ),\n        mulPerElem( tfrm.getCol1(), scaleVec ),\n        mulPerElem( tfrm.getCol2(), scaleVec ),\n        mulPerElem( tfrm.getCol3(), scaleVec )\n    );\n}\n\ninline const Transform3 Transform3::translation( const Vector3 & translateVec )\n{\n    return Transform3(\n        Vector3::xAxis( ),\n        Vector3::yAxis( ),\n        Vector3::zAxis( ),\n        translateVec\n    );\n}\n\ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 )\n{\n    return Transform3(\n        select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ),\n        select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ),\n        select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ),\n        select( tfrm0.getCol3(), tfrm1.getCol3(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Transform3 & tfrm )\n{\n    Aos::Transform3 mat0, mat1, mat2, mat3;\n    tfrm.get4Aos( mat0, mat1, mat2, mat3 );\n    printf(\"slot 0:\\n\");\n    print( mat0 );\n    printf(\"slot 1:\\n\");\n    print( mat1 );\n    printf(\"slot 2:\\n\");\n    print( mat2 );\n    printf(\"slot 3:\\n\");\n    print( mat3 );\n}\n\ninline void print( const Transform3 & tfrm, const char * name )\n{\n    printf(\"%s:\\n\", name);\n    print( tfrm );\n}\n\n#endif\n\ninline Quat::Quat( const Matrix3 & tfrm )\n{\n    vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw;\n    vec_uint4 negTrace, ZgtX, ZgtY, YgtX;\n    vec_uint4 largestXorY, largestYorZ, largestZorX;\n\n    xx = tfrm.getCol0().getX();\n    yx = tfrm.getCol0().getY();\n    zx = tfrm.getCol0().getZ();\n    xy = tfrm.getCol1().getX();\n    yy = tfrm.getCol1().getY();\n    zy = tfrm.getCol1().getZ();\n    xz = tfrm.getCol2().getX();\n    yz = tfrm.getCol2().getY();\n    zz = tfrm.getCol2().getZ();\n\n    trace = spu_add( spu_add( xx, yy ), zz );\n\n    negTrace = spu_cmpgt( spu_splats(0.0f), trace );\n    ZgtX = spu_cmpgt( zz, xx );\n    ZgtY = spu_cmpgt( zz, yy );\n    YgtX = spu_cmpgt( yy, xx );\n    largestXorY = spu_and( negTrace, spu_nand( ZgtX, ZgtY ) );\n    largestYorZ = spu_and( negTrace, spu_or( YgtX, ZgtX ) );\n    largestZorX = spu_and( negTrace, spu_orc( ZgtY, YgtX ) );\n    \n    zz = spu_sel( zz, negatef4(zz), largestXorY );\n    xy = spu_sel( xy, negatef4(xy), largestXorY );\n    xx = spu_sel( xx, negatef4(xx), largestYorZ );\n    yz = spu_sel( yz, negatef4(yz), largestYorZ );\n    yy = spu_sel( yy, negatef4(yy), largestZorX );\n    zx = spu_sel( zx, negatef4(zx), largestZorX );\n\n    radicand = spu_add( spu_add( spu_add( xx, yy ), zz ), spu_splats(1.0f) );\n    scale = spu_mul( spu_splats(0.5f), rsqrtf4( radicand ) );\n\n    tmpx = spu_mul( spu_sub( zy, yz ), scale );\n    tmpy = spu_mul( spu_sub( xz, zx ), scale );\n    tmpz = spu_mul( spu_sub( yx, xy ), scale );\n    tmpw = spu_mul( radicand, scale );\n    qx = tmpx;\n    qy = tmpy;\n    qz = tmpz;\n    qw = tmpw;\n\n    qx = spu_sel( qx, tmpw, largestXorY );\n    qy = spu_sel( qy, tmpz, largestXorY );\n    qz = spu_sel( qz, tmpy, largestXorY );\n    qw = spu_sel( qw, tmpx, largestXorY );\n    tmpx = qx;\n    tmpz = qz;\n    qx = spu_sel( qx, qy, largestYorZ );\n    qy = spu_sel( qy, tmpx, largestYorZ );\n    qz = spu_sel( qz, qw, largestYorZ );\n    qw = spu_sel( qw, tmpz, largestYorZ );\n\n    mX = qx;\n    mY = qy;\n    mZ = qz;\n    mW = qw;\n}\n\ninline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 )\n{\n    return Matrix3(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) )\n    );\n}\n\ninline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 )\n{\n    return Matrix4(\n        ( tfrm0 * tfrm1.getX( ) ),\n        ( tfrm0 * tfrm1.getY( ) ),\n        ( tfrm0 * tfrm1.getZ( ) ),\n        ( tfrm0 * tfrm1.getW( ) )\n    );\n}\n\ninline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat )\n{\n    return Vector3(\n        spu_add( spu_add( spu_mul( vec.getX(), mat.getCol0().getX() ), spu_mul( vec.getY(), mat.getCol0().getY() ) ), spu_mul( vec.getZ(), mat.getCol0().getZ() ) ),\n        spu_add( spu_add( spu_mul( vec.getX(), mat.getCol1().getX() ), spu_mul( vec.getY(), mat.getCol1().getY() ) ), spu_mul( vec.getZ(), mat.getCol1().getZ() ) ),\n        spu_add( spu_add( spu_mul( vec.getX(), mat.getCol2().getX() ), spu_mul( vec.getY(), mat.getCol2().getY() ) ), spu_mul( vec.getZ(), mat.getCol2().getZ() ) )\n    );\n}\n\ninline const Matrix3 crossMatrix( const Vector3 & vec )\n{\n    return Matrix3(\n        Vector3( spu_splats(0.0f), vec.getZ(), negatef4( vec.getY() ) ),\n        Vector3( negatef4( vec.getZ() ), spu_splats(0.0f), vec.getX() ),\n        Vector3( vec.getY(), negatef4( vec.getX() ), spu_splats(0.0f) )\n    );\n}\n\ninline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat )\n{\n    return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) );\n}\n\n} // namespace Soa\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/quat_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_AOS_CPP_H\n#define _VECTORMATH_QUAT_AOS_CPP_H\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\ninline Quat::Quat( float _x, float _y, float _z, float _w )\n{\n    mVec128 = (vec_float4){ _x, _y, _z, _w };\n}\n\ninline Quat::Quat( Vector3 xyz, float _w )\n{\n    mVec128 = spu_shuffle( xyz.get128(), spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA );\n}\n\ninline Quat::Quat( Vector4 vec )\n{\n    mVec128 = vec.get128();\n}\n\ninline Quat::Quat( float scalar )\n{\n    mVec128 = spu_splats( scalar );\n}\n\ninline Quat::Quat( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Quat Quat::identity( )\n{\n    return Quat( _VECTORMATH_UNIT_0001 );\n}\n\ninline const Quat lerp( float t, Quat quat0, Quat quat1 )\n{\n    return ( quat0 + ( ( quat1 - quat0 ) * t ) );\n}\n\ninline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 )\n{\n    Quat start;\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle );\n    cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start = Quat( spu_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = spu_splats(t);\n    oneMinusT = spu_sub( spu_splats(1.0f), tttt );\n    angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) );\n    angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) );\n    angles = spu_mul( angles, angle );\n    sines = sinf4( angles );\n    scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) );\n    scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask );\n    scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask );\n    return Quat( spu_madd( start.get128(), scale0, spu_mul( unitQuat1.get128(), scale1 ) ) );\n}\n\ninline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 )\n{\n    Quat tmp0, tmp1;\n    tmp0 = slerp( t, unitQuat0, unitQuat3 );\n    tmp1 = slerp( t, unitQuat1, unitQuat2 );\n    return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 );\n}\n\ninline vec_float4 Quat::get128( ) const\n{\n    return mVec128;\n}\n\ninline Quat & Quat::operator =( Quat quat )\n{\n    mVec128 = quat.mVec128;\n    return *this;\n}\n\ninline Quat & Quat::setXYZ( Vector3 vec )\n{\n    mVec128 = spu_sel( vec.get128(), mVec128, (vec_uint4)spu_maskb(0x000f) );\n    return *this;\n}\n\ninline const Vector3 Quat::getXYZ( ) const\n{\n    return Vector3( mVec128 );\n}\n\ninline Quat & Quat::setX( float _x )\n{\n    mVec128 = spu_insert( _x, mVec128, 0 );\n    return *this;\n}\n\ninline float Quat::getX( ) const\n{\n    return spu_extract( mVec128, 0 );\n}\n\ninline Quat & Quat::setY( float _y )\n{\n    mVec128 = spu_insert( _y, mVec128, 1 );\n    return *this;\n}\n\ninline float Quat::getY( ) const\n{\n    return spu_extract( mVec128, 1 );\n}\n\ninline Quat & Quat::setZ( float _z )\n{\n    mVec128 = spu_insert( _z, mVec128, 2 );\n    return *this;\n}\n\ninline float Quat::getZ( ) const\n{\n    return spu_extract( mVec128, 2 );\n}\n\ninline Quat & Quat::setW( float _w )\n{\n    mVec128 = spu_insert( _w, mVec128, 3 );\n    return *this;\n}\n\ninline float Quat::getW( ) const\n{\n    return spu_extract( mVec128, 3 );\n}\n\ninline Quat & Quat::setElem( int idx, float value )\n{\n    mVec128 = spu_insert( value, mVec128, idx );\n    return *this;\n}\n\ninline float Quat::getElem( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline VecIdx Quat::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline float Quat::operator []( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline const Quat Quat::operator +( Quat quat ) const\n{\n    return Quat( spu_add( mVec128, quat.mVec128 ) );\n}\n\ninline const Quat Quat::operator -( Quat quat ) const\n{\n    return Quat( spu_sub( mVec128, quat.mVec128 ) );\n}\n\ninline const Quat Quat::operator *( float scalar ) const\n{\n    return Quat( spu_mul( mVec128, spu_splats(scalar) ) );\n}\n\ninline Quat & Quat::operator +=( Quat quat )\n{\n    *this = *this + quat;\n    return *this;\n}\n\ninline Quat & Quat::operator -=( Quat quat )\n{\n    *this = *this - quat;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator /( float scalar ) const\n{\n    return Quat( divf4( mVec128, spu_splats(scalar) ) );\n}\n\ninline Quat & Quat::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator -( ) const\n{\n    return Quat( negatef4( mVec128 ) );\n}\n\ninline const Quat operator *( float scalar, Quat quat )\n{\n    return quat * scalar;\n}\n\ninline float dot( Quat quat0, Quat quat1 )\n{\n    return spu_extract( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 );\n}\n\ninline float norm( Quat quat )\n{\n    return spu_extract( _vmathVfDot4( quat.get128(), quat.get128() ), 0 );\n}\n\ninline float length( Quat quat )\n{\n    return sqrtf( norm( quat ) );\n}\n\ninline const Quat normalize( Quat quat )\n{\n    vec_float4 dot = _vmathVfDot4( quat.get128(), quat.get128() );\n    return Quat( spu_mul( quat.get128(), rsqrtf4( dot ) ) );\n}\n\ninline const Quat Quat::rotation( Vector3 unitVec0, Vector3 unitVec1 )\n{\n    Vector3 crossVec;\n    vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res;\n    cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, (vec_uchar16)spu_splats(0x00010203) );\n    cosAngleX2Plus2 = spu_madd( cosAngle, spu_splats(2.0f), spu_splats(2.0f) );\n    recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 );\n    cosHalfAngleX2 = spu_mul( recipCosHalfAngleX2, cosAngleX2Plus2 );\n    crossVec = cross( unitVec0, unitVec1 );\n    res = spu_mul( crossVec.get128(), recipCosHalfAngleX2 );\n    res = spu_sel( res, spu_mul( cosHalfAngleX2, spu_splats(0.5f) ), (vec_uint4)spu_maskb(0x000f) );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotation( float radians, Vector3 unitVec )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_mul( unitVec.get128(), s ), c, (vec_uint4)spu_maskb(0x000f) );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationX( float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0xf000) );\n    res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationY( float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x0f00) );\n    res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) );\n    return Quat( res );\n}\n\ninline const Quat Quat::rotationZ( float radians )\n{\n    vec_float4 s, c, angle, res;\n    angle = spu_mul( spu_splats(radians), spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x00f0) );\n    res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) );\n    return Quat( res );\n}\n\ninline const Quat Quat::operator *( Quat quat ) const\n{\n    vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;\n    vec_float4 product, l_wxyz, r_wxyz, xy, qw;\n    ldata = mVec128;\n    rdata = quat.mVec128;\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    tmp0 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_YZXW );\n    tmp1 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_ZXYW );\n    tmp2 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_YZXW );\n    qv = spu_mul( spu_shuffle( ldata, ldata, shuffle_wwww ), rdata );\n    qv = spu_madd( spu_shuffle( rdata, rdata, shuffle_wwww ), ldata, qv );\n    qv = spu_madd( tmp0, tmp1, qv );\n    qv = spu_nmsub( tmp2, tmp3, qv );\n    product = spu_mul( ldata, rdata );\n    l_wxyz = spu_rlqwbyte( ldata, 12 );\n    r_wxyz = spu_rlqwbyte( rdata, 12 );\n    qw = spu_nmsub( l_wxyz, r_wxyz, product );\n    xy = spu_madd( l_wxyz, r_wxyz, product );\n    qw = spu_sub( qw, spu_rlqwbyte( xy, 8 ) );\n    return Quat( spu_sel( qv, qw, (vec_uint4)spu_maskb( 0x000f ) ) );\n}\n\ninline Quat & Quat::operator *=( Quat quat )\n{\n    *this = *this * quat;\n    return *this;\n}\n\ninline const Vector3 rotate( Quat quat, Vector3 vec )\n{\n    vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res;\n    qdata = quat.get128();\n    vdata = vec.get128();\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    tmp0 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_YZXW );\n    tmp1 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_ZXYW );\n    tmp2 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_YZXW );\n    wwww = spu_shuffle( qdata, qdata, shuffle_wwww );\n    qv = spu_mul( wwww, vdata );\n    qv = spu_madd( tmp0, tmp1, qv );\n    qv = spu_nmsub( tmp2, tmp3, qv );\n    product = spu_mul( qdata, vdata );\n    qw = spu_madd( spu_rlqwbyte( qdata, 4 ), spu_rlqwbyte( vdata, 4 ), product );\n    qw = spu_add( spu_rlqwbyte( product, 8 ), qw );\n    tmp1 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_YZXW );\n    res = spu_mul( spu_shuffle( qw, qw, shuffle_xxxx ), qdata );\n    res = spu_madd( wwww, qv, res );\n    res = spu_madd( tmp0, tmp1, res );\n    res = spu_nmsub( tmp2, tmp3, res );\n    return Vector3( res );\n}\n\ninline const Quat conj( Quat quat )\n{\n    return Quat( spu_xor( quat.get128(), ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) ) );\n}\n\ninline const Quat select( Quat quat0, Quat quat1, bool select1 )\n{\n    return Quat( spu_sel( quat0.get128(), quat1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Quat quat )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat.get128();\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\ninline void print( Quat quat, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = quat.get128();\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/quat_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_QUAT_SOA_CPP_H\n#define _VECTORMATH_QUAT_SOA_CPP_H\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Soa {\n\ninline Quat::Quat( const Quat & quat )\n{\n    mX = quat.mX;\n    mY = quat.mY;\n    mZ = quat.mZ;\n    mW = quat.mW;\n}\n\ninline Quat::Quat( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n    mW = _w;\n}\n\ninline Quat::Quat( const Vector3 & xyz, vec_float4 _w )\n{\n    this->setXYZ( xyz );\n    this->setW( _w );\n}\n\ninline Quat::Quat( const Vector4 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    mW = vec.getW();\n}\n\ninline Quat::Quat( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n    mW = scalar;\n}\n\ninline Quat::Quat( Aos::Quat quat )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    vec_float4 vec128 = quat.get128();\n    mX = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    mY = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    mZ = spu_shuffle( vec128, vec128, shuffle_zzzz );\n    mW = spu_shuffle( vec128, vec128, shuffle_wwww );\n}\n\ninline Quat::Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( quat0.get128(), quat2.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( quat1.get128(), quat3.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( quat0.get128(), quat2.get128(), _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( quat1.get128(), quat3.get128(), _VECTORMATH_SHUF_ZCWD );\n    mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n    mW = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD );\n}\n\ninline const Quat Quat::identity( )\n{\n    return Quat( spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) );\n}\n\ninline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 )\n{\n    return ( quat0 + ( ( quat1 - quat0 ) * t ) );\n}\n\ninline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 )\n{\n    Quat start;\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = dot( unitQuat0, unitQuat1 );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle );\n    cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask );\n    start.setX( spu_sel( unitQuat0.getX(), negatef4( unitQuat0.getX() ), selectMask ) );\n    start.setY( spu_sel( unitQuat0.getY(), negatef4( unitQuat0.getY() ), selectMask ) );\n    start.setZ( spu_sel( unitQuat0.getZ(), negatef4( unitQuat0.getZ() ), selectMask ) );\n    start.setW( spu_sel( unitQuat0.getW(), negatef4( unitQuat0.getW() ), selectMask ) );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = recipf4( sinf4( angle ) );\n    scale0 = spu_sel( spu_sub( spu_splats(1.0f), t ), spu_mul( sinf4( spu_mul( spu_sub( spu_splats(1.0f), t ), angle ) ), recipSinAngle ), selectMask );\n    scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask );\n    return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) );\n}\n\ninline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 )\n{\n    Quat tmp0, tmp1;\n    tmp0 = slerp( t, unitQuat0, unitQuat3 );\n    tmp1 = slerp( t, unitQuat1, unitQuat2 );\n    return slerp( spu_mul( spu_mul( spu_splats(2.0f), t ), spu_sub( spu_splats(1.0f), t ) ), tmp0, tmp1 );\n}\n\ninline void Quat::get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_ZCWD );\n    result0 = Aos::Quat( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) );\n    result1 = Aos::Quat( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) );\n    result2 = Aos::Quat( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) );\n    result3 = Aos::Quat( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) );\n}\n\ninline Quat & Quat::operator =( const Quat & quat )\n{\n    mX = quat.mX;\n    mY = quat.mY;\n    mZ = quat.mZ;\n    mW = quat.mW;\n    return *this;\n}\n\ninline Quat & Quat::setXYZ( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    return *this;\n}\n\ninline const Vector3 Quat::getXYZ( ) const\n{\n    return Vector3( mX, mY, mZ );\n}\n\ninline Quat & Quat::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Quat::getX( ) const\n{\n    return mX;\n}\n\ninline Quat & Quat::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Quat::getY( ) const\n{\n    return mY;\n}\n\ninline Quat & Quat::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Quat::getZ( ) const\n{\n    return mZ;\n}\n\ninline Quat & Quat::setW( vec_float4 _w )\n{\n    mW = _w;\n    return *this;\n}\n\ninline vec_float4 Quat::getW( ) const\n{\n    return mW;\n}\n\ninline Quat & Quat::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Quat::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Quat::vec_float4_t & Quat::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Quat::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Quat Quat::operator +( const Quat & quat ) const\n{\n    return Quat(\n        spu_add( mX, quat.mX ),\n        spu_add( mY, quat.mY ),\n        spu_add( mZ, quat.mZ ),\n        spu_add( mW, quat.mW )\n    );\n}\n\ninline const Quat Quat::operator -( const Quat & quat ) const\n{\n    return Quat(\n        spu_sub( mX, quat.mX ),\n        spu_sub( mY, quat.mY ),\n        spu_sub( mZ, quat.mZ ),\n        spu_sub( mW, quat.mW )\n    );\n}\n\ninline const Quat Quat::operator *( vec_float4 scalar ) const\n{\n    return Quat(\n        spu_mul( mX, scalar ),\n        spu_mul( mY, scalar ),\n        spu_mul( mZ, scalar ),\n        spu_mul( mW, scalar )\n    );\n}\n\ninline Quat & Quat::operator +=( const Quat & quat )\n{\n    *this = *this + quat;\n    return *this;\n}\n\ninline Quat & Quat::operator -=( const Quat & quat )\n{\n    *this = *this - quat;\n    return *this;\n}\n\ninline Quat & Quat::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator /( vec_float4 scalar ) const\n{\n    return Quat(\n        divf4( mX, scalar ),\n        divf4( mY, scalar ),\n        divf4( mZ, scalar ),\n        divf4( mW, scalar )\n    );\n}\n\ninline Quat & Quat::operator /=( vec_float4 scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Quat Quat::operator -( ) const\n{\n    return Quat(\n        negatef4( mX ),\n        negatef4( mY ),\n        negatef4( mZ ),\n        negatef4( mW )\n    );\n}\n\ninline const Quat operator *( vec_float4 scalar, const Quat & quat )\n{\n    return quat * scalar;\n}\n\ninline vec_float4 dot( const Quat & quat0, const Quat & quat1 )\n{\n    vec_float4 result;\n    result = spu_mul( quat0.getX(), quat1.getX() );\n    result = spu_add( result, spu_mul( quat0.getY(), quat1.getY() ) );\n    result = spu_add( result, spu_mul( quat0.getZ(), quat1.getZ() ) );\n    result = spu_add( result, spu_mul( quat0.getW(), quat1.getW() ) );\n    return result;\n}\n\ninline vec_float4 norm( const Quat & quat )\n{\n    vec_float4 result;\n    result = spu_mul( quat.getX(), quat.getX() );\n    result = spu_add( result, spu_mul( quat.getY(), quat.getY() ) );\n    result = spu_add( result, spu_mul( quat.getZ(), quat.getZ() ) );\n    result = spu_add( result, spu_mul( quat.getW(), quat.getW() ) );\n    return result;\n}\n\ninline vec_float4 length( const Quat & quat )\n{\n    return sqrtf4( norm( quat ) );\n}\n\ninline const Quat normalize( const Quat & quat )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = norm( quat );\n    lenInv = rsqrtf4( lenSqr );\n    return Quat(\n        spu_mul( quat.getX(), lenInv ),\n        spu_mul( quat.getY(), lenInv ),\n        spu_mul( quat.getZ(), lenInv ),\n        spu_mul( quat.getW(), lenInv )\n    );\n}\n\ninline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 )\n{\n    vec_float4 cosHalfAngleX2, recipCosHalfAngleX2;\n    cosHalfAngleX2 = sqrtf4( spu_mul( spu_splats(2.0f), spu_add( spu_splats(1.0f), dot( unitVec0, unitVec1 ) ) ) );\n    recipCosHalfAngleX2 = recipf4( cosHalfAngleX2 );\n    return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), spu_mul( cosHalfAngleX2, spu_splats(0.5f) ) );\n}\n\ninline const Quat Quat::rotation( vec_float4 radians, const Vector3 & unitVec )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    return Quat( ( unitVec * s ), c );\n}\n\ninline const Quat Quat::rotationX( vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    return Quat( s, spu_splats(0.0f), spu_splats(0.0f), c );\n}\n\ninline const Quat Quat::rotationY( vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    return Quat( spu_splats(0.0f), s, spu_splats(0.0f), c );\n}\n\ninline const Quat Quat::rotationZ( vec_float4 radians )\n{\n    vec_float4 s, c, angle;\n    angle = spu_mul( radians, spu_splats(0.5f) );\n    sincosf4( angle, &s, &c );\n    return Quat( spu_splats(0.0f), spu_splats(0.0f), s, c );\n}\n\ninline const Quat Quat::operator *( const Quat & quat ) const\n{\n    return Quat(\n        spu_sub( spu_add( spu_add( spu_mul( mW, quat.mX ), spu_mul( mX, quat.mW ) ), spu_mul( mY, quat.mZ ) ), spu_mul( mZ, quat.mY ) ),\n        spu_sub( spu_add( spu_add( spu_mul( mW, quat.mY ), spu_mul( mY, quat.mW ) ), spu_mul( mZ, quat.mX ) ), spu_mul( mX, quat.mZ ) ),\n        spu_sub( spu_add( spu_add( spu_mul( mW, quat.mZ ), spu_mul( mZ, quat.mW ) ), spu_mul( mX, quat.mY ) ), spu_mul( mY, quat.mX ) ),\n        spu_sub( spu_sub( spu_sub( spu_mul( mW, quat.mW ), spu_mul( mX, quat.mX ) ), spu_mul( mY, quat.mY ) ), spu_mul( mZ, quat.mZ ) )\n    );\n}\n\ninline Quat & Quat::operator *=( const Quat & quat )\n{\n    *this = *this * quat;\n    return *this;\n}\n\ninline const Vector3 rotate( const Quat & quat, const Vector3 & vec )\n{\n    vec_float4 tmpX, tmpY, tmpZ, tmpW;\n    tmpX = spu_sub( spu_add( spu_mul( quat.getW(), vec.getX() ), spu_mul( quat.getY(), vec.getZ() ) ), spu_mul( quat.getZ(), vec.getY() ) );\n    tmpY = spu_sub( spu_add( spu_mul( quat.getW(), vec.getY() ), spu_mul( quat.getZ(), vec.getX() ) ), spu_mul( quat.getX(), vec.getZ() ) );\n    tmpZ = spu_sub( spu_add( spu_mul( quat.getW(), vec.getZ() ), spu_mul( quat.getX(), vec.getY() ) ), spu_mul( quat.getY(), vec.getX() ) );\n    tmpW = spu_add( spu_add( spu_mul( quat.getX(), vec.getX() ), spu_mul( quat.getY(), vec.getY() ) ), spu_mul( quat.getZ(), vec.getZ() ) );\n    return Vector3(\n        spu_add( spu_sub( spu_add( spu_mul( tmpW, quat.getX() ), spu_mul( tmpX, quat.getW() ) ), spu_mul( tmpY, quat.getZ() ) ), spu_mul( tmpZ, quat.getY() ) ),\n        spu_add( spu_sub( spu_add( spu_mul( tmpW, quat.getY() ), spu_mul( tmpY, quat.getW() ) ), spu_mul( tmpZ, quat.getX() ) ), spu_mul( tmpX, quat.getZ() ) ),\n        spu_add( spu_sub( spu_add( spu_mul( tmpW, quat.getZ() ), spu_mul( tmpZ, quat.getW() ) ), spu_mul( tmpX, quat.getY() ) ), spu_mul( tmpY, quat.getX() ) )\n    );\n}\n\ninline const Quat conj( const Quat & quat )\n{\n    return Quat( negatef4( quat.getX() ), negatef4( quat.getY() ), negatef4( quat.getZ() ), quat.getW() );\n}\n\ninline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 )\n{\n    return Quat(\n        spu_sel( quat0.getX(), quat1.getX(), select1 ),\n        spu_sel( quat0.getY(), quat1.getY(), select1 ),\n        spu_sel( quat0.getZ(), quat1.getZ(), select1 ),\n        spu_sel( quat0.getW(), quat1.getW(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Quat & quat )\n{\n    Aos::Quat vec0, vec1, vec2, vec3;\n    quat.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Quat & quat, const char * name )\n{\n    Aos::Quat vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    quat.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\n} // namespace Soa\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/vec_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_AOS_CPP_H\n#define _VECTORMATH_VEC_AOS_CPP_H\n//-----------------------------------------------------------------------------\n// Constants\n// for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_SHUF_X 0x00010203\n#define _VECTORMATH_SHUF_Y 0x04050607\n#define _VECTORMATH_SHUF_Z 0x08090a0b\n#define _VECTORMATH_SHUF_W 0x0c0d0e0f\n#define _VECTORMATH_SHUF_A 0x10111213\n#define _VECTORMATH_SHUF_B 0x14151617\n#define _VECTORMATH_SHUF_C 0x18191a1b\n#define _VECTORMATH_SHUF_D 0x1c1d1e1f\n#define _VECTORMATH_SHUF_0 0x80808080\n#define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A }\n#define _VECTORMATH_SHUF_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_W }\n#define _VECTORMATH_SHUF_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W }\n#define _VECTORMATH_SHUF_WABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C }\n#define _VECTORMATH_SHUF_ZWAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }\n#define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A }\n#define _VECTORMATH_SHUF_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }\n#define _VECTORMATH_SHUF_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C }\n#define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }\n#define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }\n#define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\nstatic inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0, vec1 );\n    result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );\n    return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0, vec1 );\n    result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );\n    return spu_add( spu_rlqwbyte( result, 8 ), result );\n}\n\nstatic inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3, result;\n    tmp0 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_YZXW );\n    tmp1 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_ZXYW );\n    tmp2 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_ZXYW );\n    tmp3 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_YZXW );\n    result = spu_mul( tmp0, tmp1 );\n    result = spu_nmsub( tmp2, tmp3, result );\n    return result;\n}\n\nstatic inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v)\n{\n    vec_int4 bexp;\n    vec_uint4 mant, sign, hfloat;\n    vec_uint4 notZero, isInf;\n    const vec_uint4 hfloatInf = spu_splats(0x00007c00u);\n    const vec_uint4 mergeMant = spu_splats(0x000003ffu);\n    const vec_uint4 mergeSign = spu_splats(0x00008000u);\n\n    sign = spu_rlmask((vec_uint4)v, -16);\n    mant = spu_rlmask((vec_uint4)v, -13);\n    bexp = spu_and(spu_rlmask((vec_int4)v, -23), 0xff);\n\n    notZero = spu_cmpgt(bexp, 112);\n    isInf = spu_cmpgt(bexp, 142);\n\n    bexp = spu_add(bexp, -112);\n    bexp = spu_sl(bexp, 10);\n\n    hfloat = spu_sel((vec_uint4)bexp, mant, mergeMant);\n    hfloat = spu_sel(spu_splats(0u), hfloat, notZero);\n    hfloat = spu_sel(hfloat, hfloatInf, isInf);\n    hfloat = spu_sel(hfloat, sign, mergeSign);\n\n    return hfloat;\n}\n\nstatic inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v)\n{\n    vec_uint4 hfloat_u, hfloat_v;\n    const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31};\n    hfloat_u = _vmathVfToHalfFloatsUnpacked(u);\n    hfloat_v = _vmathVfToHalfFloatsUnpacked(v);\n    return (vec_ushort8)spu_shuffle(hfloat_u, hfloat_v, pack);\n}\n\n#endif\n\nnamespace Vectormath {\nnamespace Aos {\n\ninline VecIdx::operator float() const\n{\n    return spu_extract( ref, i );\n}\n\ninline float VecIdx::operator =( float scalar )\n{\n    ref = spu_insert( scalar, ref, i );\n    return scalar;\n}\n\ninline float VecIdx::operator =( const VecIdx& scalar )\n{\n    return *this = float(scalar);\n}\n\ninline float VecIdx::operator *=( float scalar )\n{\n    float tmp = spu_extract( ref, i ) * scalar;\n    ref = spu_insert( tmp, ref, i );\n    return tmp;\n}\n\ninline float VecIdx::operator /=( float scalar )\n{\n    float tmp = spu_extract( ref, i ) / scalar;\n    ref = spu_insert( tmp, ref, i );\n    return tmp;\n}\n\ninline float VecIdx::operator +=( float scalar )\n{\n    float tmp = spu_extract( ref, i ) + scalar;\n    ref = spu_insert( tmp, ref, i );\n    return tmp;\n}\n\ninline float VecIdx::operator -=( float scalar )\n{\n    float tmp = spu_extract( ref, i ) - scalar;\n    ref = spu_insert( tmp, ref, i );\n    return tmp;\n}\n\ninline Vector3::Vector3( float _x, float _y, float _z )\n{\n    mVec128 = (vec_float4){ _x, _y, _z, 0.0f  };\n}\n\ninline Vector3::Vector3( Point3 pnt )\n{\n    mVec128 = pnt.get128();\n}\n\ninline Vector3::Vector3( float scalar )\n{\n    mVec128 = spu_splats( scalar );\n}\n\ninline Vector3::Vector3( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Vector3 Vector3::xAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_1000 );\n}\n\ninline const Vector3 Vector3::yAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_0100 );\n}\n\ninline const Vector3 Vector3::zAxis( )\n{\n    return Vector3( _VECTORMATH_UNIT_0010 );\n}\n\ninline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = spu_splats(t);\n    oneMinusT = spu_sub( spu_splats(1.0f), tttt );\n    angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) );\n    angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) );\n    angles = spu_mul( angles, angle );\n    sines = sinf4( angles );\n    scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) );\n    scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask );\n    scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask );\n    return Vector3( spu_madd( unitVec0.get128(), scale0, spu_mul( unitVec1.get128(), scale1 ) ) );\n}\n\ninline vec_float4 Vector3::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeXYZ( Vector3 vec, vec_float4 * quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = (vec_uint4)spu_maskb(0x000f);\n    dstVec = spu_sel(vec.get128(), dstVec, mask);\n    *quad = dstVec;\n}\n\ninline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC );\n    xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB );\n    xyz3 = spu_rlqwbyte( zxyz, 4 );\n    vec0 = Vector3( xyzx );\n    vec1 = Vector3( xyz1 );\n    vec2 = Vector3( xyz2 );\n    vec3 = Vector3( xyz3 );\n}\n\ninline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = spu_shuffle( vec0.get128(), vec1.get128(), _VECTORMATH_SHUF_XYZA );\n    yzxy = spu_shuffle( vec1.get128(), vec2.get128(), _VECTORMATH_SHUF_YZAB );\n    zxyz = spu_shuffle( vec2.get128(), vec3.get128(), _VECTORMATH_SHUF_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( vec0, vec1, vec2, vec3, xyz0 );\n    storeXYZArray( vec4, vec5, vec6, vec7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Vector3 & Vector3::operator =( Vector3 vec )\n{\n    mVec128 = vec.mVec128;\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( float _x )\n{\n    mVec128 = spu_insert( _x, mVec128, 0 );\n    return *this;\n}\n\ninline float Vector3::getX( ) const\n{\n    return spu_extract( mVec128, 0 );\n}\n\ninline Vector3 & Vector3::setY( float _y )\n{\n    mVec128 = spu_insert( _y, mVec128, 1 );\n    return *this;\n}\n\ninline float Vector3::getY( ) const\n{\n    return spu_extract( mVec128, 1 );\n}\n\ninline Vector3 & Vector3::setZ( float _z )\n{\n    mVec128 = spu_insert( _z, mVec128, 2 );\n    return *this;\n}\n\ninline float Vector3::getZ( ) const\n{\n    return spu_extract( mVec128, 2 );\n}\n\ninline Vector3 & Vector3::setElem( int idx, float value )\n{\n    mVec128 = spu_insert( value, mVec128, idx );\n    return *this;\n}\n\ninline float Vector3::getElem( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline VecIdx Vector3::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline float Vector3::operator []( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline const Vector3 Vector3::operator +( Vector3 vec ) const\n{\n    return Vector3( spu_add( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector3 Vector3::operator -( Vector3 vec ) const\n{\n    return Vector3( spu_sub( mVec128, vec.mVec128 ) );\n}\n\ninline const Point3 Vector3::operator +( Point3 pnt ) const\n{\n    return Point3( spu_add( mVec128, pnt.get128() ) );\n}\n\ninline const Vector3 Vector3::operator *( float scalar ) const\n{\n    return Vector3( spu_mul( mVec128, spu_splats(scalar) ) );\n}\n\ninline Vector3 & Vector3::operator +=( Vector3 vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator -=( Vector3 vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator /( float scalar ) const\n{\n    return Vector3( divf4( mVec128, spu_splats(scalar) ) );\n}\n\ninline Vector3 & Vector3::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator -( ) const\n{\n    return Vector3( negatef4( mVec128 ) );\n}\n\ninline const Vector3 operator *( float scalar, Vector3 vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( spu_mul( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( divf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 recipPerElem( Vector3 vec )\n{\n    return Vector3( recipf4( vec.get128() ) );\n}\n\ninline const Vector3 sqrtPerElem( Vector3 vec )\n{\n    return Vector3( sqrtf4( vec.get128() ) );\n}\n\ninline const Vector3 rsqrtPerElem( Vector3 vec )\n{\n    return Vector3( rsqrtf4( vec.get128() ) );\n}\n\ninline const Vector3 absPerElem( Vector3 vec )\n{\n    return Vector3( fabsf4( vec.get128() ) );\n}\n\ninline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( copysignf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( fmaxf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline float maxElem( Vector3 vec )\n{\n    vec_float4 result;\n    result = fmaxf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() );\n    result = fmaxf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\ninline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( fminf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline float minElem( Vector3 vec )\n{\n    vec_float4 result;\n    result = fminf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() );\n    result = fminf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\ninline float sum( Vector3 vec )\n{\n    return\n        spu_extract( vec.get128(), 0 ) +\n        spu_extract( vec.get128(), 1 ) +\n        spu_extract( vec.get128(), 2 );\n}\n\ninline float dot( Vector3 vec0, Vector3 vec1 )\n{\n    return spu_extract( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 );\n}\n\ninline float lengthSqr( Vector3 vec )\n{\n    return spu_extract( _vmathVfDot3( vec.get128(), vec.get128() ), 0 );\n}\n\ninline float length( Vector3 vec )\n{\n    return sqrtf( lengthSqr( vec ) );\n}\n\ninline const Vector3 normalize( Vector3 vec )\n{\n    vec_float4 dot = _vmathVfDot3( vec.get128(), vec.get128() );\n    dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) );\n    return Vector3( spu_mul( vec.get128(), rsqrtf4( dot ) ) );\n}\n\ninline const Vector3 cross( Vector3 vec0, Vector3 vec1 )\n{\n    return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 )\n{\n    return Vector3( spu_sel( vec0.get128(), vec1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Vector3 vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\ninline void print( Vector3 vec, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\ninline Vector4::Vector4( float _x, float _y, float _z, float _w )\n{\n    mVec128 = (vec_float4){ _x, _y, _z, _w };\n}\n\ninline Vector4::Vector4( Vector3 xyz, float _w )\n{\n    mVec128 = spu_shuffle( xyz.get128(), spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA );\n}\n\ninline Vector4::Vector4( Vector3 vec )\n{\n    mVec128 = spu_sel( vec.get128(), spu_splats(0.0f), (vec_uint4)spu_maskb(0x000f) );\n}\n\ninline Vector4::Vector4( Point3 pnt )\n{\n    mVec128 = spu_sel( pnt.get128(), spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) );\n}\n\ninline Vector4::Vector4( Quat quat )\n{\n    mVec128 = quat.get128();\n}\n\ninline Vector4::Vector4( float scalar )\n{\n    mVec128 = spu_splats( scalar );\n}\n\ninline Vector4::Vector4( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Vector4 Vector4::xAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_1000 );\n}\n\ninline const Vector4 Vector4::yAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0100 );\n}\n\ninline const Vector4 Vector4::zAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0010 );\n}\n\ninline const Vector4 Vector4::wAxis( )\n{\n    return Vector4( _VECTORMATH_UNIT_0001 );\n}\n\ninline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 )\n{\n    vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;\n    vec_uint4 selectMask;\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() );\n    cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    tttt = spu_splats(t);\n    oneMinusT = spu_sub( spu_splats(1.0f), tttt );\n    angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) );\n    angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) );\n    angles = spu_mul( angles, angle );\n    sines = sinf4( angles );\n    scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) );\n    scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask );\n    scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask );\n    return Vector4( spu_madd( unitVec0.get128(), scale0, spu_mul( unitVec1.get128(), scale1 ) ) );\n}\n\ninline vec_float4 Vector4::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads )\n{\n    twoQuads[0] = _vmath2VfToHalfFloats(vec0.get128(), vec1.get128());\n    twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128());\n}\n\ninline Vector4 & Vector4::operator =( Vector4 vec )\n{\n    mVec128 = vec.mVec128;\n    return *this;\n}\n\ninline Vector4 & Vector4::setXYZ( Vector3 vec )\n{\n    mVec128 = spu_sel( vec.get128(), mVec128, (vec_uint4)spu_maskb(0x000f) );\n    return *this;\n}\n\ninline const Vector3 Vector4::getXYZ( ) const\n{\n    return Vector3( mVec128 );\n}\n\ninline Vector4 & Vector4::setX( float _x )\n{\n    mVec128 = spu_insert( _x, mVec128, 0 );\n    return *this;\n}\n\ninline float Vector4::getX( ) const\n{\n    return spu_extract( mVec128, 0 );\n}\n\ninline Vector4 & Vector4::setY( float _y )\n{\n    mVec128 = spu_insert( _y, mVec128, 1 );\n    return *this;\n}\n\ninline float Vector4::getY( ) const\n{\n    return spu_extract( mVec128, 1 );\n}\n\ninline Vector4 & Vector4::setZ( float _z )\n{\n    mVec128 = spu_insert( _z, mVec128, 2 );\n    return *this;\n}\n\ninline float Vector4::getZ( ) const\n{\n    return spu_extract( mVec128, 2 );\n}\n\ninline Vector4 & Vector4::setW( float _w )\n{\n    mVec128 = spu_insert( _w, mVec128, 3 );\n    return *this;\n}\n\ninline float Vector4::getW( ) const\n{\n    return spu_extract( mVec128, 3 );\n}\n\ninline Vector4 & Vector4::setElem( int idx, float value )\n{\n    mVec128 = spu_insert( value, mVec128, idx );\n    return *this;\n}\n\ninline float Vector4::getElem( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline VecIdx Vector4::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline float Vector4::operator []( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline const Vector4 Vector4::operator +( Vector4 vec ) const\n{\n    return Vector4( spu_add( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector4 Vector4::operator -( Vector4 vec ) const\n{\n    return Vector4( spu_sub( mVec128, vec.mVec128 ) );\n}\n\ninline const Vector4 Vector4::operator *( float scalar ) const\n{\n    return Vector4( spu_mul( mVec128, spu_splats(scalar) ) );\n}\n\ninline Vector4 & Vector4::operator +=( Vector4 vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator -=( Vector4 vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( float scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator /( float scalar ) const\n{\n    return Vector4( divf4( mVec128, spu_splats(scalar) ) );\n}\n\ninline Vector4 & Vector4::operator /=( float scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator -( ) const\n{\n    return Vector4( negatef4( mVec128 ) );\n}\n\ninline const Vector4 operator *( float scalar, Vector4 vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( spu_mul( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( divf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 recipPerElem( Vector4 vec )\n{\n    return Vector4( recipf4( vec.get128() ) );\n}\n\ninline const Vector4 sqrtPerElem( Vector4 vec )\n{\n    return Vector4( sqrtf4( vec.get128() ) );\n}\n\ninline const Vector4 rsqrtPerElem( Vector4 vec )\n{\n    return Vector4( rsqrtf4( vec.get128() ) );\n}\n\ninline const Vector4 absPerElem( Vector4 vec )\n{\n    return Vector4( fabsf4( vec.get128() ) );\n}\n\ninline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( copysignf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( fmaxf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline float maxElem( Vector4 vec )\n{\n    vec_float4 result;\n    result = fmaxf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() );\n    result = fmaxf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result );\n    result = fmaxf4( spu_promote( spu_extract( vec.get128(), 3 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\ninline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 )\n{\n    return Vector4( fminf4( vec0.get128(), vec1.get128() ) );\n}\n\ninline float minElem( Vector4 vec )\n{\n    vec_float4 result;\n    result = fminf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() );\n    result = fminf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result );\n    result = fminf4( spu_promote( spu_extract( vec.get128(), 3 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\ninline float sum( Vector4 vec )\n{\n    return\n        spu_extract( vec.get128(), 0 ) +\n        spu_extract( vec.get128(), 1 ) +\n        spu_extract( vec.get128(), 2 ) +\n        spu_extract( vec.get128(), 3 );\n}\n\ninline float dot( Vector4 vec0, Vector4 vec1 )\n{\n    return spu_extract( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 );\n}\n\ninline float lengthSqr( Vector4 vec )\n{\n    return spu_extract( _vmathVfDot4( vec.get128(), vec.get128() ), 0 );\n}\n\ninline float length( Vector4 vec )\n{\n    return sqrtf( lengthSqr( vec ) );\n}\n\ninline const Vector4 normalize( Vector4 vec )\n{\n    vec_float4 dot = _vmathVfDot4( vec.get128(), vec.get128() );\n    return Vector4( spu_mul( vec.get128(), rsqrtf4( dot ) ) );\n}\n\ninline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 )\n{\n    return Vector4( spu_sel( vec0.get128(), vec1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Vector4 vec )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"( %f %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\ninline void print( Vector4 vec, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = vec.get128();\n    printf( \"%s: ( %f %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] );\n}\n\n#endif\n\ninline Point3::Point3( float _x, float _y, float _z )\n{\n    mVec128 = (vec_float4){ _x, _y, _z, 0.0f  };\n}\n\ninline Point3::Point3( Vector3 vec )\n{\n    mVec128 = vec.get128();\n}\n\ninline Point3::Point3( float scalar )\n{\n    mVec128 = spu_splats( scalar );\n}\n\ninline Point3::Point3( vec_float4 vf4 )\n{\n    mVec128 = vf4;\n}\n\ninline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 )\n{\n    return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) );\n}\n\ninline vec_float4 Point3::get128( ) const\n{\n    return mVec128;\n}\n\ninline void storeXYZ( Point3 pnt, vec_float4 * quad )\n{\n    vec_float4 dstVec = *quad;\n    vec_uint4 mask = (vec_uint4)spu_maskb(0x000f);\n    dstVec = spu_sel(pnt.get128(), dstVec, mask);\n    *quad = dstVec;\n}\n\ninline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC );\n    xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB );\n    xyz3 = spu_rlqwbyte( zxyz, 4 );\n    pnt0 = Point3( xyzx );\n    pnt1 = Point3( xyz1 );\n    pnt2 = Point3( xyz2 );\n    pnt3 = Point3( xyz3 );\n}\n\ninline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz;\n    xyzx = spu_shuffle( pnt0.get128(), pnt1.get128(), _VECTORMATH_SHUF_XYZA );\n    yzxy = spu_shuffle( pnt1.get128(), pnt2.get128(), _VECTORMATH_SHUF_YZAB );\n    zxyz = spu_shuffle( pnt2.get128(), pnt3.get128(), _VECTORMATH_SHUF_ZABC );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 );\n    storeXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Point3 & Point3::operator =( Point3 pnt )\n{\n    mVec128 = pnt.mVec128;\n    return *this;\n}\n\ninline Point3 & Point3::setX( float _x )\n{\n    mVec128 = spu_insert( _x, mVec128, 0 );\n    return *this;\n}\n\ninline float Point3::getX( ) const\n{\n    return spu_extract( mVec128, 0 );\n}\n\ninline Point3 & Point3::setY( float _y )\n{\n    mVec128 = spu_insert( _y, mVec128, 1 );\n    return *this;\n}\n\ninline float Point3::getY( ) const\n{\n    return spu_extract( mVec128, 1 );\n}\n\ninline Point3 & Point3::setZ( float _z )\n{\n    mVec128 = spu_insert( _z, mVec128, 2 );\n    return *this;\n}\n\ninline float Point3::getZ( ) const\n{\n    return spu_extract( mVec128, 2 );\n}\n\ninline Point3 & Point3::setElem( int idx, float value )\n{\n    mVec128 = spu_insert( value, mVec128, idx );\n    return *this;\n}\n\ninline float Point3::getElem( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline VecIdx Point3::operator []( int idx )\n{\n    return VecIdx( mVec128, idx );\n}\n\ninline float Point3::operator []( int idx ) const\n{\n    return spu_extract( mVec128, idx );\n}\n\ninline const Vector3 Point3::operator -( Point3 pnt ) const\n{\n    return Vector3( spu_sub( mVec128, pnt.mVec128 ) );\n}\n\ninline const Point3 Point3::operator +( Vector3 vec ) const\n{\n    return Point3( spu_add( mVec128, vec.get128() ) );\n}\n\ninline const Point3 Point3::operator -( Vector3 vec ) const\n{\n    return Point3( spu_sub( mVec128, vec.get128() ) );\n}\n\ninline Point3 & Point3::operator +=( Vector3 vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Point3 & Point3::operator -=( Vector3 vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( spu_mul( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( divf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 recipPerElem( Point3 pnt )\n{\n    return Point3( recipf4( pnt.get128() ) );\n}\n\ninline const Point3 sqrtPerElem( Point3 pnt )\n{\n    return Point3( sqrtf4( pnt.get128() ) );\n}\n\ninline const Point3 rsqrtPerElem( Point3 pnt )\n{\n    return Point3( rsqrtf4( pnt.get128() ) );\n}\n\ninline const Point3 absPerElem( Point3 pnt )\n{\n    return Point3( fabsf4( pnt.get128() ) );\n}\n\ninline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( copysignf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( fmaxf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline float maxElem( Point3 pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( spu_promote( spu_extract( pnt.get128(), 1 ), 0 ), pnt.get128() );\n    result = fmaxf4( spu_promote( spu_extract( pnt.get128(), 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\ninline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 )\n{\n    return Point3( fminf4( pnt0.get128(), pnt1.get128() ) );\n}\n\ninline float minElem( Point3 pnt )\n{\n    vec_float4 result;\n    result = fminf4( spu_promote( spu_extract( pnt.get128(), 1 ), 0 ), pnt.get128() );\n    result = fminf4( spu_promote( spu_extract( pnt.get128(), 2 ), 0 ), result );\n    return spu_extract( result, 0 );\n}\n\ninline float sum( Point3 pnt )\n{\n    return\n        spu_extract( pnt.get128(), 0 ) +\n        spu_extract( pnt.get128(), 1 ) +\n        spu_extract( pnt.get128(), 2 );\n}\n\ninline const Point3 scale( Point3 pnt, float scaleVal )\n{\n    return mulPerElem( pnt, Point3( scaleVal ) );\n}\n\ninline const Point3 scale( Point3 pnt, Vector3 scaleVec )\n{\n    return mulPerElem( pnt, Point3( scaleVec ) );\n}\n\ninline float projection( Point3 pnt, Vector3 unitVec )\n{\n    return spu_extract( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 );\n}\n\ninline float distSqrFromOrigin( Point3 pnt )\n{\n    return lengthSqr( Vector3( pnt ) );\n}\n\ninline float distFromOrigin( Point3 pnt )\n{\n    return length( Vector3( pnt ) );\n}\n\ninline float distSqr( Point3 pnt0, Point3 pnt1 )\n{\n    return lengthSqr( ( pnt1 - pnt0 ) );\n}\n\ninline float dist( Point3 pnt0, Point3 pnt1 )\n{\n    return length( ( pnt1 - pnt0 ) );\n}\n\ninline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 )\n{\n    return Point3( spu_sel( pnt0.get128(), pnt1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( Point3 pnt )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt.get128();\n    printf( \"( %f %f %f )\\n\", tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\ninline void print( Point3 pnt, const char * name )\n{\n    union { vec_float4 v; float s[4]; } tmp;\n    tmp.v = pnt.get128();\n    printf( \"%s: ( %f %f %f )\\n\", name, tmp.s[0], tmp.s[1], tmp.s[2] );\n}\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/vec_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VEC_SOA_CPP_H\n#define _VECTORMATH_VEC_SOA_CPP_H\n//-----------------------------------------------------------------------------\n// Constants\n// for shuffles, words are labeled [x,y,z,w] [a,b,c,d]\n\n#define _VECTORMATH_SHUF_X 0x00010203\n#define _VECTORMATH_SHUF_Y 0x04050607\n#define _VECTORMATH_SHUF_Z 0x08090a0b\n#define _VECTORMATH_SHUF_W 0x0c0d0e0f\n#define _VECTORMATH_SHUF_A 0x10111213\n#define _VECTORMATH_SHUF_B 0x14151617\n#define _VECTORMATH_SHUF_C 0x18191a1b\n#define _VECTORMATH_SHUF_D 0x1c1d1e1f\n#define _VECTORMATH_SHUF_0 0x80808080\n#define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_ZDW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 })\n#define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZDXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B })\n#define _VECTORMATH_SHUF_YAWC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C })\n#define _VECTORMATH_SHUF_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SHUF_XYCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D })\n#define _VECTORMATH_SLERP_TOL 0.999f\n\n//-----------------------------------------------------------------------------\n// Definitions\n\n#ifndef _VECTORMATH_INTERNAL_FUNCTIONS\n#define _VECTORMATH_INTERNAL_FUNCTIONS\n\n#endif\n\nnamespace Vectormath {\nnamespace Soa {\n\ninline Vector3::Vector3( const Vector3 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n}\n\ninline Vector3::Vector3( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n}\n\ninline Vector3::Vector3( const Point3 & pnt )\n{\n    mX = pnt.getX();\n    mY = pnt.getY();\n    mZ = pnt.getZ();\n}\n\ninline Vector3::Vector3( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n}\n\ninline Vector3::Vector3( Aos::Vector3 vec )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_float4 vec128 = vec.get128();\n    mX = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    mY = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    mZ = spu_shuffle( vec128, vec128, shuffle_zzzz );\n}\n\ninline Vector3::Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_ZCWD );\n    mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n}\n\ninline const Vector3 Vector3::xAxis( )\n{\n    return Vector3( spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) );\n}\n\ninline const Vector3 Vector3::yAxis( )\n{\n    return Vector3( spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) );\n}\n\ninline const Vector3 Vector3::zAxis( )\n{\n    return Vector3( spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) );\n}\n\ninline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 )\n{\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = recipf4( sinf4( angle ) );\n    scale0 = spu_sel( spu_sub( spu_splats(1.0f), t ), spu_mul( sinf4( spu_mul( spu_sub( spu_splats(1.0f), t ), angle ) ), recipSinAngle ), selectMask );\n    scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask );\n    return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) );\n}\n\ninline void Vector3::get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD );\n    result0 = Aos::Vector3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_XAYB ) );\n    result1 = Aos::Vector3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_ZBW0 ) );\n    result2 = Aos::Vector3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_XCY0 ) );\n    result3 = Aos::Vector3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_ZDW0 ) );\n}\n\ninline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD );\n    zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD );\n    yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD );\n    vec.setX( spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) );\n    vec.setY( spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) );\n    vec.setZ( spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) );\n}\n\ninline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = spu_shuffle( vec.getX(), vec.getY(), _VECTORMATH_SHUF_XAZC );\n    zxzx = spu_shuffle( vec.getZ(), vec.getX(), _VECTORMATH_SHUF_ZDXB );\n    yzyz = spu_shuffle( vec.getY(), vec.getZ(), _VECTORMATH_SHUF_YBWD );\n    xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD );\n    yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD );\n    zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( vec0, xyz0 );\n    storeXYZArray( vec1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Vector3 & Vector3::operator =( const Vector3 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    return *this;\n}\n\ninline Vector3 & Vector3::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Vector3::getX( ) const\n{\n    return mX;\n}\n\ninline Vector3 & Vector3::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Vector3::getY( ) const\n{\n    return mY;\n}\n\ninline Vector3 & Vector3::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Vector3::getZ( ) const\n{\n    return mZ;\n}\n\ninline Vector3 & Vector3::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Vector3::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Vector3::vec_float4_t & Vector3::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Vector3::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector3 Vector3::operator +( const Vector3 & vec ) const\n{\n    return Vector3(\n        spu_add( mX, vec.mX ),\n        spu_add( mY, vec.mY ),\n        spu_add( mZ, vec.mZ )\n    );\n}\n\ninline const Vector3 Vector3::operator -( const Vector3 & vec ) const\n{\n    return Vector3(\n        spu_sub( mX, vec.mX ),\n        spu_sub( mY, vec.mY ),\n        spu_sub( mZ, vec.mZ )\n    );\n}\n\ninline const Point3 Vector3::operator +( const Point3 & pnt ) const\n{\n    return Point3(\n        spu_add( mX, pnt.getX() ),\n        spu_add( mY, pnt.getY() ),\n        spu_add( mZ, pnt.getZ() )\n    );\n}\n\ninline const Vector3 Vector3::operator *( vec_float4 scalar ) const\n{\n    return Vector3(\n        spu_mul( mX, scalar ),\n        spu_mul( mY, scalar ),\n        spu_mul( mZ, scalar )\n    );\n}\n\ninline Vector3 & Vector3::operator +=( const Vector3 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator -=( const Vector3 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector3 & Vector3::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator /( vec_float4 scalar ) const\n{\n    return Vector3(\n        divf4( mX, scalar ),\n        divf4( mY, scalar ),\n        divf4( mZ, scalar )\n    );\n}\n\ninline Vector3 & Vector3::operator /=( vec_float4 scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector3 Vector3::operator -( ) const\n{\n    return Vector3(\n        negatef4( mX ),\n        negatef4( mY ),\n        negatef4( mZ )\n    );\n}\n\ninline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        spu_mul( vec0.getX(), vec1.getX() ),\n        spu_mul( vec0.getY(), vec1.getY() ),\n        spu_mul( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        divf4( vec0.getX(), vec1.getX() ),\n        divf4( vec0.getY(), vec1.getY() ),\n        divf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline const Vector3 recipPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        recipf4( vec.getX() ),\n        recipf4( vec.getY() ),\n        recipf4( vec.getZ() )\n    );\n}\n\ninline const Vector3 sqrtPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        sqrtf4( vec.getX() ),\n        sqrtf4( vec.getY() ),\n        sqrtf4( vec.getZ() )\n    );\n}\n\ninline const Vector3 rsqrtPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        rsqrtf4( vec.getX() ),\n        rsqrtf4( vec.getY() ),\n        rsqrtf4( vec.getZ() )\n    );\n}\n\ninline const Vector3 absPerElem( const Vector3 & vec )\n{\n    return Vector3(\n        fabsf4( vec.getX() ),\n        fabsf4( vec.getY() ),\n        fabsf4( vec.getZ() )\n    );\n}\n\ninline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        copysignf4( vec0.getX(), vec1.getX() ),\n        copysignf4( vec0.getY(), vec1.getY() ),\n        copysignf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        fmaxf4( vec0.getX(), vec1.getX() ),\n        fmaxf4( vec0.getY(), vec1.getY() ),\n        fmaxf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline vec_float4 maxElem( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec.getX(), vec.getY() );\n    result = fmaxf4( vec.getZ(), result );\n    return result;\n}\n\ninline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        fminf4( vec0.getX(), vec1.getX() ),\n        fminf4( vec0.getY(), vec1.getY() ),\n        fminf4( vec0.getZ(), vec1.getZ() )\n    );\n}\n\ninline vec_float4 minElem( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = fminf4( vec.getX(), vec.getY() );\n    result = fminf4( vec.getZ(), result );\n    return result;\n}\n\ninline vec_float4 sum( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = spu_add( vec.getX(), vec.getY() );\n    result = spu_add( result, vec.getZ() );\n    return result;\n}\n\ninline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0.getX(), vec1.getX() );\n    result = spu_add( result, spu_mul( vec0.getY(), vec1.getY() ) );\n    result = spu_add( result, spu_mul( vec0.getZ(), vec1.getZ() ) );\n    return result;\n}\n\ninline vec_float4 lengthSqr( const Vector3 & vec )\n{\n    vec_float4 result;\n    result = spu_mul( vec.getX(), vec.getX() );\n    result = spu_add( result, spu_mul( vec.getY(), vec.getY() ) );\n    result = spu_add( result, spu_mul( vec.getZ(), vec.getZ() ) );\n    return result;\n}\n\ninline vec_float4 length( const Vector3 & vec )\n{\n    return sqrtf4( lengthSqr( vec ) );\n}\n\ninline const Vector3 normalize( const Vector3 & vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = lengthSqr( vec );\n    lenInv = rsqrtf4( lenSqr );\n    return Vector3(\n        spu_mul( vec.getX(), lenInv ),\n        spu_mul( vec.getY(), lenInv ),\n        spu_mul( vec.getZ(), lenInv )\n    );\n}\n\ninline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 )\n{\n    return Vector3(\n        spu_sub( spu_mul( vec0.getY(), vec1.getZ() ), spu_mul( vec0.getZ(), vec1.getY() ) ),\n        spu_sub( spu_mul( vec0.getZ(), vec1.getX() ), spu_mul( vec0.getX(), vec1.getZ() ) ),\n        spu_sub( spu_mul( vec0.getX(), vec1.getY() ), spu_mul( vec0.getY(), vec1.getX() ) )\n    );\n}\n\ninline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 )\n{\n    return Vector3(\n        spu_sel( vec0.getX(), vec1.getX(), select1 ),\n        spu_sel( vec0.getY(), vec1.getY(), select1 ),\n        spu_sel( vec0.getZ(), vec1.getZ(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector3 & vec )\n{\n    Aos::Vector3 vec0, vec1, vec2, vec3;\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Vector3 & vec, const char * name )\n{\n    Aos::Vector3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\ninline Vector4::Vector4( const Vector4 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    mW = vec.mW;\n}\n\ninline Vector4::Vector4( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n    mW = _w;\n}\n\ninline Vector4::Vector4( const Vector3 & xyz, vec_float4 _w )\n{\n    this->setXYZ( xyz );\n    this->setW( _w );\n}\n\ninline Vector4::Vector4( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    mW = spu_splats(0.0f);\n}\n\ninline Vector4::Vector4( const Point3 & pnt )\n{\n    mX = pnt.getX();\n    mY = pnt.getY();\n    mZ = pnt.getZ();\n    mW = spu_splats(1.0f);\n}\n\ninline Vector4::Vector4( const Quat & quat )\n{\n    mX = quat.getX();\n    mY = quat.getY();\n    mZ = quat.getZ();\n    mW = quat.getW();\n}\n\ninline Vector4::Vector4( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n    mW = scalar;\n}\n\ninline Vector4::Vector4( Aos::Vector4 vec )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f);\n    vec_float4 vec128 = vec.get128();\n    mX = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    mY = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    mZ = spu_shuffle( vec128, vec128, shuffle_zzzz );\n    mW = spu_shuffle( vec128, vec128, shuffle_wwww );\n}\n\ninline Vector4::Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_ZCWD );\n    mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n    mW = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD );\n}\n\ninline const Vector4 Vector4::xAxis( )\n{\n    return Vector4( spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) );\n}\n\ninline const Vector4 Vector4::yAxis( )\n{\n    return Vector4( spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) );\n}\n\ninline const Vector4 Vector4::zAxis( )\n{\n    return Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) );\n}\n\ninline const Vector4 Vector4::wAxis( )\n{\n    return Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) );\n}\n\ninline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return ( vec0 + ( ( vec1 - vec0 ) * t ) );\n}\n\ninline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 )\n{\n    vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;\n    vec_uint4 selectMask;\n    cosAngle = dot( unitVec0, unitVec1 );\n    selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle );\n    angle = acosf4( cosAngle );\n    recipSinAngle = recipf4( sinf4( angle ) );\n    scale0 = spu_sel( spu_sub( spu_splats(1.0f), t ), spu_mul( sinf4( spu_mul( spu_sub( spu_splats(1.0f), t ), angle ) ), recipSinAngle ), selectMask );\n    scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask );\n    return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) );\n}\n\ninline void Vector4::get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_ZCWD );\n    result0 = Aos::Vector4( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) );\n    result1 = Aos::Vector4( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) );\n    result2 = Aos::Vector4( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) );\n    result3 = Aos::Vector4( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) );\n}\n\ninline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads )\n{\n    Aos::Vector4 v0, v1, v2, v3;\n    vec.get4Aos( v0, v1, v2, v3 );\n    twoQuads[0] = _vmath2VfToHalfFloats(v0.get128(), v1.get128());\n    twoQuads[1] = _vmath2VfToHalfFloats(v2.get128(), v3.get128());\n}\n\ninline Vector4 & Vector4::operator =( const Vector4 & vec )\n{\n    mX = vec.mX;\n    mY = vec.mY;\n    mZ = vec.mZ;\n    mW = vec.mW;\n    return *this;\n}\n\ninline Vector4 & Vector4::setXYZ( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n    return *this;\n}\n\ninline const Vector3 Vector4::getXYZ( ) const\n{\n    return Vector3( mX, mY, mZ );\n}\n\ninline Vector4 & Vector4::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Vector4::getX( ) const\n{\n    return mX;\n}\n\ninline Vector4 & Vector4::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Vector4::getY( ) const\n{\n    return mY;\n}\n\ninline Vector4 & Vector4::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Vector4::getZ( ) const\n{\n    return mZ;\n}\n\ninline Vector4 & Vector4::setW( vec_float4 _w )\n{\n    mW = _w;\n    return *this;\n}\n\ninline vec_float4 Vector4::getW( ) const\n{\n    return mW;\n}\n\ninline Vector4 & Vector4::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Vector4::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Vector4::vec_float4_t & Vector4::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Vector4::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector4 Vector4::operator +( const Vector4 & vec ) const\n{\n    return Vector4(\n        spu_add( mX, vec.mX ),\n        spu_add( mY, vec.mY ),\n        spu_add( mZ, vec.mZ ),\n        spu_add( mW, vec.mW )\n    );\n}\n\ninline const Vector4 Vector4::operator -( const Vector4 & vec ) const\n{\n    return Vector4(\n        spu_sub( mX, vec.mX ),\n        spu_sub( mY, vec.mY ),\n        spu_sub( mZ, vec.mZ ),\n        spu_sub( mW, vec.mW )\n    );\n}\n\ninline const Vector4 Vector4::operator *( vec_float4 scalar ) const\n{\n    return Vector4(\n        spu_mul( mX, scalar ),\n        spu_mul( mY, scalar ),\n        spu_mul( mZ, scalar ),\n        spu_mul( mW, scalar )\n    );\n}\n\ninline Vector4 & Vector4::operator +=( const Vector4 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator -=( const Vector4 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline Vector4 & Vector4::operator *=( vec_float4 scalar )\n{\n    *this = *this * scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator /( vec_float4 scalar ) const\n{\n    return Vector4(\n        divf4( mX, scalar ),\n        divf4( mY, scalar ),\n        divf4( mZ, scalar ),\n        divf4( mW, scalar )\n    );\n}\n\ninline Vector4 & Vector4::operator /=( vec_float4 scalar )\n{\n    *this = *this / scalar;\n    return *this;\n}\n\ninline const Vector4 Vector4::operator -( ) const\n{\n    return Vector4(\n        negatef4( mX ),\n        negatef4( mY ),\n        negatef4( mZ ),\n        negatef4( mW )\n    );\n}\n\ninline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec )\n{\n    return vec * scalar;\n}\n\ninline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        spu_mul( vec0.getX(), vec1.getX() ),\n        spu_mul( vec0.getY(), vec1.getY() ),\n        spu_mul( vec0.getZ(), vec1.getZ() ),\n        spu_mul( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        divf4( vec0.getX(), vec1.getX() ),\n        divf4( vec0.getY(), vec1.getY() ),\n        divf4( vec0.getZ(), vec1.getZ() ),\n        divf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline const Vector4 recipPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        recipf4( vec.getX() ),\n        recipf4( vec.getY() ),\n        recipf4( vec.getZ() ),\n        recipf4( vec.getW() )\n    );\n}\n\ninline const Vector4 sqrtPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        sqrtf4( vec.getX() ),\n        sqrtf4( vec.getY() ),\n        sqrtf4( vec.getZ() ),\n        sqrtf4( vec.getW() )\n    );\n}\n\ninline const Vector4 rsqrtPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        rsqrtf4( vec.getX() ),\n        rsqrtf4( vec.getY() ),\n        rsqrtf4( vec.getZ() ),\n        rsqrtf4( vec.getW() )\n    );\n}\n\ninline const Vector4 absPerElem( const Vector4 & vec )\n{\n    return Vector4(\n        fabsf4( vec.getX() ),\n        fabsf4( vec.getY() ),\n        fabsf4( vec.getZ() ),\n        fabsf4( vec.getW() )\n    );\n}\n\ninline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        copysignf4( vec0.getX(), vec1.getX() ),\n        copysignf4( vec0.getY(), vec1.getY() ),\n        copysignf4( vec0.getZ(), vec1.getZ() ),\n        copysignf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        fmaxf4( vec0.getX(), vec1.getX() ),\n        fmaxf4( vec0.getY(), vec1.getY() ),\n        fmaxf4( vec0.getZ(), vec1.getZ() ),\n        fmaxf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline vec_float4 maxElem( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = fmaxf4( vec.getX(), vec.getY() );\n    result = fmaxf4( vec.getZ(), result );\n    result = fmaxf4( vec.getW(), result );\n    return result;\n}\n\ninline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    return Vector4(\n        fminf4( vec0.getX(), vec1.getX() ),\n        fminf4( vec0.getY(), vec1.getY() ),\n        fminf4( vec0.getZ(), vec1.getZ() ),\n        fminf4( vec0.getW(), vec1.getW() )\n    );\n}\n\ninline vec_float4 minElem( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = fminf4( vec.getX(), vec.getY() );\n    result = fminf4( vec.getZ(), result );\n    result = fminf4( vec.getW(), result );\n    return result;\n}\n\ninline vec_float4 sum( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = spu_add( vec.getX(), vec.getY() );\n    result = spu_add( result, vec.getZ() );\n    result = spu_add( result, vec.getW() );\n    return result;\n}\n\ninline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 )\n{\n    vec_float4 result;\n    result = spu_mul( vec0.getX(), vec1.getX() );\n    result = spu_add( result, spu_mul( vec0.getY(), vec1.getY() ) );\n    result = spu_add( result, spu_mul( vec0.getZ(), vec1.getZ() ) );\n    result = spu_add( result, spu_mul( vec0.getW(), vec1.getW() ) );\n    return result;\n}\n\ninline vec_float4 lengthSqr( const Vector4 & vec )\n{\n    vec_float4 result;\n    result = spu_mul( vec.getX(), vec.getX() );\n    result = spu_add( result, spu_mul( vec.getY(), vec.getY() ) );\n    result = spu_add( result, spu_mul( vec.getZ(), vec.getZ() ) );\n    result = spu_add( result, spu_mul( vec.getW(), vec.getW() ) );\n    return result;\n}\n\ninline vec_float4 length( const Vector4 & vec )\n{\n    return sqrtf4( lengthSqr( vec ) );\n}\n\ninline const Vector4 normalize( const Vector4 & vec )\n{\n    vec_float4 lenSqr, lenInv;\n    lenSqr = lengthSqr( vec );\n    lenInv = rsqrtf4( lenSqr );\n    return Vector4(\n        spu_mul( vec.getX(), lenInv ),\n        spu_mul( vec.getY(), lenInv ),\n        spu_mul( vec.getZ(), lenInv ),\n        spu_mul( vec.getW(), lenInv )\n    );\n}\n\ninline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 )\n{\n    return Vector4(\n        spu_sel( vec0.getX(), vec1.getX(), select1 ),\n        spu_sel( vec0.getY(), vec1.getY(), select1 ),\n        spu_sel( vec0.getZ(), vec1.getZ(), select1 ),\n        spu_sel( vec0.getW(), vec1.getW(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Vector4 & vec )\n{\n    Aos::Vector4 vec0, vec1, vec2, vec3;\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Vector4 & vec, const char * name )\n{\n    Aos::Vector4 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    vec.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\ninline Point3::Point3( const Point3 & pnt )\n{\n    mX = pnt.mX;\n    mY = pnt.mY;\n    mZ = pnt.mZ;\n}\n\ninline Point3::Point3( vec_float4 _x, vec_float4 _y, vec_float4 _z )\n{\n    mX = _x;\n    mY = _y;\n    mZ = _z;\n}\n\ninline Point3::Point3( const Vector3 & vec )\n{\n    mX = vec.getX();\n    mY = vec.getY();\n    mZ = vec.getZ();\n}\n\ninline Point3::Point3( vec_float4 scalar )\n{\n    mX = scalar;\n    mY = scalar;\n    mZ = scalar;\n}\n\ninline Point3::Point3( Aos::Point3 pnt )\n{\n    vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203);\n    vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607);\n    vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b);\n    vec_float4 vec128 = pnt.get128();\n    mX = spu_shuffle( vec128, vec128, shuffle_xxxx );\n    mY = spu_shuffle( vec128, vec128, shuffle_yyyy );\n    mZ = spu_shuffle( vec128, vec128, shuffle_zzzz );\n}\n\ninline Point3::Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 )\n{\n    vec_float4 tmp0, tmp1, tmp2, tmp3;\n    tmp0 = spu_shuffle( pnt0.get128(), pnt2.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( pnt1.get128(), pnt3.get128(), _VECTORMATH_SHUF_XAYB );\n    tmp2 = spu_shuffle( pnt0.get128(), pnt2.get128(), _VECTORMATH_SHUF_ZCWD );\n    tmp3 = spu_shuffle( pnt1.get128(), pnt3.get128(), _VECTORMATH_SHUF_ZCWD );\n    mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB );\n    mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD );\n    mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB );\n}\n\ninline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) );\n}\n\ninline void Point3::get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const\n{\n    vec_float4 tmp0, tmp1;\n    tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB );\n    tmp1 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD );\n    result0 = Aos::Point3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_XAYB ) );\n    result1 = Aos::Point3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_ZBW0 ) );\n    result2 = Aos::Point3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_XCY0 ) );\n    result3 = Aos::Point3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_ZDW0 ) );\n}\n\ninline void loadXYZArray( Point3 & vec, const vec_float4 * threeQuads )\n{\n    vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz;\n    xyzx = threeQuads[0];\n    yzxy = threeQuads[1];\n    zxyz = threeQuads[2];\n    xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD );\n    zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD );\n    yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD );\n    vec.setX( spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) );\n    vec.setY( spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) );\n    vec.setZ( spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) );\n}\n\ninline void storeXYZArray( const Point3 & vec, vec_float4 * threeQuads )\n{\n    vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz;\n    xyxy = spu_shuffle( vec.getX(), vec.getY(), _VECTORMATH_SHUF_XAZC );\n    zxzx = spu_shuffle( vec.getZ(), vec.getX(), _VECTORMATH_SHUF_ZDXB );\n    yzyz = spu_shuffle( vec.getY(), vec.getZ(), _VECTORMATH_SHUF_YBWD );\n    xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD );\n    yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD );\n    zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD );\n    threeQuads[0] = xyzx;\n    threeQuads[1] = yzxy;\n    threeQuads[2] = zxyz;\n}\n\ninline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads )\n{\n    vec_float4 xyz0[3];\n    vec_float4 xyz1[3];\n    storeXYZArray( pnt0, xyz0 );\n    storeXYZArray( pnt1, xyz1 );\n    threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]);\n    threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]);\n    threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]);\n}\n\ninline Point3 & Point3::operator =( const Point3 & pnt )\n{\n    mX = pnt.mX;\n    mY = pnt.mY;\n    mZ = pnt.mZ;\n    return *this;\n}\n\ninline Point3 & Point3::setX( vec_float4 _x )\n{\n    mX = _x;\n    return *this;\n}\n\ninline vec_float4 Point3::getX( ) const\n{\n    return mX;\n}\n\ninline Point3 & Point3::setY( vec_float4 _y )\n{\n    mY = _y;\n    return *this;\n}\n\ninline vec_float4 Point3::getY( ) const\n{\n    return mY;\n}\n\ninline Point3 & Point3::setZ( vec_float4 _z )\n{\n    mZ = _z;\n    return *this;\n}\n\ninline vec_float4 Point3::getZ( ) const\n{\n    return mZ;\n}\n\ninline Point3 & Point3::setElem( int idx, vec_float4 value )\n{\n    *(&mX + idx) = value;\n    return *this;\n}\n\ninline vec_float4 Point3::getElem( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline Point3::vec_float4_t & Point3::operator []( int idx )\n{\n    return *(&mX + idx);\n}\n\ninline vec_float4 Point3::operator []( int idx ) const\n{\n    return *(&mX + idx);\n}\n\ninline const Vector3 Point3::operator -( const Point3 & pnt ) const\n{\n    return Vector3(\n        spu_sub( mX, pnt.mX ),\n        spu_sub( mY, pnt.mY ),\n        spu_sub( mZ, pnt.mZ )\n    );\n}\n\ninline const Point3 Point3::operator +( const Vector3 & vec ) const\n{\n    return Point3(\n        spu_add( mX, vec.getX() ),\n        spu_add( mY, vec.getY() ),\n        spu_add( mZ, vec.getZ() )\n    );\n}\n\ninline const Point3 Point3::operator -( const Vector3 & vec ) const\n{\n    return Point3(\n        spu_sub( mX, vec.getX() ),\n        spu_sub( mY, vec.getY() ),\n        spu_sub( mZ, vec.getZ() )\n    );\n}\n\ninline Point3 & Point3::operator +=( const Vector3 & vec )\n{\n    *this = *this + vec;\n    return *this;\n}\n\ninline Point3 & Point3::operator -=( const Vector3 & vec )\n{\n    *this = *this - vec;\n    return *this;\n}\n\ninline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        spu_mul( pnt0.getX(), pnt1.getX() ),\n        spu_mul( pnt0.getY(), pnt1.getY() ),\n        spu_mul( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        divf4( pnt0.getX(), pnt1.getX() ),\n        divf4( pnt0.getY(), pnt1.getY() ),\n        divf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline const Point3 recipPerElem( const Point3 & pnt )\n{\n    return Point3(\n        recipf4( pnt.getX() ),\n        recipf4( pnt.getY() ),\n        recipf4( pnt.getZ() )\n    );\n}\n\ninline const Point3 sqrtPerElem( const Point3 & pnt )\n{\n    return Point3(\n        sqrtf4( pnt.getX() ),\n        sqrtf4( pnt.getY() ),\n        sqrtf4( pnt.getZ() )\n    );\n}\n\ninline const Point3 rsqrtPerElem( const Point3 & pnt )\n{\n    return Point3(\n        rsqrtf4( pnt.getX() ),\n        rsqrtf4( pnt.getY() ),\n        rsqrtf4( pnt.getZ() )\n    );\n}\n\ninline const Point3 absPerElem( const Point3 & pnt )\n{\n    return Point3(\n        fabsf4( pnt.getX() ),\n        fabsf4( pnt.getY() ),\n        fabsf4( pnt.getZ() )\n    );\n}\n\ninline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        copysignf4( pnt0.getX(), pnt1.getX() ),\n        copysignf4( pnt0.getY(), pnt1.getY() ),\n        copysignf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        fmaxf4( pnt0.getX(), pnt1.getX() ),\n        fmaxf4( pnt0.getY(), pnt1.getY() ),\n        fmaxf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline vec_float4 maxElem( const Point3 & pnt )\n{\n    vec_float4 result;\n    result = fmaxf4( pnt.getX(), pnt.getY() );\n    result = fmaxf4( pnt.getZ(), result );\n    return result;\n}\n\ninline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return Point3(\n        fminf4( pnt0.getX(), pnt1.getX() ),\n        fminf4( pnt0.getY(), pnt1.getY() ),\n        fminf4( pnt0.getZ(), pnt1.getZ() )\n    );\n}\n\ninline vec_float4 minElem( const Point3 & pnt )\n{\n    vec_float4 result;\n    result = fminf4( pnt.getX(), pnt.getY() );\n    result = fminf4( pnt.getZ(), result );\n    return result;\n}\n\ninline vec_float4 sum( const Point3 & pnt )\n{\n    vec_float4 result;\n    result = spu_add( pnt.getX(), pnt.getY() );\n    result = spu_add( result, pnt.getZ() );\n    return result;\n}\n\ninline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal )\n{\n    return mulPerElem( pnt, Point3( scaleVal ) );\n}\n\ninline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec )\n{\n    return mulPerElem( pnt, Point3( scaleVec ) );\n}\n\ninline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec )\n{\n    vec_float4 result;\n    result = spu_mul( pnt.getX(), unitVec.getX() );\n    result = spu_add( result, spu_mul( pnt.getY(), unitVec.getY() ) );\n    result = spu_add( result, spu_mul( pnt.getZ(), unitVec.getZ() ) );\n    return result;\n}\n\ninline vec_float4 distSqrFromOrigin( const Point3 & pnt )\n{\n    return lengthSqr( Vector3( pnt ) );\n}\n\ninline vec_float4 distFromOrigin( const Point3 & pnt )\n{\n    return length( Vector3( pnt ) );\n}\n\ninline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return lengthSqr( ( pnt1 - pnt0 ) );\n}\n\ninline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 )\n{\n    return length( ( pnt1 - pnt0 ) );\n}\n\ninline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 )\n{\n    return Point3(\n        spu_sel( pnt0.getX(), pnt1.getX(), select1 ),\n        spu_sel( pnt0.getY(), pnt1.getY(), select1 ),\n        spu_sel( pnt0.getZ(), pnt1.getZ(), select1 )\n    );\n}\n\n#ifdef _VECTORMATH_DEBUG\n\ninline void print( const Point3 & pnt )\n{\n    Aos::Point3 vec0, vec1, vec2, vec3;\n    pnt.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\ninline void print( const Point3 & pnt, const char * name )\n{\n    Aos::Point3 vec0, vec1, vec2, vec3;\n    printf( \"%s:\\n\", name );\n    pnt.get4Aos( vec0, vec1, vec2, vec3 );\n    printf(\"slot 0:\\n\");\n    print( vec0 );\n    printf(\"slot 1:\\n\");\n    print( vec1 );\n    printf(\"slot 2:\\n\");\n    print( vec2 );\n    printf(\"slot 3:\\n\");\n    print( vec3 );\n}\n\n#endif\n\n} // namespace Soa\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/vecidx_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_VECIDX_AOS_H\n#define _VECTORMATH_VECIDX_AOS_H\n\n#include <spu_intrinsics.h>\n\nnamespace Vectormath {\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// VecIdx \n// Used in setting elements of Vector3, Vector4, Point3, or Quat with the \n// subscripting operator.\n//\n\nclass VecIdx\n{\nprivate:\n    typedef vec_float4 vec_float4_t;\n    vec_float4_t &ref __attribute__ ((aligned(16)));\n    int i __attribute__ ((aligned(16)));\npublic:\n    inline VecIdx( vec_float4& vec, int idx ): ref(vec) { i = idx; }\n    inline operator float() const;\n    inline float operator =( float scalar );\n    inline float operator =( const VecIdx& scalar );\n    inline float operator *=( float scalar );\n    inline float operator /=( float scalar );\n    inline float operator +=( float scalar );\n    inline float operator -=( float scalar );\n};\n\n} // namespace Aos\n} // namespace Vectormath\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/vectormath_aos.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_AOS_CPP_SPU_H\n#define _VECTORMATH_AOS_CPP_SPU_H\n\n#include <math.h>\n#include <spu_intrinsics.h>\n#include \"floatInVec.h\"\n#include \"boolInVec.h\"\n#include \"vecidx_aos.h\"\n#include <stdio.h>\n\n#ifdef _VECTORMATH_DEBUG\n#endif\n\nnamespace Vectormath {\n\nnamespace Aos {\n\n//-----------------------------------------------------------------------------\n// Forward Declarations\n//\n\nclass Vector3;\nclass Vector4;\nclass Point3;\nclass Quat;\nclass Matrix3;\nclass Matrix4;\nclass Transform3;\n\n// A 3-D vector in array-of-structures format\n//\nclass Vector3\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector3( ) { };\n\n    // Construct a 3-D vector from x, y, and z elements\n    // \n    inline Vector3( float x, float y, float z );\n\n    // Copy elements from a 3-D point into a 3-D vector\n    // \n    explicit inline Vector3( Point3 pnt );\n\n    // Set all elements of a 3-D vector to the same scalar value\n    // \n    explicit inline Vector3( float scalar );\n\n    // Set vector float data in a 3-D vector\n    // \n    explicit inline Vector3( vec_float4 vf4 );\n\n    // Get vector float data from a 3-D vector\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one 3-D vector to another\n    // \n    inline Vector3 & operator =( Vector3 vec );\n\n    // Set the x element of a 3-D vector\n    // \n    inline Vector3 & setX( float x );\n\n    // Set the y element of a 3-D vector\n    // \n    inline Vector3 & setY( float y );\n\n    // Set the z element of a 3-D vector\n    // \n    inline Vector3 & setZ( float z );\n\n    // Get the x element of a 3-D vector\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a 3-D vector\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a 3-D vector\n    // \n    inline float getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D vector by index\n    // \n    inline Vector3 & setElem( int idx, float value );\n\n    // Get an x, y, or z element of a 3-D vector by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Add two 3-D vectors\n    // \n    inline const Vector3 operator +( Vector3 vec ) const;\n\n    // Subtract a 3-D vector from another 3-D vector\n    // \n    inline const Vector3 operator -( Vector3 vec ) const;\n\n    // Add a 3-D vector to a 3-D point\n    // \n    inline const Point3 operator +( Point3 pnt ) const;\n\n    // Multiply a 3-D vector by a scalar\n    // \n    inline const Vector3 operator *( float scalar ) const;\n\n    // Divide a 3-D vector by a scalar\n    // \n    inline const Vector3 operator /( float scalar ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Vector3 & operator +=( Vector3 vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Vector3 & operator -=( Vector3 vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector3 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector3 & operator /=( float scalar );\n\n    // Negate all elements of a 3-D vector\n    // \n    inline const Vector3 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector3 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector3 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector3 zAxis( );\n\n};\n\n// Multiply a 3-D vector by a scalar\n// \ninline const Vector3 operator *( float scalar, Vector3 vec );\n\n// Multiply two 3-D vectors per element\n// \ninline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Divide two 3-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Compute the reciprocal of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector3 recipPerElem( Vector3 vec );\n\n// Compute the square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector3 sqrtPerElem( Vector3 vec );\n\n// Compute the reciprocal square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector3 rsqrtPerElem( Vector3 vec );\n\n// Compute the absolute value of a 3-D vector per element\n// \ninline const Vector3 absPerElem( Vector3 vec );\n\n// Copy sign from one 3-D vector to another, per element\n// \ninline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Maximum of two 3-D vectors per element\n// \ninline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Minimum of two 3-D vectors per element\n// \ninline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 );\n\n// Maximum element of a 3-D vector\n// \ninline float maxElem( Vector3 vec );\n\n// Minimum element of a 3-D vector\n// \ninline float minElem( Vector3 vec );\n\n// Compute the sum of all elements of a 3-D vector\n// \ninline float sum( Vector3 vec );\n\n// Compute the dot product of two 3-D vectors\n// \ninline float dot( Vector3 vec0, Vector3 vec1 );\n\n// Compute the square of the length of a 3-D vector\n// \ninline float lengthSqr( Vector3 vec );\n\n// Compute the length of a 3-D vector\n// \ninline float length( Vector3 vec );\n\n// Normalize a 3-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector3 normalize( Vector3 vec );\n\n// Compute cross product of two 3-D vectors\n// \ninline const Vector3 cross( Vector3 vec0, Vector3 vec1 );\n\n// Outer product of two 3-D vectors\n// \ninline const Matrix3 outer( Vector3 vec0, Vector3 vec1 );\n\n// Pre-multiply a row vector by a 3x3 matrix\n// NOTE: \n// Slower than column post-multiply.\n// \ninline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat );\n\n// Cross-product matrix of a 3-D vector\n// \ninline const Matrix3 crossMatrix( Vector3 vec );\n\n// Create cross-product matrix and multiply\n// NOTE: \n// Faster than separately creating a cross-product matrix and multiplying.\n// \ninline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat );\n\n// Linear interpolation between two 3-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 );\n\n// Spherical linear interpolation between two 3-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 );\n\n// Conditionally select between two 3-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 );\n\n// Store x, y, and z elements of a 3-D vector in the first three words of a quadword.\n// The value of the fourth word (the word with the highest address) remains unchanged\n// \ninline void storeXYZ( Vector3 vec, vec_float4 * quad );\n\n// Load four three-float 3-D vectors, stored in three quadwords\n// \ninline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads );\n\n// Store four 3-D vectors in three quadwords\n// \ninline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads );\n\n// Store eight 3-D vectors as half-floats\n// \ninline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector3 vec );\n\n// Print a 3-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector3 vec, const char * name );\n\n#endif\n\n// A 4-D vector in array-of-structures format\n//\nclass Vector4\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector4( ) { };\n\n    // Construct a 4-D vector from x, y, z, and w elements\n    // \n    inline Vector4( float x, float y, float z, float w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar\n    // \n    inline Vector4( Vector3 xyz, float w );\n\n    // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n    // \n    explicit inline Vector4( Vector3 vec );\n\n    // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n    // \n    explicit inline Vector4( Point3 pnt );\n\n    // Copy elements from a quaternion into a 4-D vector\n    // \n    explicit inline Vector4( Quat quat );\n\n    // Set all elements of a 4-D vector to the same scalar value\n    // \n    explicit inline Vector4( float scalar );\n\n    // Set vector float data in a 4-D vector\n    // \n    explicit inline Vector4( vec_float4 vf4 );\n\n    // Get vector float data from a 4-D vector\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one 4-D vector to another\n    // \n    inline Vector4 & operator =( Vector4 vec );\n\n    // Set the x, y, and z elements of a 4-D vector\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Vector4 & setXYZ( Vector3 vec );\n\n    // Get the x, y, and z elements of a 4-D vector\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a 4-D vector\n    // \n    inline Vector4 & setX( float x );\n\n    // Set the y element of a 4-D vector\n    // \n    inline Vector4 & setY( float y );\n\n    // Set the z element of a 4-D vector\n    // \n    inline Vector4 & setZ( float z );\n\n    // Set the w element of a 4-D vector\n    // \n    inline Vector4 & setW( float w );\n\n    // Get the x element of a 4-D vector\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a 4-D vector\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a 4-D vector\n    // \n    inline float getZ( ) const;\n\n    // Get the w element of a 4-D vector\n    // \n    inline float getW( ) const;\n\n    // Set an x, y, z, or w element of a 4-D vector by index\n    // \n    inline Vector4 & setElem( int idx, float value );\n\n    // Get an x, y, z, or w element of a 4-D vector by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Add two 4-D vectors\n    // \n    inline const Vector4 operator +( Vector4 vec ) const;\n\n    // Subtract a 4-D vector from another 4-D vector\n    // \n    inline const Vector4 operator -( Vector4 vec ) const;\n\n    // Multiply a 4-D vector by a scalar\n    // \n    inline const Vector4 operator *( float scalar ) const;\n\n    // Divide a 4-D vector by a scalar\n    // \n    inline const Vector4 operator /( float scalar ) const;\n\n    // Perform compound assignment and addition with a 4-D vector\n    // \n    inline Vector4 & operator +=( Vector4 vec );\n\n    // Perform compound assignment and subtraction by a 4-D vector\n    // \n    inline Vector4 & operator -=( Vector4 vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector4 & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector4 & operator /=( float scalar );\n\n    // Negate all elements of a 4-D vector\n    // \n    inline const Vector4 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector4 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector4 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector4 zAxis( );\n\n    // Construct w axis\n    // \n    static inline const Vector4 wAxis( );\n\n};\n\n// Multiply a 4-D vector by a scalar\n// \ninline const Vector4 operator *( float scalar, Vector4 vec );\n\n// Multiply two 4-D vectors per element\n// \ninline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Divide two 4-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Compute the reciprocal of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector4 recipPerElem( Vector4 vec );\n\n// Compute the square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector4 sqrtPerElem( Vector4 vec );\n\n// Compute the reciprocal square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector4 rsqrtPerElem( Vector4 vec );\n\n// Compute the absolute value of a 4-D vector per element\n// \ninline const Vector4 absPerElem( Vector4 vec );\n\n// Copy sign from one 4-D vector to another, per element\n// \ninline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Maximum of two 4-D vectors per element\n// \ninline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Minimum of two 4-D vectors per element\n// \ninline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 );\n\n// Maximum element of a 4-D vector\n// \ninline float maxElem( Vector4 vec );\n\n// Minimum element of a 4-D vector\n// \ninline float minElem( Vector4 vec );\n\n// Compute the sum of all elements of a 4-D vector\n// \ninline float sum( Vector4 vec );\n\n// Compute the dot product of two 4-D vectors\n// \ninline float dot( Vector4 vec0, Vector4 vec1 );\n\n// Compute the square of the length of a 4-D vector\n// \ninline float lengthSqr( Vector4 vec );\n\n// Compute the length of a 4-D vector\n// \ninline float length( Vector4 vec );\n\n// Normalize a 4-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector4 normalize( Vector4 vec );\n\n// Outer product of two 4-D vectors\n// \ninline const Matrix4 outer( Vector4 vec0, Vector4 vec1 );\n\n// Linear interpolation between two 4-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 );\n\n// Spherical linear interpolation between two 4-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 );\n\n// Conditionally select between two 4-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 );\n\n// Store four 4-D vectors as half-floats\n// \ninline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector4 vec );\n\n// Print a 4-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Vector4 vec, const char * name );\n\n#endif\n\n// A 3-D point in array-of-structures format\n//\nclass Point3\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Point3( ) { };\n\n    // Construct a 3-D point from x, y, and z elements\n    // \n    inline Point3( float x, float y, float z );\n\n    // Copy elements from a 3-D vector into a 3-D point\n    // \n    explicit inline Point3( Vector3 vec );\n\n    // Set all elements of a 3-D point to the same scalar value\n    // \n    explicit inline Point3( float scalar );\n\n    // Set vector float data in a 3-D point\n    // \n    explicit inline Point3( vec_float4 vf4 );\n\n    // Get vector float data from a 3-D point\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one 3-D point to another\n    // \n    inline Point3 & operator =( Point3 pnt );\n\n    // Set the x element of a 3-D point\n    // \n    inline Point3 & setX( float x );\n\n    // Set the y element of a 3-D point\n    // \n    inline Point3 & setY( float y );\n\n    // Set the z element of a 3-D point\n    // \n    inline Point3 & setZ( float z );\n\n    // Get the x element of a 3-D point\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a 3-D point\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a 3-D point\n    // \n    inline float getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D point by index\n    // \n    inline Point3 & setElem( int idx, float value );\n\n    // Get an x, y, or z element of a 3-D point by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Subtract a 3-D point from another 3-D point\n    // \n    inline const Vector3 operator -( Point3 pnt ) const;\n\n    // Add a 3-D point to a 3-D vector\n    // \n    inline const Point3 operator +( Vector3 vec ) const;\n\n    // Subtract a 3-D vector from a 3-D point\n    // \n    inline const Point3 operator -( Vector3 vec ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Point3 & operator +=( Vector3 vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Point3 & operator -=( Vector3 vec );\n\n};\n\n// Multiply two 3-D points per element\n// \ninline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Divide two 3-D points per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Compute the reciprocal of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Point3 recipPerElem( Point3 pnt );\n\n// Compute the square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Point3 sqrtPerElem( Point3 pnt );\n\n// Compute the reciprocal square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Point3 rsqrtPerElem( Point3 pnt );\n\n// Compute the absolute value of a 3-D point per element\n// \ninline const Point3 absPerElem( Point3 pnt );\n\n// Copy sign from one 3-D point to another, per element\n// \ninline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Maximum of two 3-D points per element\n// \ninline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Minimum of two 3-D points per element\n// \ninline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 );\n\n// Maximum element of a 3-D point\n// \ninline float maxElem( Point3 pnt );\n\n// Minimum element of a 3-D point\n// \ninline float minElem( Point3 pnt );\n\n// Compute the sum of all elements of a 3-D point\n// \ninline float sum( Point3 pnt );\n\n// Apply uniform scale to a 3-D point\n// \ninline const Point3 scale( Point3 pnt, float scaleVal );\n\n// Apply non-uniform scale to a 3-D point\n// \ninline const Point3 scale( Point3 pnt, Vector3 scaleVec );\n\n// Scalar projection of a 3-D point on a unit-length 3-D vector\n// \ninline float projection( Point3 pnt, Vector3 unitVec );\n\n// Compute the square of the distance of a 3-D point from the coordinate-system origin\n// \ninline float distSqrFromOrigin( Point3 pnt );\n\n// Compute the distance of a 3-D point from the coordinate-system origin\n// \ninline float distFromOrigin( Point3 pnt );\n\n// Compute the square of the distance between two 3-D points\n// \ninline float distSqr( Point3 pnt0, Point3 pnt1 );\n\n// Compute the distance between two 3-D points\n// \ninline float dist( Point3 pnt0, Point3 pnt1 );\n\n// Linear interpolation between two 3-D points\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 );\n\n// Conditionally select between two 3-D points\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 );\n\n// Store x, y, and z elements of a 3-D point in the first three words of a quadword.\n// The value of the fourth word (the word with the highest address) remains unchanged\n// \ninline void storeXYZ( Point3 pnt, vec_float4 * quad );\n\n// Load four three-float 3-D points, stored in three quadwords\n// \ninline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads );\n\n// Store four 3-D points in three quadwords\n// \ninline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads );\n\n// Store eight 3-D points as half-floats\n// \ninline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D point\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Point3 pnt );\n\n// Print a 3-D point and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Point3 pnt, const char * name );\n\n#endif\n\n// A quaternion in array-of-structures format\n//\nclass Quat\n{\n    vec_float4 mVec128;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Quat( ) { };\n\n    // Construct a quaternion from x, y, z, and w elements\n    // \n    inline Quat( float x, float y, float z, float w );\n\n    // Construct a quaternion from a 3-D vector and a scalar\n    // \n    inline Quat( Vector3 xyz, float w );\n\n    // Copy elements from a 4-D vector into a quaternion\n    // \n    explicit inline Quat( Vector4 vec );\n\n    // Convert a rotation matrix to a unit-length quaternion\n    // \n    explicit inline Quat( const Matrix3 & rotMat );\n\n    // Set all elements of a quaternion to the same scalar value\n    // \n    explicit inline Quat( float scalar );\n\n    // Set vector float data in a quaternion\n    // \n    explicit inline Quat( vec_float4 vf4 );\n\n    // Get vector float data from a quaternion\n    // \n    inline vec_float4 get128( ) const;\n\n    // Assign one quaternion to another\n    // \n    inline Quat & operator =( Quat quat );\n\n    // Set the x, y, and z elements of a quaternion\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Quat & setXYZ( Vector3 vec );\n\n    // Get the x, y, and z elements of a quaternion\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a quaternion\n    // \n    inline Quat & setX( float x );\n\n    // Set the y element of a quaternion\n    // \n    inline Quat & setY( float y );\n\n    // Set the z element of a quaternion\n    // \n    inline Quat & setZ( float z );\n\n    // Set the w element of a quaternion\n    // \n    inline Quat & setW( float w );\n\n    // Get the x element of a quaternion\n    // \n    inline float getX( ) const;\n\n    // Get the y element of a quaternion\n    // \n    inline float getY( ) const;\n\n    // Get the z element of a quaternion\n    // \n    inline float getZ( ) const;\n\n    // Get the w element of a quaternion\n    // \n    inline float getW( ) const;\n\n    // Set an x, y, z, or w element of a quaternion by index\n    // \n    inline Quat & setElem( int idx, float value );\n\n    // Get an x, y, z, or w element of a quaternion by index\n    // \n    inline float getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline VecIdx operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline float operator []( int idx ) const;\n\n    // Add two quaternions\n    // \n    inline const Quat operator +( Quat quat ) const;\n\n    // Subtract a quaternion from another quaternion\n    // \n    inline const Quat operator -( Quat quat ) const;\n\n    // Multiply two quaternions\n    // \n    inline const Quat operator *( Quat quat ) const;\n\n    // Multiply a quaternion by a scalar\n    // \n    inline const Quat operator *( float scalar ) const;\n\n    // Divide a quaternion by a scalar\n    // \n    inline const Quat operator /( float scalar ) const;\n\n    // Perform compound assignment and addition with a quaternion\n    // \n    inline Quat & operator +=( Quat quat );\n\n    // Perform compound assignment and subtraction by a quaternion\n    // \n    inline Quat & operator -=( Quat quat );\n\n    // Perform compound assignment and multiplication by a quaternion\n    // \n    inline Quat & operator *=( Quat quat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Quat & operator *=( float scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Quat & operator /=( float scalar );\n\n    // Negate all elements of a quaternion\n    // \n    inline const Quat operator -( ) const;\n\n    // Construct an identity quaternion\n    // \n    static inline const Quat identity( );\n\n    // Construct a quaternion to rotate between two unit-length 3-D vectors\n    // NOTE: \n    // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n    // \n    static inline const Quat rotation( Vector3 unitVec0, Vector3 unitVec1 );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector\n    // \n    static inline const Quat rotation( float radians, Vector3 unitVec );\n\n    // Construct a quaternion to rotate around the x axis\n    // \n    static inline const Quat rotationX( float radians );\n\n    // Construct a quaternion to rotate around the y axis\n    // \n    static inline const Quat rotationY( float radians );\n\n    // Construct a quaternion to rotate around the z axis\n    // \n    static inline const Quat rotationZ( float radians );\n\n};\n\n// Multiply a quaternion by a scalar\n// \ninline const Quat operator *( float scalar, Quat quat );\n\n// Compute the conjugate of a quaternion\n// \ninline const Quat conj( Quat quat );\n\n// Use a unit-length quaternion to rotate a 3-D vector\n// \ninline const Vector3 rotate( Quat unitQuat, Vector3 vec );\n\n// Compute the dot product of two quaternions\n// \ninline float dot( Quat quat0, Quat quat1 );\n\n// Compute the norm of a quaternion\n// \ninline float norm( Quat quat );\n\n// Compute the length of a quaternion\n// \ninline float length( Quat quat );\n\n// Normalize a quaternion\n// NOTE: \n// The result is unpredictable when all elements of quat are at or near zero.\n// \ninline const Quat normalize( Quat quat );\n\n// Linear interpolation between two quaternions\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Quat lerp( float t, Quat quat0, Quat quat1 );\n\n// Spherical linear interpolation between two quaternions\n// NOTE: \n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n// \ninline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 );\n\n// Spherical quadrangle interpolation\n// \ninline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 );\n\n// Conditionally select between two quaternions\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Quat select( Quat quat0, Quat quat1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a quaternion\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Quat quat );\n\n// Print a quaternion and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( Quat quat, const char * name );\n\n#endif\n\n// A 3x3 matrix in array-of-structures format\n//\nclass Matrix3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix3( ) { };\n\n    // Copy a 3x3 matrix\n    // \n    inline Matrix3( const Matrix3 & mat );\n\n    // Construct a 3x3 matrix containing the specified columns\n    // \n    inline Matrix3( Vector3 col0, Vector3 col1, Vector3 col2 );\n\n    // Construct a 3x3 rotation matrix from a unit-length quaternion\n    // \n    explicit inline Matrix3( Quat unitQuat );\n\n    // Set all elements of a 3x3 matrix to the same scalar value\n    // \n    explicit inline Matrix3( float scalar );\n\n    // Assign one 3x3 matrix to another\n    // \n    inline Matrix3 & operator =( const Matrix3 & mat );\n\n    // Set column 0 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol0( Vector3 col0 );\n\n    // Set column 1 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol1( Vector3 col1 );\n\n    // Set column 2 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol2( Vector3 col2 );\n\n    // Get column 0 of a 3x3 matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x3 matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x3 matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Set the column of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setCol( int col, Vector3 vec );\n\n    // Set the row of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setRow( int row, Vector3 vec );\n\n    // Get the column of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline Matrix3 & setElem( int col, int row, float val );\n\n    // Get the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline float getElem( int col, int row ) const;\n\n    // Add two 3x3 matrices\n    // \n    inline const Matrix3 operator +( const Matrix3 & mat ) const;\n\n    // Subtract a 3x3 matrix from another 3x3 matrix\n    // \n    inline const Matrix3 operator -( const Matrix3 & mat ) const;\n\n    // Negate all elements of a 3x3 matrix\n    // \n    inline const Matrix3 operator -( ) const;\n\n    // Multiply a 3x3 matrix by a scalar\n    // \n    inline const Matrix3 operator *( float scalar ) const;\n\n    // Multiply a 3x3 matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( Vector3 vec ) const;\n\n    // Multiply two 3x3 matrices\n    // \n    inline const Matrix3 operator *( const Matrix3 & mat ) const;\n\n    // Perform compound assignment and addition with a 3x3 matrix\n    // \n    inline Matrix3 & operator +=( const Matrix3 & mat );\n\n    // Perform compound assignment and subtraction by a 3x3 matrix\n    // \n    inline Matrix3 & operator -=( const Matrix3 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix3 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a 3x3 matrix\n    // \n    inline Matrix3 & operator *=( const Matrix3 & mat );\n\n    // Construct an identity 3x3 matrix\n    // \n    static inline const Matrix3 identity( );\n\n    // Construct a 3x3 matrix to rotate around the x axis\n    // \n    static inline const Matrix3 rotationX( float radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis\n    // \n    static inline const Matrix3 rotationY( float radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis\n    // \n    static inline const Matrix3 rotationZ( float radians );\n\n    // Construct a 3x3 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix3 rotationZYX( Vector3 radiansXYZ );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix3 rotation( float radians, Vector3 unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix3 rotation( Quat unitQuat );\n\n    // Construct a 3x3 matrix to perform scaling\n    // \n    static inline const Matrix3 scale( Vector3 scaleVec );\n\n};\n// Multiply a 3x3 matrix by a scalar\n// \ninline const Matrix3 operator *( float scalar, const Matrix3 & mat );\n\n// Append (post-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat );\n\n// Multiply two 3x3 matrices per element\n// \ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );\n\n// Compute the absolute value of a 3x3 matrix per element\n// \ninline const Matrix3 absPerElem( const Matrix3 & mat );\n\n// Transpose of a 3x3 matrix\n// \ninline const Matrix3 transpose( const Matrix3 & mat );\n\n// Compute the inverse of a 3x3 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix3 inverse( const Matrix3 & mat );\n\n// Determinant of a 3x3 matrix\n// \ninline float determinant( const Matrix3 & mat );\n\n// Conditionally select between two 3x3 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x3 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat );\n\n// Print a 3x3 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat, const char * name );\n\n#endif\n\n// A 4x4 matrix in array-of-structures format\n//\nclass Matrix4\n{\n    Vector4 mCol0;\n    Vector4 mCol1;\n    Vector4 mCol2;\n    Vector4 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix4( ) { };\n\n    // Copy a 4x4 matrix\n    // \n    inline Matrix4( const Matrix4 & mat );\n\n    // Construct a 4x4 matrix containing the specified columns\n    // \n    inline Matrix4( Vector4 col0, Vector4 col1, Vector4 col2, Vector4 col3 );\n\n    // Construct a 4x4 matrix from a 3x4 transformation matrix\n    // \n    explicit inline Matrix4( const Transform3 & mat );\n\n    // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Matrix4( const Matrix3 & mat, Vector3 translateVec );\n\n    // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Matrix4( Quat unitQuat, Vector3 translateVec );\n\n    // Set all elements of a 4x4 matrix to the same scalar value\n    // \n    explicit inline Matrix4( float scalar );\n\n    // Assign one 4x4 matrix to another\n    // \n    inline Matrix4 & operator =( const Matrix4 & mat );\n\n    // Set the upper-left 3x3 submatrix\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 4x4 matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setTranslation( Vector3 translateVec );\n\n    // Get the translation component of a 4x4 matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol0( Vector4 col0 );\n\n    // Set column 1 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol1( Vector4 col1 );\n\n    // Set column 2 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol2( Vector4 col2 );\n\n    // Set column 3 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol3( Vector4 col3 );\n\n    // Get column 0 of a 4x4 matrix\n    // \n    inline const Vector4 getCol0( ) const;\n\n    // Get column 1 of a 4x4 matrix\n    // \n    inline const Vector4 getCol1( ) const;\n\n    // Get column 2 of a 4x4 matrix\n    // \n    inline const Vector4 getCol2( ) const;\n\n    // Get column 3 of a 4x4 matrix\n    // \n    inline const Vector4 getCol3( ) const;\n\n    // Set the column of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setCol( int col, Vector4 vec );\n\n    // Set the row of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setRow( int row, Vector4 vec );\n\n    // Get the column of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getCol( int col ) const;\n\n    // Get the row of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector4 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector4 operator []( int col ) const;\n\n    // Set the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline Matrix4 & setElem( int col, int row, float val );\n\n    // Get the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline float getElem( int col, int row ) const;\n\n    // Add two 4x4 matrices\n    // \n    inline const Matrix4 operator +( const Matrix4 & mat ) const;\n\n    // Subtract a 4x4 matrix from another 4x4 matrix\n    // \n    inline const Matrix4 operator -( const Matrix4 & mat ) const;\n\n    // Negate all elements of a 4x4 matrix\n    // \n    inline const Matrix4 operator -( ) const;\n\n    // Multiply a 4x4 matrix by a scalar\n    // \n    inline const Matrix4 operator *( float scalar ) const;\n\n    // Multiply a 4x4 matrix by a 4-D vector\n    // \n    inline const Vector4 operator *( Vector4 vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D vector\n    // \n    inline const Vector4 operator *( Vector3 vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D point\n    // \n    inline const Vector4 operator *( Point3 pnt ) const;\n\n    // Multiply two 4x4 matrices\n    // \n    inline const Matrix4 operator *( const Matrix4 & mat ) const;\n\n    // Multiply a 4x4 matrix by a 3x4 transformation matrix\n    // \n    inline const Matrix4 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and addition with a 4x4 matrix\n    // \n    inline Matrix4 & operator +=( const Matrix4 & mat );\n\n    // Perform compound assignment and subtraction by a 4x4 matrix\n    // \n    inline Matrix4 & operator -=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix4 & operator *=( float scalar );\n\n    // Perform compound assignment and multiplication by a 4x4 matrix\n    // \n    inline Matrix4 & operator *=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Matrix4 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 4x4 matrix\n    // \n    static inline const Matrix4 identity( );\n\n    // Construct a 4x4 matrix to rotate around the x axis\n    // \n    static inline const Matrix4 rotationX( float radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis\n    // \n    static inline const Matrix4 rotationY( float radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis\n    // \n    static inline const Matrix4 rotationZ( float radians );\n\n    // Construct a 4x4 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix4 rotationZYX( Vector3 radiansXYZ );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix4 rotation( float radians, Vector3 unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix4 rotation( Quat unitQuat );\n\n    // Construct a 4x4 matrix to perform scaling\n    // \n    static inline const Matrix4 scale( Vector3 scaleVec );\n\n    // Construct a 4x4 matrix to perform translation\n    // \n    static inline const Matrix4 translation( Vector3 translateVec );\n\n    // Construct viewing matrix based on eye position, position looked at, and up direction\n    // \n    static inline const Matrix4 lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec );\n\n    // Construct a perspective projection matrix\n    // \n    static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar );\n\n    // Construct a perspective projection matrix based on frustum\n    // \n    static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar );\n\n    // Construct an orthographic projection matrix\n    // \n    static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar );\n\n};\n// Multiply a 4x4 matrix by a scalar\n// \ninline const Matrix4 operator *( float scalar, const Matrix4 & mat );\n\n// Append (post-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat );\n\n// Multiply two 4x4 matrices per element\n// \ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );\n\n// Compute the absolute value of a 4x4 matrix per element\n// \ninline const Matrix4 absPerElem( const Matrix4 & mat );\n\n// Transpose of a 4x4 matrix\n// \ninline const Matrix4 transpose( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 inverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 affineInverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n// \ninline const Matrix4 orthoInverse( const Matrix4 & mat );\n\n// Determinant of a 4x4 matrix\n// \ninline float determinant( const Matrix4 & mat );\n\n// Conditionally select between two 4x4 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4x4 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat );\n\n// Print a 4x4 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat, const char * name );\n\n#endif\n\n// A 3x4 transformation matrix in array-of-structures format\n//\nclass Transform3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n    Vector3 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Transform3( ) { };\n\n    // Copy a 3x4 transformation matrix\n    // \n    inline Transform3( const Transform3 & tfrm );\n\n    // Construct a 3x4 transformation matrix containing the specified columns\n    // \n    inline Transform3( Vector3 col0, Vector3 col1, Vector3 col2, Vector3 col3 );\n\n    // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Transform3( const Matrix3 & tfrm, Vector3 translateVec );\n\n    // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Transform3( Quat unitQuat, Vector3 translateVec );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value\n    // \n    explicit inline Transform3( float scalar );\n\n    // Assign one 3x4 transformation matrix to another\n    // \n    inline Transform3 & operator =( const Transform3 & tfrm );\n\n    // Set the upper-left 3x3 submatrix\n    // \n    inline Transform3 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // \n    inline Transform3 & setTranslation( Vector3 translateVec );\n\n    // Get the translation component of a 3x4 transformation matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol0( Vector3 col0 );\n\n    // Set column 1 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol1( Vector3 col1 );\n\n    // Set column 2 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol2( Vector3 col2 );\n\n    // Set column 3 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol3( Vector3 col3 );\n\n    // Get column 0 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Get column 3 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol3( ) const;\n\n    // Set the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setCol( int col, Vector3 vec );\n\n    // Set the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setRow( int row, Vector4 vec );\n\n    // Get the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline Transform3 & setElem( int col, int row, float val );\n\n    // Get the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline float getElem( int col, int row ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( Vector3 vec ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D point\n    // \n    inline const Point3 operator *( Point3 pnt ) const;\n\n    // Multiply two 3x4 transformation matrices\n    // \n    inline const Transform3 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Transform3 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 3x4 transformation matrix\n    // \n    static inline const Transform3 identity( );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis\n    // \n    static inline const Transform3 rotationX( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis\n    // \n    static inline const Transform3 rotationY( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis\n    // \n    static inline const Transform3 rotationZ( float radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n    // \n    static inline const Transform3 rotationZYX( Vector3 radiansXYZ );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Transform3 rotation( float radians, Vector3 unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Transform3 rotation( Quat unitQuat );\n\n    // Construct a 3x4 transformation matrix to perform scaling\n    // \n    static inline const Transform3 scale( Vector3 scaleVec );\n\n    // Construct a 3x4 transformation matrix to perform translation\n    // \n    static inline const Transform3 translation( Vector3 translateVec );\n\n};\n// Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm );\n\n// Multiply two 3x4 transformation matrices per element\n// \ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );\n\n// Compute the absolute value of a 3x4 transformation matrix per element\n// \ninline const Transform3 absPerElem( const Transform3 & tfrm );\n\n// Inverse of a 3x4 transformation matrix\n// NOTE: \n// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n// \ninline const Transform3 inverse( const Transform3 & tfrm );\n\n// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n// \ninline const Transform3 orthoInverse( const Transform3 & tfrm );\n\n// Conditionally select between two 3x4 transformation matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x4 transformation matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm );\n\n// Print a 3x4 transformation matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm, const char * name );\n\n#endif\n\n} // namespace Aos\n} // namespace Vectormath\n\n#include \"vec_aos.h\"\n#include \"quat_aos.h\"\n#include \"mat_aos.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/spu/cpp/vectormath_soa.h",
    "content": "/*\n   Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.\n   All rights reserved.\n\n   Redistribution and use in source and binary forms,\n   with or without modification, are permitted provided that the\n   following conditions are met:\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of the Sony Computer Entertainment Inc nor the names\n      of its contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n   POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef _VECTORMATH_SOA_CPP_SPU_H\n#define _VECTORMATH_SOA_CPP_SPU_H\n\n#include <math.h>\n#include <spu_intrinsics.h>\n#include \"floatInVec.h\"\n#include \"boolInVec.h\"\n#include \"vectormath_aos.h\"\n#include <stdio.h>\n\n#ifdef _VECTORMATH_DEBUG\n#endif\n\nnamespace Vectormath {\n\nnamespace Soa {\n\n//-----------------------------------------------------------------------------\n// Forward Declarations\n//\n\nclass Vector3;\nclass Vector4;\nclass Point3;\nclass Quat;\nclass Matrix3;\nclass Matrix4;\nclass Transform3;\n\n// A set of four 3-D vectors in structure-of-arrays format\n//\nclass Vector3\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector3( ) { };\n\n    // Copy a 3-D vector\n    // \n    inline Vector3( const Vector3 & vec );\n\n    // Construct a 3-D vector from x, y, and z elements\n    // \n    inline Vector3( vec_float4 x, vec_float4 y, vec_float4 z );\n\n    // Copy elements from a 3-D point into a 3-D vector\n    // \n    explicit inline Vector3( const Point3 & pnt );\n\n    // Set all elements of a 3-D vector to the same scalar value\n    // \n    explicit inline Vector3( vec_float4 scalar );\n\n    // Replicate an AoS 3-D vector\n    // \n    inline Vector3( Aos::Vector3 vec );\n\n    // Insert four AoS 3-D vectors\n    // \n    inline Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 );\n\n    // Extract four AoS 3-D vectors\n    // \n    inline void get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const;\n\n    // Assign one 3-D vector to another\n    // \n    inline Vector3 & operator =( const Vector3 & vec );\n\n    // Set the x element of a 3-D vector\n    // \n    inline Vector3 & setX( vec_float4 x );\n\n    // Set the y element of a 3-D vector\n    // \n    inline Vector3 & setY( vec_float4 y );\n\n    // Set the z element of a 3-D vector\n    // \n    inline Vector3 & setZ( vec_float4 z );\n\n    // Get the x element of a 3-D vector\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a 3-D vector\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a 3-D vector\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D vector by index\n    // \n    inline Vector3 & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, or z element of a 3-D vector by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Add two 3-D vectors\n    // \n    inline const Vector3 operator +( const Vector3 & vec ) const;\n\n    // Subtract a 3-D vector from another 3-D vector\n    // \n    inline const Vector3 operator -( const Vector3 & vec ) const;\n\n    // Add a 3-D vector to a 3-D point\n    // \n    inline const Point3 operator +( const Point3 & pnt ) const;\n\n    // Multiply a 3-D vector by a scalar\n    // \n    inline const Vector3 operator *( vec_float4 scalar ) const;\n\n    // Divide a 3-D vector by a scalar\n    // \n    inline const Vector3 operator /( vec_float4 scalar ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Vector3 & operator +=( const Vector3 & vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Vector3 & operator -=( const Vector3 & vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector3 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector3 & operator /=( vec_float4 scalar );\n\n    // Negate all elements of a 3-D vector\n    // \n    inline const Vector3 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector3 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector3 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector3 zAxis( );\n\n};\n\n// Multiply a 3-D vector by a scalar\n// \ninline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec );\n\n// Multiply two 3-D vectors per element\n// \ninline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Divide two 3-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Compute the reciprocal of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector3 recipPerElem( const Vector3 & vec );\n\n// Compute the square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector3 sqrtPerElem( const Vector3 & vec );\n\n// Compute the reciprocal square root of a 3-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector3 rsqrtPerElem( const Vector3 & vec );\n\n// Compute the absolute value of a 3-D vector per element\n// \ninline const Vector3 absPerElem( const Vector3 & vec );\n\n// Copy sign from one 3-D vector to another, per element\n// \ninline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Maximum of two 3-D vectors per element\n// \ninline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Minimum of two 3-D vectors per element\n// \ninline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Maximum element of a 3-D vector\n// \ninline vec_float4 maxElem( const Vector3 & vec );\n\n// Minimum element of a 3-D vector\n// \ninline vec_float4 minElem( const Vector3 & vec );\n\n// Compute the sum of all elements of a 3-D vector\n// \ninline vec_float4 sum( const Vector3 & vec );\n\n// Compute the dot product of two 3-D vectors\n// \ninline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Compute the square of the length of a 3-D vector\n// \ninline vec_float4 lengthSqr( const Vector3 & vec );\n\n// Compute the length of a 3-D vector\n// \ninline vec_float4 length( const Vector3 & vec );\n\n// Normalize a 3-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector3 normalize( const Vector3 & vec );\n\n// Compute cross product of two 3-D vectors\n// \ninline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Outer product of two 3-D vectors\n// \ninline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 );\n\n// Pre-multiply a row vector by a 3x3 matrix\n// \ninline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat );\n\n// Cross-product matrix of a 3-D vector\n// \ninline const Matrix3 crossMatrix( const Vector3 & vec );\n\n// Create cross-product matrix and multiply\n// NOTE: \n// Faster than separately creating a cross-product matrix and multiplying.\n// \ninline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat );\n\n// Linear interpolation between two 3-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 );\n\n// Spherical linear interpolation between two 3-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 );\n\n// Conditionally select between two 3-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 );\n\n// Load four three-float 3-D vectors, stored in three quadwords\n// \ninline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads );\n\n// Store four slots of an SoA 3-D vector in three quadwords\n// \ninline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads );\n\n// Store eight slots of two SoA 3-D vectors as half-floats\n// \ninline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector3 & vec );\n\n// Print a 3-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector3 & vec, const char * name );\n\n#endif\n\n// A set of four 4-D vectors in structure-of-arrays format\n//\nclass Vector4\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n    vec_float4 mW;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Vector4( ) { };\n\n    // Copy a 4-D vector\n    // \n    inline Vector4( const Vector4 & vec );\n\n    // Construct a 4-D vector from x, y, z, and w elements\n    // \n    inline Vector4( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n    // Construct a 4-D vector from a 3-D vector and a scalar\n    // \n    inline Vector4( const Vector3 & xyz, vec_float4 w );\n\n    // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0\n    // \n    explicit inline Vector4( const Vector3 & vec );\n\n    // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1\n    // \n    explicit inline Vector4( const Point3 & pnt );\n\n    // Copy elements from a quaternion into a 4-D vector\n    // \n    explicit inline Vector4( const Quat & quat );\n\n    // Set all elements of a 4-D vector to the same scalar value\n    // \n    explicit inline Vector4( vec_float4 scalar );\n\n    // Replicate an AoS 4-D vector\n    // \n    inline Vector4( Aos::Vector4 vec );\n\n    // Insert four AoS 4-D vectors\n    // \n    inline Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 );\n\n    // Extract four AoS 4-D vectors\n    // \n    inline void get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const;\n\n    // Assign one 4-D vector to another\n    // \n    inline Vector4 & operator =( const Vector4 & vec );\n\n    // Set the x, y, and z elements of a 4-D vector\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Vector4 & setXYZ( const Vector3 & vec );\n\n    // Get the x, y, and z elements of a 4-D vector\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a 4-D vector\n    // \n    inline Vector4 & setX( vec_float4 x );\n\n    // Set the y element of a 4-D vector\n    // \n    inline Vector4 & setY( vec_float4 y );\n\n    // Set the z element of a 4-D vector\n    // \n    inline Vector4 & setZ( vec_float4 z );\n\n    // Set the w element of a 4-D vector\n    // \n    inline Vector4 & setW( vec_float4 w );\n\n    // Get the x element of a 4-D vector\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a 4-D vector\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a 4-D vector\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Get the w element of a 4-D vector\n    // \n    inline vec_float4 getW( ) const;\n\n    // Set an x, y, z, or w element of a 4-D vector by index\n    // \n    inline Vector4 & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, z, or w element of a 4-D vector by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Add two 4-D vectors\n    // \n    inline const Vector4 operator +( const Vector4 & vec ) const;\n\n    // Subtract a 4-D vector from another 4-D vector\n    // \n    inline const Vector4 operator -( const Vector4 & vec ) const;\n\n    // Multiply a 4-D vector by a scalar\n    // \n    inline const Vector4 operator *( vec_float4 scalar ) const;\n\n    // Divide a 4-D vector by a scalar\n    // \n    inline const Vector4 operator /( vec_float4 scalar ) const;\n\n    // Perform compound assignment and addition with a 4-D vector\n    // \n    inline Vector4 & operator +=( const Vector4 & vec );\n\n    // Perform compound assignment and subtraction by a 4-D vector\n    // \n    inline Vector4 & operator -=( const Vector4 & vec );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Vector4 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Vector4 & operator /=( vec_float4 scalar );\n\n    // Negate all elements of a 4-D vector\n    // \n    inline const Vector4 operator -( ) const;\n\n    // Construct x axis\n    // \n    static inline const Vector4 xAxis( );\n\n    // Construct y axis\n    // \n    static inline const Vector4 yAxis( );\n\n    // Construct z axis\n    // \n    static inline const Vector4 zAxis( );\n\n    // Construct w axis\n    // \n    static inline const Vector4 wAxis( );\n\n};\n\n// Multiply a 4-D vector by a scalar\n// \ninline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec );\n\n// Multiply two 4-D vectors per element\n// \ninline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Divide two 4-D vectors per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Compute the reciprocal of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Vector4 recipPerElem( const Vector4 & vec );\n\n// Compute the square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Vector4 sqrtPerElem( const Vector4 & vec );\n\n// Compute the reciprocal square root of a 4-D vector per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Vector4 rsqrtPerElem( const Vector4 & vec );\n\n// Compute the absolute value of a 4-D vector per element\n// \ninline const Vector4 absPerElem( const Vector4 & vec );\n\n// Copy sign from one 4-D vector to another, per element\n// \ninline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Maximum of two 4-D vectors per element\n// \ninline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Minimum of two 4-D vectors per element\n// \ninline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Maximum element of a 4-D vector\n// \ninline vec_float4 maxElem( const Vector4 & vec );\n\n// Minimum element of a 4-D vector\n// \ninline vec_float4 minElem( const Vector4 & vec );\n\n// Compute the sum of all elements of a 4-D vector\n// \ninline vec_float4 sum( const Vector4 & vec );\n\n// Compute the dot product of two 4-D vectors\n// \ninline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Compute the square of the length of a 4-D vector\n// \ninline vec_float4 lengthSqr( const Vector4 & vec );\n\n// Compute the length of a 4-D vector\n// \ninline vec_float4 length( const Vector4 & vec );\n\n// Normalize a 4-D vector\n// NOTE: \n// The result is unpredictable when all elements of vec are at or near zero.\n// \ninline const Vector4 normalize( const Vector4 & vec );\n\n// Outer product of two 4-D vectors\n// \ninline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 );\n\n// Linear interpolation between two 4-D vectors\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 );\n\n// Spherical linear interpolation between two 4-D vectors\n// NOTE: \n// The result is unpredictable if the vectors point in opposite directions.\n// Does not clamp t between 0 and 1.\n// \ninline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 );\n\n// Conditionally select between two 4-D vectors\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 );\n\n// Store four slots of an SoA 4-D vector as half-floats\n// \ninline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4-D vector\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector4 & vec );\n\n// Print a 4-D vector and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Vector4 & vec, const char * name );\n\n#endif\n\n// A set of four 3-D points in structure-of-arrays format\n//\nclass Point3\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Point3( ) { };\n\n    // Copy a 3-D point\n    // \n    inline Point3( const Point3 & pnt );\n\n    // Construct a 3-D point from x, y, and z elements\n    // \n    inline Point3( vec_float4 x, vec_float4 y, vec_float4 z );\n\n    // Copy elements from a 3-D vector into a 3-D point\n    // \n    explicit inline Point3( const Vector3 & vec );\n\n    // Set all elements of a 3-D point to the same scalar value\n    // \n    explicit inline Point3( vec_float4 scalar );\n\n    // Replicate an AoS 3-D point\n    // \n    inline Point3( Aos::Point3 pnt );\n\n    // Insert four AoS 3-D points\n    // \n    inline Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 );\n\n    // Extract four AoS 3-D points\n    // \n    inline void get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const;\n\n    // Assign one 3-D point to another\n    // \n    inline Point3 & operator =( const Point3 & pnt );\n\n    // Set the x element of a 3-D point\n    // \n    inline Point3 & setX( vec_float4 x );\n\n    // Set the y element of a 3-D point\n    // \n    inline Point3 & setY( vec_float4 y );\n\n    // Set the z element of a 3-D point\n    // \n    inline Point3 & setZ( vec_float4 z );\n\n    // Get the x element of a 3-D point\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a 3-D point\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a 3-D point\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Set an x, y, or z element of a 3-D point by index\n    // \n    inline Point3 & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, or z element of a 3-D point by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Subtract a 3-D point from another 3-D point\n    // \n    inline const Vector3 operator -( const Point3 & pnt ) const;\n\n    // Add a 3-D point to a 3-D vector\n    // \n    inline const Point3 operator +( const Vector3 & vec ) const;\n\n    // Subtract a 3-D vector from a 3-D point\n    // \n    inline const Point3 operator -( const Vector3 & vec ) const;\n\n    // Perform compound assignment and addition with a 3-D vector\n    // \n    inline Point3 & operator +=( const Vector3 & vec );\n\n    // Perform compound assignment and subtraction by a 3-D vector\n    // \n    inline Point3 & operator -=( const Vector3 & vec );\n\n};\n\n// Multiply two 3-D points per element\n// \ninline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Divide two 3-D points per element\n// NOTE: \n// Floating-point behavior matches standard library function divf4.\n// \ninline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Compute the reciprocal of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function recipf4.\n// \ninline const Point3 recipPerElem( const Point3 & pnt );\n\n// Compute the square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function sqrtf4.\n// \ninline const Point3 sqrtPerElem( const Point3 & pnt );\n\n// Compute the reciprocal square root of a 3-D point per element\n// NOTE: \n// Floating-point behavior matches standard library function rsqrtf4.\n// \ninline const Point3 rsqrtPerElem( const Point3 & pnt );\n\n// Compute the absolute value of a 3-D point per element\n// \ninline const Point3 absPerElem( const Point3 & pnt );\n\n// Copy sign from one 3-D point to another, per element\n// \ninline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Maximum of two 3-D points per element\n// \ninline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Minimum of two 3-D points per element\n// \ninline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Maximum element of a 3-D point\n// \ninline vec_float4 maxElem( const Point3 & pnt );\n\n// Minimum element of a 3-D point\n// \ninline vec_float4 minElem( const Point3 & pnt );\n\n// Compute the sum of all elements of a 3-D point\n// \ninline vec_float4 sum( const Point3 & pnt );\n\n// Apply uniform scale to a 3-D point\n// \ninline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal );\n\n// Apply non-uniform scale to a 3-D point\n// \ninline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec );\n\n// Scalar projection of a 3-D point on a unit-length 3-D vector\n// \ninline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec );\n\n// Compute the square of the distance of a 3-D point from the coordinate-system origin\n// \ninline vec_float4 distSqrFromOrigin( const Point3 & pnt );\n\n// Compute the distance of a 3-D point from the coordinate-system origin\n// \ninline vec_float4 distFromOrigin( const Point3 & pnt );\n\n// Compute the square of the distance between two 3-D points\n// \ninline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Compute the distance between two 3-D points\n// \ninline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 );\n\n// Linear interpolation between two 3-D points\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 );\n\n// Conditionally select between two 3-D points\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 );\n\n// Load four three-float 3-D points, stored in three quadwords\n// \ninline void loadXYZArray( Point3 & pnt, const vec_float4 * threeQuads );\n\n// Store four slots of an SoA 3-D point in three quadwords\n// \ninline void storeXYZArray( const Point3 & pnt, vec_float4 * threeQuads );\n\n// Store eight slots of two SoA 3-D points as half-floats\n// \ninline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3-D point\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Point3 & pnt );\n\n// Print a 3-D point and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Point3 & pnt, const char * name );\n\n#endif\n\n// A set of four quaternions in structure-of-arrays format\n//\nclass Quat\n{\n    typedef vec_float4 vec_float4_t;\n    vec_float4 mX;\n    vec_float4 mY;\n    vec_float4 mZ;\n    vec_float4 mW;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Quat( ) { };\n\n    // Copy a quaternion\n    // \n    inline Quat( const Quat & quat );\n\n    // Construct a quaternion from x, y, z, and w elements\n    // \n    inline Quat( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w );\n\n    // Construct a quaternion from a 3-D vector and a scalar\n    // \n    inline Quat( const Vector3 & xyz, vec_float4 w );\n\n    // Copy elements from a 4-D vector into a quaternion\n    // \n    explicit inline Quat( const Vector4 & vec );\n\n    // Convert a rotation matrix to a unit-length quaternion\n    // \n    explicit inline Quat( const Matrix3 & rotMat );\n\n    // Set all elements of a quaternion to the same scalar value\n    // \n    explicit inline Quat( vec_float4 scalar );\n\n    // Replicate an AoS quaternion\n    // \n    inline Quat( Aos::Quat quat );\n\n    // Insert four AoS quaternions\n    // \n    inline Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 );\n\n    // Extract four AoS quaternions\n    // \n    inline void get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const;\n\n    // Assign one quaternion to another\n    // \n    inline Quat & operator =( const Quat & quat );\n\n    // Set the x, y, and z elements of a quaternion\n    // NOTE: \n    // This function does not change the w element.\n    // \n    inline Quat & setXYZ( const Vector3 & vec );\n\n    // Get the x, y, and z elements of a quaternion\n    // \n    inline const Vector3 getXYZ( ) const;\n\n    // Set the x element of a quaternion\n    // \n    inline Quat & setX( vec_float4 x );\n\n    // Set the y element of a quaternion\n    // \n    inline Quat & setY( vec_float4 y );\n\n    // Set the z element of a quaternion\n    // \n    inline Quat & setZ( vec_float4 z );\n\n    // Set the w element of a quaternion\n    // \n    inline Quat & setW( vec_float4 w );\n\n    // Get the x element of a quaternion\n    // \n    inline vec_float4 getX( ) const;\n\n    // Get the y element of a quaternion\n    // \n    inline vec_float4 getY( ) const;\n\n    // Get the z element of a quaternion\n    // \n    inline vec_float4 getZ( ) const;\n\n    // Get the w element of a quaternion\n    // \n    inline vec_float4 getW( ) const;\n\n    // Set an x, y, z, or w element of a quaternion by index\n    // \n    inline Quat & setElem( int idx, vec_float4 value );\n\n    // Get an x, y, z, or w element of a quaternion by index\n    // \n    inline vec_float4 getElem( int idx ) const;\n\n    // Subscripting operator to set or get an element\n    // \n    inline vec_float4_t & operator []( int idx );\n\n    // Subscripting operator to get an element\n    // \n    inline vec_float4 operator []( int idx ) const;\n\n    // Add two quaternions\n    // \n    inline const Quat operator +( const Quat & quat ) const;\n\n    // Subtract a quaternion from another quaternion\n    // \n    inline const Quat operator -( const Quat & quat ) const;\n\n    // Multiply two quaternions\n    // \n    inline const Quat operator *( const Quat & quat ) const;\n\n    // Multiply a quaternion by a scalar\n    // \n    inline const Quat operator *( vec_float4 scalar ) const;\n\n    // Divide a quaternion by a scalar\n    // \n    inline const Quat operator /( vec_float4 scalar ) const;\n\n    // Perform compound assignment and addition with a quaternion\n    // \n    inline Quat & operator +=( const Quat & quat );\n\n    // Perform compound assignment and subtraction by a quaternion\n    // \n    inline Quat & operator -=( const Quat & quat );\n\n    // Perform compound assignment and multiplication by a quaternion\n    // \n    inline Quat & operator *=( const Quat & quat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Quat & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and division by a scalar\n    // \n    inline Quat & operator /=( vec_float4 scalar );\n\n    // Negate all elements of a quaternion\n    // \n    inline const Quat operator -( ) const;\n\n    // Construct an identity quaternion\n    // \n    static inline const Quat identity( );\n\n    // Construct a quaternion to rotate between two unit-length 3-D vectors\n    // NOTE: \n    // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.\n    // \n    static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 );\n\n    // Construct a quaternion to rotate around a unit-length 3-D vector\n    // \n    static inline const Quat rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a quaternion to rotate around the x axis\n    // \n    static inline const Quat rotationX( vec_float4 radians );\n\n    // Construct a quaternion to rotate around the y axis\n    // \n    static inline const Quat rotationY( vec_float4 radians );\n\n    // Construct a quaternion to rotate around the z axis\n    // \n    static inline const Quat rotationZ( vec_float4 radians );\n\n};\n\n// Multiply a quaternion by a scalar\n// \ninline const Quat operator *( vec_float4 scalar, const Quat & quat );\n\n// Compute the conjugate of a quaternion\n// \ninline const Quat conj( const Quat & quat );\n\n// Use a unit-length quaternion to rotate a 3-D vector\n// \ninline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec );\n\n// Compute the dot product of two quaternions\n// \ninline vec_float4 dot( const Quat & quat0, const Quat & quat1 );\n\n// Compute the norm of a quaternion\n// \ninline vec_float4 norm( const Quat & quat );\n\n// Compute the length of a quaternion\n// \ninline vec_float4 length( const Quat & quat );\n\n// Normalize a quaternion\n// NOTE: \n// The result is unpredictable when all elements of quat are at or near zero.\n// \ninline const Quat normalize( const Quat & quat );\n\n// Linear interpolation between two quaternions\n// NOTE: \n// Does not clamp t between 0 and 1.\n// \ninline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 );\n\n// Spherical linear interpolation between two quaternions\n// NOTE: \n// Interpolates along the shortest path between orientations.\n// Does not clamp t between 0 and 1.\n// \ninline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 );\n\n// Spherical quadrangle interpolation\n// \ninline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 );\n\n// Conditionally select between two quaternions\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a quaternion\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Quat & quat );\n\n// Print a quaternion and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Quat & quat, const char * name );\n\n#endif\n\n// A set of four 3x3 matrices in structure-of-arrays format\n//\nclass Matrix3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix3( ) { };\n\n    // Copy a 3x3 matrix\n    // \n    inline Matrix3( const Matrix3 & mat );\n\n    // Construct a 3x3 matrix containing the specified columns\n    // \n    inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 );\n\n    // Construct a 3x3 rotation matrix from a unit-length quaternion\n    // \n    explicit inline Matrix3( const Quat & unitQuat );\n\n    // Set all elements of a 3x3 matrix to the same scalar value\n    // \n    explicit inline Matrix3( vec_float4 scalar );\n\n    // Replicate an AoS 3x3 matrix\n    // \n    inline Matrix3( const Aos::Matrix3 & mat );\n\n    // Insert four AoS 3x3 matrices\n    // \n    inline Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 );\n\n    // Extract four AoS 3x3 matrices\n    // \n    inline void get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const;\n\n    // Assign one 3x3 matrix to another\n    // \n    inline Matrix3 & operator =( const Matrix3 & mat );\n\n    // Set column 0 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol0( const Vector3 & col0 );\n\n    // Set column 1 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol1( const Vector3 & col1 );\n\n    // Set column 2 of a 3x3 matrix\n    // \n    inline Matrix3 & setCol2( const Vector3 & col2 );\n\n    // Get column 0 of a 3x3 matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x3 matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x3 matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Set the column of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setCol( int col, const Vector3 & vec );\n\n    // Set the row of a 3x3 matrix referred to by the specified index\n    // \n    inline Matrix3 & setRow( int row, const Vector3 & vec );\n\n    // Get the column of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x3 matrix referred to by the specified index\n    // \n    inline const Vector3 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline Matrix3 & setElem( int col, int row, vec_float4 val );\n\n    // Get the element of a 3x3 matrix referred to by column and row indices\n    // \n    inline vec_float4 getElem( int col, int row ) const;\n\n    // Add two 3x3 matrices\n    // \n    inline const Matrix3 operator +( const Matrix3 & mat ) const;\n\n    // Subtract a 3x3 matrix from another 3x3 matrix\n    // \n    inline const Matrix3 operator -( const Matrix3 & mat ) const;\n\n    // Negate all elements of a 3x3 matrix\n    // \n    inline const Matrix3 operator -( ) const;\n\n    // Multiply a 3x3 matrix by a scalar\n    // \n    inline const Matrix3 operator *( vec_float4 scalar ) const;\n\n    // Multiply a 3x3 matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( const Vector3 & vec ) const;\n\n    // Multiply two 3x3 matrices\n    // \n    inline const Matrix3 operator *( const Matrix3 & mat ) const;\n\n    // Perform compound assignment and addition with a 3x3 matrix\n    // \n    inline Matrix3 & operator +=( const Matrix3 & mat );\n\n    // Perform compound assignment and subtraction by a 3x3 matrix\n    // \n    inline Matrix3 & operator -=( const Matrix3 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix3 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and multiplication by a 3x3 matrix\n    // \n    inline Matrix3 & operator *=( const Matrix3 & mat );\n\n    // Construct an identity 3x3 matrix\n    // \n    static inline const Matrix3 identity( );\n\n    // Construct a 3x3 matrix to rotate around the x axis\n    // \n    static inline const Matrix3 rotationX( vec_float4 radians );\n\n    // Construct a 3x3 matrix to rotate around the y axis\n    // \n    static inline const Matrix3 rotationY( vec_float4 radians );\n\n    // Construct a 3x3 matrix to rotate around the z axis\n    // \n    static inline const Matrix3 rotationZ( vec_float4 radians );\n\n    // Construct a 3x3 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 3x3 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix3 rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix3 rotation( const Quat & unitQuat );\n\n    // Construct a 3x3 matrix to perform scaling\n    // \n    static inline const Matrix3 scale( const Vector3 & scaleVec );\n\n};\n// Multiply a 3x3 matrix by a scalar\n// \ninline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat );\n\n// Append (post-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x3 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat );\n\n// Multiply two 3x3 matrices per element\n// \ninline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 );\n\n// Compute the absolute value of a 3x3 matrix per element\n// \ninline const Matrix3 absPerElem( const Matrix3 & mat );\n\n// Transpose of a 3x3 matrix\n// \ninline const Matrix3 transpose( const Matrix3 & mat );\n\n// Compute the inverse of a 3x3 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix3 inverse( const Matrix3 & mat );\n\n// Determinant of a 3x3 matrix\n// \ninline vec_float4 determinant( const Matrix3 & mat );\n\n// Conditionally select between two 3x3 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x3 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat );\n\n// Print a 3x3 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix3 & mat, const char * name );\n\n#endif\n\n// A set of four 4x4 matrices in structure-of-arrays format\n//\nclass Matrix4\n{\n    Vector4 mCol0;\n    Vector4 mCol1;\n    Vector4 mCol2;\n    Vector4 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Matrix4( ) { };\n\n    // Copy a 4x4 matrix\n    // \n    inline Matrix4( const Matrix4 & mat );\n\n    // Construct a 4x4 matrix containing the specified columns\n    // \n    inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 );\n\n    // Construct a 4x4 matrix from a 3x4 transformation matrix\n    // \n    explicit inline Matrix4( const Transform3 & mat );\n\n    // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec );\n\n    // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec );\n\n    // Set all elements of a 4x4 matrix to the same scalar value\n    // \n    explicit inline Matrix4( vec_float4 scalar );\n\n    // Replicate an AoS 4x4 matrix\n    // \n    inline Matrix4( const Aos::Matrix4 & mat );\n\n    // Insert four AoS 4x4 matrices\n    // \n    inline Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 );\n\n    // Extract four AoS 4x4 matrices\n    // \n    inline void get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const;\n\n    // Assign one 4x4 matrix to another\n    // \n    inline Matrix4 & operator =( const Matrix4 & mat );\n\n    // Set the upper-left 3x3 submatrix\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 4x4 matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // NOTE: \n    // This function does not change the bottom row elements.\n    // \n    inline Matrix4 & setTranslation( const Vector3 & translateVec );\n\n    // Get the translation component of a 4x4 matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol0( const Vector4 & col0 );\n\n    // Set column 1 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol1( const Vector4 & col1 );\n\n    // Set column 2 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol2( const Vector4 & col2 );\n\n    // Set column 3 of a 4x4 matrix\n    // \n    inline Matrix4 & setCol3( const Vector4 & col3 );\n\n    // Get column 0 of a 4x4 matrix\n    // \n    inline const Vector4 getCol0( ) const;\n\n    // Get column 1 of a 4x4 matrix\n    // \n    inline const Vector4 getCol1( ) const;\n\n    // Get column 2 of a 4x4 matrix\n    // \n    inline const Vector4 getCol2( ) const;\n\n    // Get column 3 of a 4x4 matrix\n    // \n    inline const Vector4 getCol3( ) const;\n\n    // Set the column of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setCol( int col, const Vector4 & vec );\n\n    // Set the row of a 4x4 matrix referred to by the specified index\n    // \n    inline Matrix4 & setRow( int row, const Vector4 & vec );\n\n    // Get the column of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getCol( int col ) const;\n\n    // Get the row of a 4x4 matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector4 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector4 operator []( int col ) const;\n\n    // Set the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline Matrix4 & setElem( int col, int row, vec_float4 val );\n\n    // Get the element of a 4x4 matrix referred to by column and row indices\n    // \n    inline vec_float4 getElem( int col, int row ) const;\n\n    // Add two 4x4 matrices\n    // \n    inline const Matrix4 operator +( const Matrix4 & mat ) const;\n\n    // Subtract a 4x4 matrix from another 4x4 matrix\n    // \n    inline const Matrix4 operator -( const Matrix4 & mat ) const;\n\n    // Negate all elements of a 4x4 matrix\n    // \n    inline const Matrix4 operator -( ) const;\n\n    // Multiply a 4x4 matrix by a scalar\n    // \n    inline const Matrix4 operator *( vec_float4 scalar ) const;\n\n    // Multiply a 4x4 matrix by a 4-D vector\n    // \n    inline const Vector4 operator *( const Vector4 & vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D vector\n    // \n    inline const Vector4 operator *( const Vector3 & vec ) const;\n\n    // Multiply a 4x4 matrix by a 3-D point\n    // \n    inline const Vector4 operator *( const Point3 & pnt ) const;\n\n    // Multiply two 4x4 matrices\n    // \n    inline const Matrix4 operator *( const Matrix4 & mat ) const;\n\n    // Multiply a 4x4 matrix by a 3x4 transformation matrix\n    // \n    inline const Matrix4 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and addition with a 4x4 matrix\n    // \n    inline Matrix4 & operator +=( const Matrix4 & mat );\n\n    // Perform compound assignment and subtraction by a 4x4 matrix\n    // \n    inline Matrix4 & operator -=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a scalar\n    // \n    inline Matrix4 & operator *=( vec_float4 scalar );\n\n    // Perform compound assignment and multiplication by a 4x4 matrix\n    // \n    inline Matrix4 & operator *=( const Matrix4 & mat );\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Matrix4 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 4x4 matrix\n    // \n    static inline const Matrix4 identity( );\n\n    // Construct a 4x4 matrix to rotate around the x axis\n    // \n    static inline const Matrix4 rotationX( vec_float4 radians );\n\n    // Construct a 4x4 matrix to rotate around the y axis\n    // \n    static inline const Matrix4 rotationY( vec_float4 radians );\n\n    // Construct a 4x4 matrix to rotate around the z axis\n    // \n    static inline const Matrix4 rotationZ( vec_float4 radians );\n\n    // Construct a 4x4 matrix to rotate around the x, y, and z axes\n    // \n    static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 4x4 matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Matrix4 rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Matrix4 rotation( const Quat & unitQuat );\n\n    // Construct a 4x4 matrix to perform scaling\n    // \n    static inline const Matrix4 scale( const Vector3 & scaleVec );\n\n    // Construct a 4x4 matrix to perform translation\n    // \n    static inline const Matrix4 translation( const Vector3 & translateVec );\n\n    // Construct viewing matrix based on eye position, position looked at, and up direction\n    // \n    static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec );\n\n    // Construct a perspective projection matrix\n    // \n    static inline const Matrix4 perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar );\n\n    // Construct a perspective projection matrix based on frustum\n    // \n    static inline const Matrix4 frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n    // Construct an orthographic projection matrix\n    // \n    static inline const Matrix4 orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar );\n\n};\n// Multiply a 4x4 matrix by a scalar\n// \ninline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat );\n\n// Append (post-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 4x4 matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat );\n\n// Multiply two 4x4 matrices per element\n// \ninline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 );\n\n// Compute the absolute value of a 4x4 matrix per element\n// \ninline const Matrix4 absPerElem( const Matrix4 & mat );\n\n// Transpose of a 4x4 matrix\n// \ninline const Matrix4 transpose( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix\n// NOTE: \n// Result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 inverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.\n// \ninline const Matrix4 affineInverse( const Matrix4 & mat );\n\n// Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.\n// \ninline const Matrix4 orthoInverse( const Matrix4 & mat );\n\n// Determinant of a 4x4 matrix\n// \ninline vec_float4 determinant( const Matrix4 & mat );\n\n// Conditionally select between two 4x4 matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 4x4 matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat );\n\n// Print a 4x4 matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Matrix4 & mat, const char * name );\n\n#endif\n\n// A set of four 3x4 transformation matrices in structure-of-arrays format\n//\nclass Transform3\n{\n    Vector3 mCol0;\n    Vector3 mCol1;\n    Vector3 mCol2;\n    Vector3 mCol3;\n\npublic:\n    // Default constructor; does no initialization\n    // \n    inline Transform3( ) { };\n\n    // Copy a 3x4 transformation matrix\n    // \n    inline Transform3( const Transform3 & tfrm );\n\n    // Construct a 3x4 transformation matrix containing the specified columns\n    // \n    inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 );\n\n    // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector\n    // \n    inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec );\n\n    // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector\n    // \n    inline Transform3( const Quat & unitQuat, const Vector3 & translateVec );\n\n    // Set all elements of a 3x4 transformation matrix to the same scalar value\n    // \n    explicit inline Transform3( vec_float4 scalar );\n\n    // Replicate an AoS 3x4 transformation matrix\n    // \n    inline Transform3( const Aos::Transform3 & tfrm );\n\n    // Insert four AoS 3x4 transformation matrices\n    // \n    inline Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 );\n\n    // Extract four AoS 3x4 transformation matrices\n    // \n    inline void get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const;\n\n    // Assign one 3x4 transformation matrix to another\n    // \n    inline Transform3 & operator =( const Transform3 & tfrm );\n\n    // Set the upper-left 3x3 submatrix\n    // \n    inline Transform3 & setUpper3x3( const Matrix3 & mat3 );\n\n    // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix\n    // \n    inline const Matrix3 getUpper3x3( ) const;\n\n    // Set translation component\n    // \n    inline Transform3 & setTranslation( const Vector3 & translateVec );\n\n    // Get the translation component of a 3x4 transformation matrix\n    // \n    inline const Vector3 getTranslation( ) const;\n\n    // Set column 0 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol0( const Vector3 & col0 );\n\n    // Set column 1 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol1( const Vector3 & col1 );\n\n    // Set column 2 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol2( const Vector3 & col2 );\n\n    // Set column 3 of a 3x4 transformation matrix\n    // \n    inline Transform3 & setCol3( const Vector3 & col3 );\n\n    // Get column 0 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol0( ) const;\n\n    // Get column 1 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol1( ) const;\n\n    // Get column 2 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol2( ) const;\n\n    // Get column 3 of a 3x4 transformation matrix\n    // \n    inline const Vector3 getCol3( ) const;\n\n    // Set the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setCol( int col, const Vector3 & vec );\n\n    // Set the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline Transform3 & setRow( int row, const Vector4 & vec );\n\n    // Get the column of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector3 getCol( int col ) const;\n\n    // Get the row of a 3x4 transformation matrix referred to by the specified index\n    // \n    inline const Vector4 getRow( int row ) const;\n\n    // Subscripting operator to set or get a column\n    // \n    inline Vector3 & operator []( int col );\n\n    // Subscripting operator to get a column\n    // \n    inline const Vector3 operator []( int col ) const;\n\n    // Set the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline Transform3 & setElem( int col, int row, vec_float4 val );\n\n    // Get the element of a 3x4 transformation matrix referred to by column and row indices\n    // \n    inline vec_float4 getElem( int col, int row ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D vector\n    // \n    inline const Vector3 operator *( const Vector3 & vec ) const;\n\n    // Multiply a 3x4 transformation matrix by a 3-D point\n    // \n    inline const Point3 operator *( const Point3 & pnt ) const;\n\n    // Multiply two 3x4 transformation matrices\n    // \n    inline const Transform3 operator *( const Transform3 & tfrm ) const;\n\n    // Perform compound assignment and multiplication by a 3x4 transformation matrix\n    // \n    inline Transform3 & operator *=( const Transform3 & tfrm );\n\n    // Construct an identity 3x4 transformation matrix\n    // \n    static inline const Transform3 identity( );\n\n    // Construct a 3x4 transformation matrix to rotate around the x axis\n    // \n    static inline const Transform3 rotationX( vec_float4 radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the y axis\n    // \n    static inline const Transform3 rotationY( vec_float4 radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the z axis\n    // \n    static inline const Transform3 rotationZ( vec_float4 radians );\n\n    // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes\n    // \n    static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ );\n\n    // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector\n    // \n    static inline const Transform3 rotation( vec_float4 radians, const Vector3 & unitVec );\n\n    // Construct a rotation matrix from a unit-length quaternion\n    // \n    static inline const Transform3 rotation( const Quat & unitQuat );\n\n    // Construct a 3x4 transformation matrix to perform scaling\n    // \n    static inline const Transform3 scale( const Vector3 & scaleVec );\n\n    // Construct a 3x4 transformation matrix to perform translation\n    // \n    static inline const Transform3 translation( const Vector3 & translateVec );\n\n};\n// Append (post-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec );\n\n// Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix\n// NOTE: \n// Faster than creating and multiplying a scale transformation matrix.\n// \ninline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm );\n\n// Multiply two 3x4 transformation matrices per element\n// \ninline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 );\n\n// Compute the absolute value of a 3x4 transformation matrix per element\n// \ninline const Transform3 absPerElem( const Transform3 & tfrm );\n\n// Inverse of a 3x4 transformation matrix\n// NOTE: \n// Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.\n// \ninline const Transform3 inverse( const Transform3 & tfrm );\n\n// Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix\n// NOTE: \n// This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.\n// \ninline const Transform3 orthoInverse( const Transform3 & tfrm );\n\n// Conditionally select between two 3x4 transformation matrices\n// NOTE: \n// This function uses a conditional select instruction to avoid a branch.\n// \ninline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 );\n\n#ifdef _VECTORMATH_DEBUG\n\n// Print a 3x4 transformation matrix\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm );\n\n// Print a 3x4 transformation matrix and an associated string identifier\n// NOTE: \n// Function is only defined when _VECTORMATH_DEBUG is defined.\n// \ninline void print( const Transform3 & tfrm, const char * name );\n\n#endif\n\n} // namespace Soa\n} // namespace Vectormath\n\n#include \"vec_soa.h\"\n#include \"quat_soa.h\"\n#include \"mat_soa.h\"\n\n#endif\n"
  },
  {
    "path": "samples/vectormath/vectormath.h",
    "content": "\n// ================================================================================================\n// -*- C++ -*-\n// File:   vectormath.h\n// Author: Guilherme R. Lampert\n// Brief:  This header exposes the Sony Vector Math library types into the global scope.\n// ================================================================================================\n\n#ifndef VECTORMATH_H_\n#define VECTORMATH_H_\n\n// We're using the generic Array of Structures (AoS) format.\n#include \"cpp/vectormath_aos.h\"\nusing namespace Vectormath::Aos;\n\ninline float * toFloatPtr(Point3  & p) { return reinterpret_cast<float *>(&p); }\ninline float * toFloatPtr(Vector3 & v) { return reinterpret_cast<float *>(&v); }\ninline float * toFloatPtr(Vector4 & v) { return reinterpret_cast<float *>(&v); }\ninline float * toFloatPtr(Quat    & q) { return reinterpret_cast<float *>(&q); }\ninline float * toFloatPtr(Matrix3 & m) { return reinterpret_cast<float *>(&m); }\ninline float * toFloatPtr(Matrix4 & m) { return reinterpret_cast<float *>(&m); }\n\ninline const float * toFloatPtr(const Point3  & p) { return reinterpret_cast<const float *>(&p); }\ninline const float * toFloatPtr(const Vector3 & v) { return reinterpret_cast<const float *>(&v); }\ninline const float * toFloatPtr(const Vector4 & v) { return reinterpret_cast<const float *>(&v); }\ninline const float * toFloatPtr(const Quat    & q) { return reinterpret_cast<const float *>(&q); }\ninline const float * toFloatPtr(const Matrix3 & m) { return reinterpret_cast<const float *>(&m); }\ninline const float * toFloatPtr(const Matrix4 & m) { return reinterpret_cast<const float *>(&m); }\n\n// Shorthand to discard the last element of a Vector4 and get a Point3.\ninline Point3 toPoint3(const Vector4 & v4)\n{\n    return Point3(v4[0], v4[1], v4[2]);\n}\n\n// Convert from world (global) coordinates to local model coordinates.\n// Input matrix must be the inverse of the model matrix, e.g.: 'inverse(modelMatrix)'.\ninline Point3 worldPointToModel(const Matrix4 & invModelToWorldMatrix, const Point3 & point)\n{\n    return toPoint3(invModelToWorldMatrix * point);\n}\n\n#endif // VECTORMATH_H_\n"
  },
  {
    "path": "samples/vs2015/ddSampleD3D11/ddSampleD3D11.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_d3d11.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleD3D11/ddSampleD3D11.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25420.1\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ddSampleD3D11\", \"ddSampleD3D11.vcxproj\", \"{362616A9-7C5B-428B-B2EF-3350A7961F81}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.Build.0 = Debug|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.ActiveCfg = Release|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/vs2015/ddSampleD3D11/ddSampleD3D11.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{362616A9-7C5B-428B-B2EF-3350A7961F81}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>ddSampleD3D11</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n    <ProjectName>ddSampleD3D11</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <FxCompile>\n      <EntryPointName>VS_LinePoint</EntryPointName>\n      <ShaderModel>4.0</ShaderModel>\n    </FxCompile>\n    <Manifest>\n      <EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>\n    </Manifest>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <FxCompile>\n      <EntryPointName>VS_LinePoint</EntryPointName>\n      <ShaderModel>4.0</ShaderModel>\n    </FxCompile>\n    <Manifest>\n      <EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>\n    </Manifest>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <FxCompile>\n      <EntryPointName>VS_LinePoint</EntryPointName>\n      <ShaderModel>4.0</ShaderModel>\n    </FxCompile>\n    <Manifest>\n      <EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>\n    </Manifest>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <FxCompile>\n      <EntryPointName>VS_LinePoint</EntryPointName>\n      <ShaderModel>4.0</ShaderModel>\n    </FxCompile>\n    <Manifest>\n      <EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>\n    </Manifest>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\" />\n    <ClInclude Include=\"..\\..\\samples_common.hpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_d3d11.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <FxCompile Include=\"ddShader.fx\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleD3D11/ddShader.fx",
    "content": "\n///////////////////////////////////////////////////////////////////////////////\n\nTexture2D    glyphsTexture : register(t0);\nSamplerState glyphsSampler : register(s0);\n\ncbuffer ConstantBufferData : register(b0)\n{\n    matrix mvpMatrix;\n    float4 screenDimensions;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n\nstruct VertexInput\n{\n    float4 pos   : POSITION;\n    float4 uv    : TEXCOORD;\n    float4 color : COLOR;\n};\n\nstruct VertexOutput\n{\n    float4 vpos  : SV_POSITION;\n    float4 uv    : TEXCOORD;\n    float4 color : COLOR;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Line/point drawing:\n///////////////////////////////////////////////////////////////////////////////\n\nVertexOutput VS_LinePoint(VertexInput input)\n{\n    VertexOutput output;\n    output.vpos  = mul(input.pos, mvpMatrix);\n    output.uv    = input.uv;\n    output.color = input.color;\n    return output;\n}\n\nfloat4 PS_LinePoint(VertexOutput input) : SV_TARGET\n{\n    return input.color;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// Text glyphs drawing:\n///////////////////////////////////////////////////////////////////////////////\n\nVertexOutput VS_TextGlyph(VertexInput input)\n{\n    // Map to normalized clip coordinates:\n    float x = ((2.0 * (input.pos.x - 0.5)) / screenDimensions.x) - 1.0;\n    float y = 1.0 - ((2.0 * (input.pos.y - 0.5)) / screenDimensions.y);\n\n    VertexOutput output;\n    output.vpos  = float4(x, y, 0.0, 1.0);\n    output.uv    = input.uv;\n    output.color = input.color;\n    return output;\n}\n\nfloat4 PS_TextGlyph(VertexOutput input) : SV_TARGET\n{\n    float4 texColor  = glyphsTexture.Sample(glyphsSampler, input.uv.xy);\n    float4 fragColor = input.color;\n\n    fragColor.a = texColor.r;\n    return fragColor;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "samples/vs2015/ddSampleGLCore/ddSampleGLCore.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.23107.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ddSampleGLCore\", \"ddSampleGLCore.vcxproj\", \"{44AFAFA2-2597-49F5-A8FC-FB49783C8864}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.Build.0 = Debug|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.Build.0 = Debug|Win32\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.ActiveCfg = Release|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.Build.0 = Release|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.ActiveCfg = Release|Win32\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/vs2015/ddSampleGLCore/ddSampleGLCore.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{44AFAFA2-2597-49F5-A8FC-FB49783C8864}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>ddSampleGLCore</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN32\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN64\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN32\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN64\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN32\\lib-vc2015;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN64\\lib-vc2015\\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN32\\lib-vc2015;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN64\\lib-vc2015\\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\" />\n    <ClInclude Include=\"..\\..\\samples_common.hpp\" />\n    <ClInclude Include=\"..\\..\\vectormath\\vectormath.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\gl3w\\src\\gl3w.cpp\" />\n    <ClCompile Include=\"..\\..\\sample_gl_core.cpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleGLCore/ddSampleGLCore.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\samples_common.hpp\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\vectormath\\vectormath.h\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_gl_core.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\gl3w\\src\\gl3w.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleGLLegacy/ddSampleGLCore.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{44AFAFA2-2597-49F5-A8FC-FB49783C8864}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>ddSampleGLCore</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n    <ProjectName>ddSampleGLLegacy</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN32\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN64\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN32\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\;$(SolutionDir)..\\..\\..\\;$(SolutionDir)..\\..\\vectormath\\;$(SolutionDir)..\\..\\gl3w\\include\\;$(SolutionDir)..\\glfw-3.2-WIN64\\include\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN32\\lib-vc2015;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN64\\lib-vc2015\\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN32\\lib-vc2015;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalLibraryDirectories>$(SolutionDir)..\\glfw-3.2-WIN64\\lib-vc2015\\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <AdditionalDependencies>glfw3.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\" />\n    <ClInclude Include=\"..\\..\\samples_common.hpp\" />\n    <ClInclude Include=\"..\\..\\vectormath\\vectormath.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_gl_legacy.cpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleGLLegacy/ddSampleGLCore.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\samples_common.hpp\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\vectormath\\vectormath.h\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_gl_legacy.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleGLLegacy/ddSampleGLLegacy.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.23107.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ddSampleGLCore\", \"ddSampleGLCore.vcxproj\", \"{44AFAFA2-2597-49F5-A8FC-FB49783C8864}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.Build.0 = Debug|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.Build.0 = Debug|Win32\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.ActiveCfg = Release|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.Build.0 = Release|x64\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.ActiveCfg = Release|Win32\n\t\t{44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/vs2015/ddSampleNullRenderer/ddSampleNullRenderer.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.23107.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ddSampleNullRenderer\", \"ddSampleNullRenderer.vcxproj\", \"{362616A9-7C5B-428B-B2EF-3350A7961F81}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.Build.0 = Debug|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x86.Build.0 = Debug|Win32\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.ActiveCfg = Release|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.Build.0 = Release|x64\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x86.ActiveCfg = Release|Win32\n\t\t{362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/vs2015/ddSampleNullRenderer/ddSampleNullRenderer.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{362616A9-7C5B-428B-B2EF-3350A7961F81}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>ddSampleNullRenderer</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>$(SolutionDir)..\\..\\..\\;$(IncludePath)</IncludePath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_null_renderer.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/ddSampleNullRenderer/ddSampleNullRenderer.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\sample_null_renderer.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\debug_draw.hpp\">\n      <Filter>Source Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/vs2015/glfw-3.2-WIN32/COPYING.txt",
    "content": "Copyright (c) 2002-2006 Marcus Geelnard\nCopyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would\n   be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\n   distribution.\n\n"
  },
  {
    "path": "samples/vs2015/glfw-3.2-WIN32/include/GLFW/glfw3.h",
    "content": "/*************************************************************************\n * GLFW 3.2 - www.glfw.org\n * A library for OpenGL, window and input\n *------------------------------------------------------------------------\n * Copyright (c) 2002-2006 Marcus Geelnard\n * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n *\n *************************************************************************/\n\n#ifndef _glfw3_h_\n#define _glfw3_h_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/*************************************************************************\n * Doxygen documentation\n *************************************************************************/\n\n/*! @file glfw3.h\n *  @brief The header of the GLFW 3 API.\n *\n *  This is the header file of the GLFW 3 API.  It defines all its types and\n *  declares all its functions.\n *\n *  For more information about how to use this file, see @ref build_include.\n */\n/*! @defgroup context Context reference\n *\n *  This is the reference documentation for OpenGL and OpenGL ES context related\n *  functions.  For more task-oriented information, see the @ref context_guide.\n */\n/*! @defgroup vulkan Vulkan reference\n *\n *  This is the reference documentation for Vulkan related functions and types.\n *  For more task-oriented information, see the @ref vulkan_guide.\n */\n/*! @defgroup init Initialization, version and error reference\n *\n *  This is the reference documentation for initialization and termination of\n *  the library, version management and error handling.  For more task-oriented\n *  information, see the @ref intro_guide.\n */\n/*! @defgroup input Input reference\n *\n *  This is the reference documentation for input related functions and types.\n *  For more task-oriented information, see the @ref input_guide.\n */\n/*! @defgroup monitor Monitor reference\n *\n *  This is the reference documentation for monitor related functions and types.\n *  For more task-oriented information, see the @ref monitor_guide.\n */\n/*! @defgroup window Window reference\n *\n *  This is the reference documentation for window related functions and types,\n *  including creation, deletion and event polling.  For more task-oriented\n *  information, see the @ref window_guide.\n */\n\n\n/*************************************************************************\n * Compiler- and platform-specific preprocessor work\n *************************************************************************/\n\n/* If we are we on Windows, we want a single define for it.\n */\n#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))\n #define _WIN32\n#endif /* _WIN32 */\n\n/* It is customary to use APIENTRY for OpenGL function pointer declarations on\n * all platforms.  Additionally, the Windows OpenGL header needs APIENTRY.\n */\n#ifndef APIENTRY\n #ifdef _WIN32\n  #define APIENTRY __stdcall\n #else\n  #define APIENTRY\n #endif\n#endif /* APIENTRY */\n\n/* Some Windows OpenGL headers need this.\n */\n#if !defined(WINGDIAPI) && defined(_WIN32)\n #define WINGDIAPI __declspec(dllimport)\n #define GLFW_WINGDIAPI_DEFINED\n#endif /* WINGDIAPI */\n\n/* Some Windows GLU headers need this.\n */\n#if !defined(CALLBACK) && defined(_WIN32)\n #define CALLBACK __stdcall\n #define GLFW_CALLBACK_DEFINED\n#endif /* CALLBACK */\n\n/* Most Windows GLU headers need wchar_t.\n * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.\n * Include it unconditionally to avoid surprising side-effects.\n */\n#include <stddef.h>\n#include <stdint.h>\n\n/* Include the chosen client API headers.\n */\n#if defined(__APPLE__)\n #if defined(GLFW_INCLUDE_GLCOREARB)\n  #include <OpenGL/gl3.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <OpenGL/gl3ext.h>\n  #endif\n #elif !defined(GLFW_INCLUDE_NONE)\n  #if !defined(GLFW_INCLUDE_GLEXT)\n   #define GL_GLEXT_LEGACY\n  #endif\n  #include <OpenGL/gl.h>\n #endif\n #if defined(GLFW_INCLUDE_GLU)\n  #include <OpenGL/glu.h>\n #endif\n#else\n #if defined(GLFW_INCLUDE_GLCOREARB)\n  #include <GL/glcorearb.h>\n #elif defined(GLFW_INCLUDE_ES1)\n  #include <GLES/gl.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES/glext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_ES2)\n  #include <GLES2/gl2.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES2/gl2ext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_ES3)\n  #include <GLES3/gl3.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES2/gl2ext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_ES31)\n  #include <GLES3/gl31.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES2/gl2ext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_VULKAN)\n  #include <vulkan/vulkan.h>\n #elif !defined(GLFW_INCLUDE_NONE)\n  #include <GL/gl.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GL/glext.h>\n  #endif\n #endif\n #if defined(GLFW_INCLUDE_GLU)\n  #include <GL/glu.h>\n #endif\n#endif\n\n#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)\n /* GLFW_DLL must be defined by applications that are linking against the DLL\n  * version of the GLFW library.  _GLFW_BUILD_DLL is defined by the GLFW\n  * configuration header when compiling the DLL version of the library.\n  */\n #error \"You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined\"\n#endif\n\n/* GLFWAPI is used to declare public API functions for export\n * from the DLL / shared library / dynamic library.\n */\n#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)\n /* We are building GLFW as a Win32 DLL */\n #define GLFWAPI __declspec(dllexport)\n#elif defined(_WIN32) && defined(GLFW_DLL)\n /* We are calling GLFW as a Win32 DLL */\n #define GLFWAPI __declspec(dllimport)\n#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)\n /* We are building GLFW as a shared / dynamic library */\n #define GLFWAPI __attribute__((visibility(\"default\")))\n#else\n /* We are building or calling GLFW as a static library */\n #define GLFWAPI\n#endif\n\n\n/*************************************************************************\n * GLFW API tokens\n *************************************************************************/\n\n/*! @name GLFW version macros\n *  @{ */\n/*! @brief The major version number of the GLFW library.\n *\n *  This is incremented when the API is changed in non-compatible ways.\n *  @ingroup init\n */\n#define GLFW_VERSION_MAJOR          3\n/*! @brief The minor version number of the GLFW library.\n *\n *  This is incremented when features are added to the API but it remains\n *  backward-compatible.\n *  @ingroup init\n */\n#define GLFW_VERSION_MINOR          2\n/*! @brief The revision number of the GLFW library.\n *\n *  This is incremented when a bug fix release is made that does not contain any\n *  API changes.\n *  @ingroup init\n */\n#define GLFW_VERSION_REVISION       0\n/*! @} */\n\n/*! @name Boolean values\n *  @{ */\n/*! @brief One.\n *\n *  One.  Seriously.  You don't _need_ to use this symbol in your code.  It's\n *  just semantic sugar for the number 1.  You can use `1` or `true` or `_True`\n *  or `GL_TRUE` or whatever you want.\n */\n#define GLFW_TRUE                   1\n/*! @brief Zero.\n *\n *  Zero.  Seriously.  You don't _need_ to use this symbol in your code.  It's\n *  just just semantic sugar for the number 0.  You can use `0` or `false` or\n *  `_False` or `GL_FALSE` or whatever you want.\n */\n#define GLFW_FALSE                  0\n/*! @} */\n\n/*! @name Key and button actions\n *  @{ */\n/*! @brief The key or mouse button was released.\n *\n *  The key or mouse button was released.\n *\n *  @ingroup input\n */\n#define GLFW_RELEASE                0\n/*! @brief The key or mouse button was pressed.\n *\n *  The key or mouse button was pressed.\n *\n *  @ingroup input\n */\n#define GLFW_PRESS                  1\n/*! @brief The key was held down until it repeated.\n *\n *  The key was held down until it repeated.\n *\n *  @ingroup input\n */\n#define GLFW_REPEAT                 2\n/*! @} */\n\n/*! @defgroup keys Keyboard keys\n *\n *  See [key input](@ref input_key) for how these are used.\n *\n *  These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),\n *  but re-arranged to map to 7-bit ASCII for printable keys (function keys are\n *  put in the 256+ range).\n *\n *  The naming of the key codes follow these rules:\n *   - The US keyboard layout is used\n *   - Names of printable alpha-numeric characters are used (e.g. \"A\", \"R\",\n *     \"3\", etc.)\n *   - For non-alphanumeric characters, Unicode:ish names are used (e.g.\n *     \"COMMA\", \"LEFT_SQUARE_BRACKET\", etc.). Note that some names do not\n *     correspond to the Unicode standard (usually for brevity)\n *   - Keys that lack a clear US mapping are named \"WORLD_x\"\n *   - For non-printable keys, custom names are used (e.g. \"F4\",\n *     \"BACKSPACE\", etc.)\n *\n *  @ingroup input\n *  @{\n */\n\n/* The unknown key */\n#define GLFW_KEY_UNKNOWN            -1\n\n/* Printable keys */\n#define GLFW_KEY_SPACE              32\n#define GLFW_KEY_APOSTROPHE         39  /* ' */\n#define GLFW_KEY_COMMA              44  /* , */\n#define GLFW_KEY_MINUS              45  /* - */\n#define GLFW_KEY_PERIOD             46  /* . */\n#define GLFW_KEY_SLASH              47  /* / */\n#define GLFW_KEY_0                  48\n#define GLFW_KEY_1                  49\n#define GLFW_KEY_2                  50\n#define GLFW_KEY_3                  51\n#define GLFW_KEY_4                  52\n#define GLFW_KEY_5                  53\n#define GLFW_KEY_6                  54\n#define GLFW_KEY_7                  55\n#define GLFW_KEY_8                  56\n#define GLFW_KEY_9                  57\n#define GLFW_KEY_SEMICOLON          59  /* ; */\n#define GLFW_KEY_EQUAL              61  /* = */\n#define GLFW_KEY_A                  65\n#define GLFW_KEY_B                  66\n#define GLFW_KEY_C                  67\n#define GLFW_KEY_D                  68\n#define GLFW_KEY_E                  69\n#define GLFW_KEY_F                  70\n#define GLFW_KEY_G                  71\n#define GLFW_KEY_H                  72\n#define GLFW_KEY_I                  73\n#define GLFW_KEY_J                  74\n#define GLFW_KEY_K                  75\n#define GLFW_KEY_L                  76\n#define GLFW_KEY_M                  77\n#define GLFW_KEY_N                  78\n#define GLFW_KEY_O                  79\n#define GLFW_KEY_P                  80\n#define GLFW_KEY_Q                  81\n#define GLFW_KEY_R                  82\n#define GLFW_KEY_S                  83\n#define GLFW_KEY_T                  84\n#define GLFW_KEY_U                  85\n#define GLFW_KEY_V                  86\n#define GLFW_KEY_W                  87\n#define GLFW_KEY_X                  88\n#define GLFW_KEY_Y                  89\n#define GLFW_KEY_Z                  90\n#define GLFW_KEY_LEFT_BRACKET       91  /* [ */\n#define GLFW_KEY_BACKSLASH          92  /* \\ */\n#define GLFW_KEY_RIGHT_BRACKET      93  /* ] */\n#define GLFW_KEY_GRAVE_ACCENT       96  /* ` */\n#define GLFW_KEY_WORLD_1            161 /* non-US #1 */\n#define GLFW_KEY_WORLD_2            162 /* non-US #2 */\n\n/* Function keys */\n#define GLFW_KEY_ESCAPE             256\n#define GLFW_KEY_ENTER              257\n#define GLFW_KEY_TAB                258\n#define GLFW_KEY_BACKSPACE          259\n#define GLFW_KEY_INSERT             260\n#define GLFW_KEY_DELETE             261\n#define GLFW_KEY_RIGHT              262\n#define GLFW_KEY_LEFT               263\n#define GLFW_KEY_DOWN               264\n#define GLFW_KEY_UP                 265\n#define GLFW_KEY_PAGE_UP            266\n#define GLFW_KEY_PAGE_DOWN          267\n#define GLFW_KEY_HOME               268\n#define GLFW_KEY_END                269\n#define GLFW_KEY_CAPS_LOCK          280\n#define GLFW_KEY_SCROLL_LOCK        281\n#define GLFW_KEY_NUM_LOCK           282\n#define GLFW_KEY_PRINT_SCREEN       283\n#define GLFW_KEY_PAUSE              284\n#define GLFW_KEY_F1                 290\n#define GLFW_KEY_F2                 291\n#define GLFW_KEY_F3                 292\n#define GLFW_KEY_F4                 293\n#define GLFW_KEY_F5                 294\n#define GLFW_KEY_F6                 295\n#define GLFW_KEY_F7                 296\n#define GLFW_KEY_F8                 297\n#define GLFW_KEY_F9                 298\n#define GLFW_KEY_F10                299\n#define GLFW_KEY_F11                300\n#define GLFW_KEY_F12                301\n#define GLFW_KEY_F13                302\n#define GLFW_KEY_F14                303\n#define GLFW_KEY_F15                304\n#define GLFW_KEY_F16                305\n#define GLFW_KEY_F17                306\n#define GLFW_KEY_F18                307\n#define GLFW_KEY_F19                308\n#define GLFW_KEY_F20                309\n#define GLFW_KEY_F21                310\n#define GLFW_KEY_F22                311\n#define GLFW_KEY_F23                312\n#define GLFW_KEY_F24                313\n#define GLFW_KEY_F25                314\n#define GLFW_KEY_KP_0               320\n#define GLFW_KEY_KP_1               321\n#define GLFW_KEY_KP_2               322\n#define GLFW_KEY_KP_3               323\n#define GLFW_KEY_KP_4               324\n#define GLFW_KEY_KP_5               325\n#define GLFW_KEY_KP_6               326\n#define GLFW_KEY_KP_7               327\n#define GLFW_KEY_KP_8               328\n#define GLFW_KEY_KP_9               329\n#define GLFW_KEY_KP_DECIMAL         330\n#define GLFW_KEY_KP_DIVIDE          331\n#define GLFW_KEY_KP_MULTIPLY        332\n#define GLFW_KEY_KP_SUBTRACT        333\n#define GLFW_KEY_KP_ADD             334\n#define GLFW_KEY_KP_ENTER           335\n#define GLFW_KEY_KP_EQUAL           336\n#define GLFW_KEY_LEFT_SHIFT         340\n#define GLFW_KEY_LEFT_CONTROL       341\n#define GLFW_KEY_LEFT_ALT           342\n#define GLFW_KEY_LEFT_SUPER         343\n#define GLFW_KEY_RIGHT_SHIFT        344\n#define GLFW_KEY_RIGHT_CONTROL      345\n#define GLFW_KEY_RIGHT_ALT          346\n#define GLFW_KEY_RIGHT_SUPER        347\n#define GLFW_KEY_MENU               348\n\n#define GLFW_KEY_LAST               GLFW_KEY_MENU\n\n/*! @} */\n\n/*! @defgroup mods Modifier key flags\n *\n *  See [key input](@ref input_key) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n\n/*! @brief If this bit is set one or more Shift keys were held down.\n */\n#define GLFW_MOD_SHIFT           0x0001\n/*! @brief If this bit is set one or more Control keys were held down.\n */\n#define GLFW_MOD_CONTROL         0x0002\n/*! @brief If this bit is set one or more Alt keys were held down.\n */\n#define GLFW_MOD_ALT             0x0004\n/*! @brief If this bit is set one or more Super keys were held down.\n */\n#define GLFW_MOD_SUPER           0x0008\n\n/*! @} */\n\n/*! @defgroup buttons Mouse buttons\n *\n *  See [mouse button input](@ref input_mouse_button) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n#define GLFW_MOUSE_BUTTON_1         0\n#define GLFW_MOUSE_BUTTON_2         1\n#define GLFW_MOUSE_BUTTON_3         2\n#define GLFW_MOUSE_BUTTON_4         3\n#define GLFW_MOUSE_BUTTON_5         4\n#define GLFW_MOUSE_BUTTON_6         5\n#define GLFW_MOUSE_BUTTON_7         6\n#define GLFW_MOUSE_BUTTON_8         7\n#define GLFW_MOUSE_BUTTON_LAST      GLFW_MOUSE_BUTTON_8\n#define GLFW_MOUSE_BUTTON_LEFT      GLFW_MOUSE_BUTTON_1\n#define GLFW_MOUSE_BUTTON_RIGHT     GLFW_MOUSE_BUTTON_2\n#define GLFW_MOUSE_BUTTON_MIDDLE    GLFW_MOUSE_BUTTON_3\n/*! @} */\n\n/*! @defgroup joysticks Joysticks\n *\n *  See [joystick input](@ref joystick) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n#define GLFW_JOYSTICK_1             0\n#define GLFW_JOYSTICK_2             1\n#define GLFW_JOYSTICK_3             2\n#define GLFW_JOYSTICK_4             3\n#define GLFW_JOYSTICK_5             4\n#define GLFW_JOYSTICK_6             5\n#define GLFW_JOYSTICK_7             6\n#define GLFW_JOYSTICK_8             7\n#define GLFW_JOYSTICK_9             8\n#define GLFW_JOYSTICK_10            9\n#define GLFW_JOYSTICK_11            10\n#define GLFW_JOYSTICK_12            11\n#define GLFW_JOYSTICK_13            12\n#define GLFW_JOYSTICK_14            13\n#define GLFW_JOYSTICK_15            14\n#define GLFW_JOYSTICK_16            15\n#define GLFW_JOYSTICK_LAST          GLFW_JOYSTICK_16\n/*! @} */\n\n/*! @defgroup errors Error codes\n *\n *  See [error handling](@ref error_handling) for how these are used.\n *\n *  @ingroup init\n *  @{ */\n/*! @brief GLFW has not been initialized.\n *\n *  This occurs if a GLFW function was called that must not be called unless the\n *  library is [initialized](@ref intro_init).\n *\n *  @analysis Application programmer error.  Initialize GLFW before calling any\n *  function that requires initialization.\n */\n#define GLFW_NOT_INITIALIZED        0x00010001\n/*! @brief No context is current for this thread.\n *\n *  This occurs if a GLFW function was called that needs and operates on the\n *  current OpenGL or OpenGL ES context but no context is current on the calling\n *  thread.  One such function is @ref glfwSwapInterval.\n *\n *  @analysis Application programmer error.  Ensure a context is current before\n *  calling functions that require a current context.\n */\n#define GLFW_NO_CURRENT_CONTEXT     0x00010002\n/*! @brief One of the arguments to the function was an invalid enum value.\n *\n *  One of the arguments to the function was an invalid enum value, for example\n *  requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref\n *  glfwGetWindowAttrib.\n *\n *  @analysis Application programmer error.  Fix the offending call.\n */\n#define GLFW_INVALID_ENUM           0x00010003\n/*! @brief One of the arguments to the function was an invalid value.\n *\n *  One of the arguments to the function was an invalid value, for example\n *  requesting a non-existent OpenGL or OpenGL ES version like 2.7.\n *\n *  Requesting a valid but unavailable OpenGL or OpenGL ES version will instead\n *  result in a @ref GLFW_VERSION_UNAVAILABLE error.\n *\n *  @analysis Application programmer error.  Fix the offending call.\n */\n#define GLFW_INVALID_VALUE          0x00010004\n/*! @brief A memory allocation failed.\n *\n *  A memory allocation failed.\n *\n *  @analysis A bug in GLFW or the underlying operating system.  Report the bug\n *  to our [issue tracker](https://github.com/glfw/glfw/issues).\n */\n#define GLFW_OUT_OF_MEMORY          0x00010005\n/*! @brief GLFW could not find support for the requested API on the system.\n *\n *  GLFW could not find support for the requested API on the system.\n *\n *  @analysis The installed graphics driver does not support the requested\n *  API, or does not support it via the chosen context creation backend.\n *  Below are a few examples.\n *\n *  @par\n *  Some pre-installed Windows graphics drivers do not support OpenGL.  AMD only\n *  supports OpenGL ES via EGL, while Nvidia and Intel only support it via\n *  a WGL or GLX extension.  OS X does not provide OpenGL ES at all.  The Mesa\n *  EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary\n *  driver.  Older graphics drivers do not support Vulkan.\n */\n#define GLFW_API_UNAVAILABLE        0x00010006\n/*! @brief The requested OpenGL or OpenGL ES version is not available.\n *\n *  The requested OpenGL or OpenGL ES version (including any requested context\n *  or framebuffer hints) is not available on this machine.\n *\n *  @analysis The machine does not support your requirements.  If your\n *  application is sufficiently flexible, downgrade your requirements and try\n *  again.  Otherwise, inform the user that their machine does not match your\n *  requirements.\n *\n *  @par\n *  Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0\n *  comes out before the 4.x series gets that far, also fail with this error and\n *  not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions\n *  will exist.\n */\n#define GLFW_VERSION_UNAVAILABLE    0x00010007\n/*! @brief A platform-specific error occurred that does not match any of the\n *  more specific categories.\n *\n *  A platform-specific error occurred that does not match any of the more\n *  specific categories.\n *\n *  @analysis A bug or configuration error in GLFW, the underlying operating\n *  system or its drivers, or a lack of required resources.  Report the issue to\n *  our [issue tracker](https://github.com/glfw/glfw/issues).\n */\n#define GLFW_PLATFORM_ERROR         0x00010008\n/*! @brief The requested format is not supported or available.\n *\n *  If emitted during window creation, the requested pixel format is not\n *  supported.\n *\n *  If emitted when querying the clipboard, the contents of the clipboard could\n *  not be converted to the requested format.\n *\n *  @analysis If emitted during window creation, one or more\n *  [hard constraints](@ref window_hints_hard) did not match any of the\n *  available pixel formats.  If your application is sufficiently flexible,\n *  downgrade your requirements and try again.  Otherwise, inform the user that\n *  their machine does not match your requirements.\n *\n *  @par\n *  If emitted when querying the clipboard, ignore the error or report it to\n *  the user, as appropriate.\n */\n#define GLFW_FORMAT_UNAVAILABLE     0x00010009\n/*! @brief The specified window does not have an OpenGL or OpenGL ES context.\n *\n *  A window that does not have an OpenGL or OpenGL ES context was passed to\n *  a function that requires it to have one.\n *\n *  @analysis Application programmer error.  Fix the offending call.\n */\n#define GLFW_NO_WINDOW_CONTEXT      0x0001000A\n/*! @} */\n\n#define GLFW_FOCUSED                0x00020001\n#define GLFW_ICONIFIED              0x00020002\n#define GLFW_RESIZABLE              0x00020003\n#define GLFW_VISIBLE                0x00020004\n#define GLFW_DECORATED              0x00020005\n#define GLFW_AUTO_ICONIFY           0x00020006\n#define GLFW_FLOATING               0x00020007\n#define GLFW_MAXIMIZED              0x00020008\n\n#define GLFW_RED_BITS               0x00021001\n#define GLFW_GREEN_BITS             0x00021002\n#define GLFW_BLUE_BITS              0x00021003\n#define GLFW_ALPHA_BITS             0x00021004\n#define GLFW_DEPTH_BITS             0x00021005\n#define GLFW_STENCIL_BITS           0x00021006\n#define GLFW_ACCUM_RED_BITS         0x00021007\n#define GLFW_ACCUM_GREEN_BITS       0x00021008\n#define GLFW_ACCUM_BLUE_BITS        0x00021009\n#define GLFW_ACCUM_ALPHA_BITS       0x0002100A\n#define GLFW_AUX_BUFFERS            0x0002100B\n#define GLFW_STEREO                 0x0002100C\n#define GLFW_SAMPLES                0x0002100D\n#define GLFW_SRGB_CAPABLE           0x0002100E\n#define GLFW_REFRESH_RATE           0x0002100F\n#define GLFW_DOUBLEBUFFER           0x00021010\n\n#define GLFW_CLIENT_API             0x00022001\n#define GLFW_CONTEXT_VERSION_MAJOR  0x00022002\n#define GLFW_CONTEXT_VERSION_MINOR  0x00022003\n#define GLFW_CONTEXT_REVISION       0x00022004\n#define GLFW_CONTEXT_ROBUSTNESS     0x00022005\n#define GLFW_OPENGL_FORWARD_COMPAT  0x00022006\n#define GLFW_OPENGL_DEBUG_CONTEXT   0x00022007\n#define GLFW_OPENGL_PROFILE         0x00022008\n#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009\n#define GLFW_CONTEXT_NO_ERROR       0x0002200A\n#define GLFW_CONTEXT_CREATION_API   0x0002200B\n\n#define GLFW_NO_API                          0\n#define GLFW_OPENGL_API             0x00030001\n#define GLFW_OPENGL_ES_API          0x00030002\n\n#define GLFW_NO_ROBUSTNESS                   0\n#define GLFW_NO_RESET_NOTIFICATION  0x00031001\n#define GLFW_LOSE_CONTEXT_ON_RESET  0x00031002\n\n#define GLFW_OPENGL_ANY_PROFILE              0\n#define GLFW_OPENGL_CORE_PROFILE    0x00032001\n#define GLFW_OPENGL_COMPAT_PROFILE  0x00032002\n\n#define GLFW_CURSOR                 0x00033001\n#define GLFW_STICKY_KEYS            0x00033002\n#define GLFW_STICKY_MOUSE_BUTTONS   0x00033003\n\n#define GLFW_CURSOR_NORMAL          0x00034001\n#define GLFW_CURSOR_HIDDEN          0x00034002\n#define GLFW_CURSOR_DISABLED        0x00034003\n\n#define GLFW_ANY_RELEASE_BEHAVIOR            0\n#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001\n#define GLFW_RELEASE_BEHAVIOR_NONE  0x00035002\n\n#define GLFW_NATIVE_CONTEXT_API     0x00036001\n#define GLFW_EGL_CONTEXT_API        0x00036002\n\n/*! @defgroup shapes Standard cursor shapes\n *\n *  See [standard cursor creation](@ref cursor_standard) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n\n/*! @brief The regular arrow cursor shape.\n *\n *  The regular arrow cursor.\n */\n#define GLFW_ARROW_CURSOR           0x00036001\n/*! @brief The text input I-beam cursor shape.\n *\n *  The text input I-beam cursor shape.\n */\n#define GLFW_IBEAM_CURSOR           0x00036002\n/*! @brief The crosshair shape.\n *\n *  The crosshair shape.\n */\n#define GLFW_CROSSHAIR_CURSOR       0x00036003\n/*! @brief The hand shape.\n *\n *  The hand shape.\n */\n#define GLFW_HAND_CURSOR            0x00036004\n/*! @brief The horizontal resize arrow shape.\n *\n *  The horizontal resize arrow shape.\n */\n#define GLFW_HRESIZE_CURSOR         0x00036005\n/*! @brief The vertical resize arrow shape.\n *\n *  The vertical resize arrow shape.\n */\n#define GLFW_VRESIZE_CURSOR         0x00036006\n/*! @} */\n\n#define GLFW_CONNECTED              0x00040001\n#define GLFW_DISCONNECTED           0x00040002\n\n#define GLFW_DONT_CARE              -1\n\n\n/*************************************************************************\n * GLFW API types\n *************************************************************************/\n\n/*! @brief Client API function pointer type.\n *\n *  Generic function pointer used for returning client API function pointers\n *  without forcing a cast from a regular pointer.\n *\n *  @sa @ref context_glext\n *  @sa glfwGetProcAddress\n *\n *  @since Added in version 3.0.\n \n *  @ingroup context\n */\ntypedef void (*GLFWglproc)(void);\n\n/*! @brief Vulkan API function pointer type.\n *\n *  Generic function pointer used for returning Vulkan API function pointers\n *  without forcing a cast from a regular pointer.\n *\n *  @sa @ref vulkan_proc\n *  @sa glfwGetInstanceProcAddress\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\ntypedef void (*GLFWvkproc)(void);\n\n/*! @brief Opaque monitor object.\n *\n *  Opaque monitor object.\n *\n *  @see @ref monitor_object\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\ntypedef struct GLFWmonitor GLFWmonitor;\n\n/*! @brief Opaque window object.\n *\n *  Opaque window object.\n *\n *  @see @ref window_object\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef struct GLFWwindow GLFWwindow;\n\n/*! @brief Opaque cursor object.\n *\n *  Opaque cursor object.\n *\n *  @see @ref cursor_object\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup cursor\n */\ntypedef struct GLFWcursor GLFWcursor;\n\n/*! @brief The function signature for error callbacks.\n *\n *  This is the function signature for error callback functions.\n *\n *  @param[in] error An [error code](@ref errors).\n *  @param[in] description A UTF-8 encoded string describing the error.\n *\n *  @sa @ref error_handling\n *  @sa glfwSetErrorCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup init\n */\ntypedef void (* GLFWerrorfun)(int,const char*);\n\n/*! @brief The function signature for window position callbacks.\n *\n *  This is the function signature for window position callback functions.\n *\n *  @param[in] window The window that was moved.\n *  @param[in] xpos The new x-coordinate, in screen coordinates, of the\n *  upper-left corner of the client area of the window.\n *  @param[in] ypos The new y-coordinate, in screen coordinates, of the\n *  upper-left corner of the client area of the window.\n *\n *  @sa @ref window_pos\n *  @sa glfwSetWindowPosCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);\n\n/*! @brief The function signature for window resize callbacks.\n *\n *  This is the function signature for window size callback functions.\n *\n *  @param[in] window The window that was resized.\n *  @param[in] width The new width, in screen coordinates, of the window.\n *  @param[in] height The new height, in screen coordinates, of the window.\n *\n *  @sa @ref window_size\n *  @sa glfwSetWindowSizeCallback\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);\n\n/*! @brief The function signature for window close callbacks.\n *\n *  This is the function signature for window close callback functions.\n *\n *  @param[in] window The window that the user attempted to close.\n *\n *  @sa @ref window_close\n *  @sa glfwSetWindowCloseCallback\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowclosefun)(GLFWwindow*);\n\n/*! @brief The function signature for window content refresh callbacks.\n *\n *  This is the function signature for window refresh callback functions.\n *\n *  @param[in] window The window whose content needs to be refreshed.\n *\n *  @sa @ref window_refresh\n *  @sa glfwSetWindowRefreshCallback\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowrefreshfun)(GLFWwindow*);\n\n/*! @brief The function signature for window focus/defocus callbacks.\n *\n *  This is the function signature for window focus callback functions.\n *\n *  @param[in] window The window that gained or lost input focus.\n *  @param[in] focused `GLFW_TRUE` if the window was given input focus, or\n *  `GLFW_FALSE` if it lost it.\n *\n *  @sa @ref window_focus\n *  @sa glfwSetWindowFocusCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);\n\n/*! @brief The function signature for window iconify/restore callbacks.\n *\n *  This is the function signature for window iconify/restore callback\n *  functions.\n *\n *  @param[in] window The window that was iconified or restored.\n *  @param[in] iconified `GLFW_TRUE` if the window was iconified, or\n *  `GLFW_FALSE` if it was restored.\n *\n *  @sa @ref window_iconify\n *  @sa glfwSetWindowIconifyCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);\n\n/*! @brief The function signature for framebuffer resize callbacks.\n *\n *  This is the function signature for framebuffer resize callback\n *  functions.\n *\n *  @param[in] window The window whose framebuffer was resized.\n *  @param[in] width The new width, in pixels, of the framebuffer.\n *  @param[in] height The new height, in pixels, of the framebuffer.\n *\n *  @sa @ref window_fbsize\n *  @sa glfwSetFramebufferSizeCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);\n\n/*! @brief The function signature for mouse button callbacks.\n *\n *  This is the function signature for mouse button callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] button The [mouse button](@ref buttons) that was pressed or\n *  released.\n *  @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.\n *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were\n *  held down.\n *\n *  @sa @ref input_mouse_button\n *  @sa glfwSetMouseButtonCallback\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle and modifier mask parameters.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);\n\n/*! @brief The function signature for cursor position callbacks.\n *\n *  This is the function signature for cursor position callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] xpos The new cursor x-coordinate, relative to the left edge of\n *  the client area.\n *  @param[in] ypos The new cursor y-coordinate, relative to the top edge of the\n *  client area.\n *\n *  @sa @ref cursor_pos\n *  @sa glfwSetCursorPosCallback\n *\n *  @since Added in version 3.0.  Replaces `GLFWmouseposfun`.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);\n\n/*! @brief The function signature for cursor enter/leave callbacks.\n *\n *  This is the function signature for cursor enter/leave callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] entered `GLFW_TRUE` if the cursor entered the window's client\n *  area, or `GLFW_FALSE` if it left it.\n *\n *  @sa @ref cursor_enter\n *  @sa glfwSetCursorEnterCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcursorenterfun)(GLFWwindow*,int);\n\n/*! @brief The function signature for scroll callbacks.\n *\n *  This is the function signature for scroll callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] xoffset The scroll offset along the x-axis.\n *  @param[in] yoffset The scroll offset along the y-axis.\n *\n *  @sa @ref scrolling\n *  @sa glfwSetScrollCallback\n *\n *  @since Added in version 3.0.  Replaces `GLFWmousewheelfun`.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWscrollfun)(GLFWwindow*,double,double);\n\n/*! @brief The function signature for keyboard key callbacks.\n *\n *  This is the function signature for keyboard key callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] key The [keyboard key](@ref keys) that was pressed or released.\n *  @param[in] scancode The system-specific scancode of the key.\n *  @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.\n *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were\n *  held down.\n *\n *  @sa @ref input_key\n *  @sa glfwSetKeyCallback\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle, scancode and modifier mask parameters.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);\n\n/*! @brief The function signature for Unicode character callbacks.\n *\n *  This is the function signature for Unicode character callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] codepoint The Unicode code point of the character.\n *\n *  @sa @ref input_char\n *  @sa glfwSetCharCallback\n *\n *  @since Added in version 2.4.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);\n\n/*! @brief The function signature for Unicode character with modifiers\n *  callbacks.\n *\n *  This is the function signature for Unicode character with modifiers callback\n *  functions.  It is called for each input character, regardless of what\n *  modifier keys are held down.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] codepoint The Unicode code point of the character.\n *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were\n *  held down.\n *\n *  @sa @ref input_char\n *  @sa glfwSetCharModsCallback\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);\n\n/*! @brief The function signature for file drop callbacks.\n *\n *  This is the function signature for file drop callbacks.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] count The number of dropped files.\n *  @param[in] paths The UTF-8 encoded file and/or directory path names.\n *\n *  @sa @ref path_drop\n *  @sa glfwSetDropCallback\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);\n\n/*! @brief The function signature for monitor configuration callbacks.\n *\n *  This is the function signature for monitor configuration callback functions.\n *\n *  @param[in] monitor The monitor that was connected or disconnected.\n *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.\n *\n *  @sa @ref monitor_event\n *  @sa glfwSetMonitorCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\ntypedef void (* GLFWmonitorfun)(GLFWmonitor*,int);\n\n/*! @brief The function signature for joystick configuration callbacks.\n *\n *  This is the function signature for joystick configuration callback\n *  functions.\n *\n *  @param[in] joy The joystick that was connected or disconnected.\n *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.\n *\n *  @sa @ref joystick_event\n *  @sa glfwSetJoystickCallback\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWjoystickfun)(int,int);\n\n/*! @brief Video mode type.\n *\n *  This describes a single video mode.\n *\n *  @sa @ref monitor_modes\n *  @sa glfwGetVideoMode glfwGetVideoModes\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added refresh rate member.\n *\n *  @ingroup monitor\n */\ntypedef struct GLFWvidmode\n{\n    /*! The width, in screen coordinates, of the video mode.\n     */\n    int width;\n    /*! The height, in screen coordinates, of the video mode.\n     */\n    int height;\n    /*! The bit depth of the red channel of the video mode.\n     */\n    int redBits;\n    /*! The bit depth of the green channel of the video mode.\n     */\n    int greenBits;\n    /*! The bit depth of the blue channel of the video mode.\n     */\n    int blueBits;\n    /*! The refresh rate, in Hz, of the video mode.\n     */\n    int refreshRate;\n} GLFWvidmode;\n\n/*! @brief Gamma ramp.\n *\n *  This describes the gamma ramp for a monitor.\n *\n *  @sa @ref monitor_gamma\n *  @sa glfwGetGammaRamp glfwSetGammaRamp\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\ntypedef struct GLFWgammaramp\n{\n    /*! An array of value describing the response of the red channel.\n     */\n    unsigned short* red;\n    /*! An array of value describing the response of the green channel.\n     */\n    unsigned short* green;\n    /*! An array of value describing the response of the blue channel.\n     */\n    unsigned short* blue;\n    /*! The number of elements in each array.\n     */\n    unsigned int size;\n} GLFWgammaramp;\n\n/*! @brief Image data.\n *\n *  @sa @ref cursor_custom\n *\n *  @since Added in version 2.1.\n *  @glfw3 Removed format and bytes-per-pixel members.\n */\ntypedef struct GLFWimage\n{\n    /*! The width, in pixels, of this image.\n     */\n    int width;\n    /*! The height, in pixels, of this image.\n     */\n    int height;\n    /*! The pixel data of this image, arranged left-to-right, top-to-bottom.\n     */\n    unsigned char* pixels;\n} GLFWimage;\n\n\n/*************************************************************************\n * GLFW API functions\n *************************************************************************/\n\n/*! @brief Initializes the GLFW library.\n *\n *  This function initializes the GLFW library.  Before most GLFW functions can\n *  be used, GLFW must be initialized, and before an application terminates GLFW\n *  should be terminated in order to free any resources allocated during or\n *  after initialization.\n *\n *  If this function fails, it calls @ref glfwTerminate before returning.  If it\n *  succeeds, you should call @ref glfwTerminate before the application exits.\n *\n *  Additional calls to this function after successful initialization but before\n *  termination will return `GLFW_TRUE` immediately.\n *\n *  @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark @osx This function will change the current directory of the\n *  application to the `Contents/Resources` subdirectory of the application's\n *  bundle, if present.  This can be disabled with a\n *  [compile-time option](@ref compile_options_osx).\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref intro_init\n *  @sa glfwTerminate\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup init\n */\nGLFWAPI int glfwInit(void);\n\n/*! @brief Terminates the GLFW library.\n *\n *  This function destroys all remaining windows and cursors, restores any\n *  modified gamma ramps and frees any other allocated resources.  Once this\n *  function is called, you must again call @ref glfwInit successfully before\n *  you will be able to use most GLFW functions.\n *\n *  If GLFW has been successfully initialized, this function should be called\n *  before the application exits.  If initialization fails, there is no need to\n *  call this function, as it is called by @ref glfwInit before it returns\n *  failure.\n *\n *  @errors Possible errors include @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @warning The contexts of any remaining windows must not be current on any\n *  other thread when this function is called.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref intro_init\n *  @sa glfwInit\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup init\n */\nGLFWAPI void glfwTerminate(void);\n\n/*! @brief Retrieves the version of the GLFW library.\n *\n *  This function retrieves the major, minor and revision numbers of the GLFW\n *  library.  It is intended for when you are using GLFW as a shared library and\n *  want to ensure that you are using the minimum required version.\n *\n *  Any or all of the version arguments may be `NULL`.\n *\n *  @param[out] major Where to store the major version number, or `NULL`.\n *  @param[out] minor Where to store the minor version number, or `NULL`.\n *  @param[out] rev Where to store the revision number, or `NULL`.\n *\n *  @errors None.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref intro_version\n *  @sa glfwGetVersionString\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup init\n */\nGLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);\n\n/*! @brief Returns a string describing the compile-time configuration.\n *\n *  This function returns the compile-time generated\n *  [version string](@ref intro_version_string) of the GLFW library binary.  It\n *  describes the version, platform, compiler and any platform-specific\n *  compile-time options.  It should not be confused with the OpenGL or OpenGL\n *  ES version string, queried with `glGetString`.\n *\n *  __Do not use the version string__ to parse the GLFW library version.  The\n *  @ref glfwGetVersion function provides the version of the running library\n *  binary in numerical format.\n *\n *  @return The ASCII encoded GLFW version string.\n *\n *  @errors None.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @pointer_lifetime The returned string is static and compile-time generated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref intro_version\n *  @sa glfwGetVersion\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup init\n */\nGLFWAPI const char* glfwGetVersionString(void);\n\n/*! @brief Sets the error callback.\n *\n *  This function sets the error callback, which is called with an error code\n *  and a human-readable description each time a GLFW error occurs.\n *\n *  The error callback is called on the thread where the error occurred.  If you\n *  are using GLFW from multiple threads, your error callback needs to be\n *  written accordingly.\n *\n *  Because the description string may have been generated specifically for that\n *  error, it is not guaranteed to be valid after the callback has returned.  If\n *  you wish to use it after the callback returns, you need to make a copy.\n *\n *  Once set, the error callback remains set even after the library has been\n *  terminated.\n *\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set.\n *\n *  @errors None.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref error_handling\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup init\n */\nGLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);\n\n/*! @brief Returns the currently connected monitors.\n *\n *  This function returns an array of handles for all currently connected\n *  monitors.  The primary monitor is always first in the returned array.  If no\n *  monitors were found, this function returns `NULL`.\n *\n *  @param[out] count Where to store the number of monitors in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of monitor handles, or `NULL` if no monitors were found or\n *  if an [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is guaranteed to be valid only until the\n *  monitor configuration changes or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_monitors\n *  @sa @ref monitor_event\n *  @sa glfwGetPrimaryMonitor\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI GLFWmonitor** glfwGetMonitors(int* count);\n\n/*! @brief Returns the primary monitor.\n *\n *  This function returns the primary monitor.  This is usually the monitor\n *  where elements like the task bar or global menu bar are located.\n *\n *  @return The primary monitor, or `NULL` if no monitors were found or if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @remark The primary monitor is always first in the array returned by @ref\n *  glfwGetMonitors.\n *\n *  @sa @ref monitor_monitors\n *  @sa glfwGetMonitors\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);\n\n/*! @brief Returns the position of the monitor's viewport on the virtual screen.\n *\n *  This function returns the position, in screen coordinates, of the upper-left\n *  corner of the specified monitor.\n *\n *  Any or all of the position arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` position arguments will be set to zero.\n *\n *  @param[in] monitor The monitor to query.\n *  @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.\n *  @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_properties\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);\n\n/*! @brief Returns the physical size of the monitor.\n *\n *  This function returns the size, in millimetres, of the display area of the\n *  specified monitor.\n *\n *  Some systems do not provide accurate monitor size information, either\n *  because the monitor\n *  [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)\n *  data is incorrect or because the driver does not report it accurately.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] monitor The monitor to query.\n *  @param[out] widthMM Where to store the width, in millimetres, of the\n *  monitor's display area, or `NULL`.\n *  @param[out] heightMM Where to store the height, in millimetres, of the\n *  monitor's display area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @remark @win32 calculates the returned physical size from the\n *  current resolution and system DPI instead of querying the monitor EDID data.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_properties\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);\n\n/*! @brief Returns the name of the specified monitor.\n *\n *  This function returns a human-readable name, encoded as UTF-8, of the\n *  specified monitor.  The name typically reflects the make and model of the\n *  monitor and is not guaranteed to be unique among the connected monitors.\n *\n *  @param[in] monitor The monitor to query.\n *  @return The UTF-8 encoded name of the monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified monitor is\n *  disconnected or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_properties\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);\n\n/*! @brief Sets the monitor configuration callback.\n *\n *  This function sets the monitor configuration callback, or removes the\n *  currently set callback.  This is called when a monitor is connected to or\n *  disconnected from the system.\n *\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_event\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);\n\n/*! @brief Returns the available video modes for the specified monitor.\n *\n *  This function returns an array of all video modes supported by the specified\n *  monitor.  The returned array is sorted in ascending order, first by color\n *  bit depth (the sum of all channel depths) and then by resolution area (the\n *  product of width and height).\n *\n *  @param[in] monitor The monitor to query.\n *  @param[out] count Where to store the number of video modes in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of video modes, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified monitor is\n *  disconnected, this function is called again for that monitor or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_modes\n *  @sa glfwGetVideoMode\n *\n *  @since Added in version 1.0.\n *  @glfw3 Changed to return an array of modes for a specific monitor.\n *\n *  @ingroup monitor\n */\nGLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);\n\n/*! @brief Returns the current mode of the specified monitor.\n *\n *  This function returns the current video mode of the specified monitor.  If\n *  you have created a full screen window for that monitor, the return value\n *  will depend on whether that window is iconified.\n *\n *  @param[in] monitor The monitor to query.\n *  @return The current mode of the monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified monitor is\n *  disconnected or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_modes\n *  @sa glfwGetVideoModes\n *\n *  @since Added in version 3.0.  Replaces `glfwGetDesktopMode`.\n *\n *  @ingroup monitor\n */\nGLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);\n\n/*! @brief Generates a gamma ramp and sets it for the specified monitor.\n *\n *  This function generates a 256-element gamma ramp from the specified exponent\n *  and then calls @ref glfwSetGammaRamp with it.  The value must be a finite\n *  number greater than zero.\n *\n *  @param[in] monitor The monitor whose gamma ramp to set.\n *  @param[in] gamma The desired exponent.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_gamma\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);\n\n/*! @brief Returns the current gamma ramp for the specified monitor.\n *\n *  This function returns the current gamma ramp of the specified monitor.\n *\n *  @param[in] monitor The monitor to query.\n *  @return The current gamma ramp, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned structure and its arrays are allocated and\n *  freed by GLFW.  You should not free them yourself.  They are valid until the\n *  specified monitor is disconnected, this function is called again for that\n *  monitor or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_gamma\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);\n\n/*! @brief Sets the current gamma ramp for the specified monitor.\n *\n *  This function sets the current gamma ramp for the specified monitor.  The\n *  original gamma ramp for that monitor is saved by GLFW the first time this\n *  function is called and is restored by @ref glfwTerminate.\n *\n *  @param[in] monitor The monitor whose gamma ramp to set.\n *  @param[in] ramp The gamma ramp to use.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @remark Gamma ramp sizes other than 256 are not supported by all platforms\n *  or graphics hardware.\n *\n *  @remark @win32 The gamma ramp size must be 256.\n *\n *  @pointer_lifetime The specified gamma ramp is copied before this function\n *  returns.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_gamma\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);\n\n/*! @brief Resets all window hints to their default values.\n *\n *  This function resets all window hints to their\n *  [default values](@ref window_hints_values).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hints\n *  @sa glfwWindowHint\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwDefaultWindowHints(void);\n\n/*! @brief Sets the specified window hint to the desired value.\n *\n *  This function sets hints for the next call to @ref glfwCreateWindow.  The\n *  hints, once set, retain their values until changed by a call to @ref\n *  glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is\n *  terminated.\n *\n *  This function does not check whether the specified hint values are valid.\n *  If you set hints to invalid values this will instead be reported by the next\n *  call to @ref glfwCreateWindow.\n *\n *  @param[in] hint The [window hint](@ref window_hints) to set.\n *  @param[in] value The new value of the window hint.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hints\n *  @sa glfwDefaultWindowHints\n *\n *  @since Added in version 3.0.  Replaces `glfwOpenWindowHint`.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwWindowHint(int hint, int value);\n\n/*! @brief Creates a window and its associated context.\n *\n *  This function creates a window and its associated OpenGL or OpenGL ES\n *  context.  Most of the options controlling how the window and its context\n *  should be created are specified with [window hints](@ref window_hints).\n *\n *  Successful creation does not change which context is current.  Before you\n *  can use the newly created context, you need to\n *  [make it current](@ref context_current).  For information about the `share`\n *  parameter, see @ref context_sharing.\n *\n *  The created window, framebuffer and context may differ from what you\n *  requested, as not all parameters and hints are\n *  [hard constraints](@ref window_hints_hard).  This includes the size of the\n *  window, especially for full screen windows.  To query the actual attributes\n *  of the created window, framebuffer and context, see @ref\n *  glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.\n *\n *  To create a full screen window, you need to specify the monitor the window\n *  will cover.  If no monitor is specified, the window will be windowed mode.\n *  Unless you have a way for the user to choose a specific monitor, it is\n *  recommended that you pick the primary monitor.  For more information on how\n *  to query connected monitors, see @ref monitor_monitors.\n *\n *  For full screen windows, the specified size becomes the resolution of the\n *  window's _desired video mode_.  As long as a full screen window is not\n *  iconified, the supported video mode most closely matching the desired video\n *  mode is set for the specified monitor.  For more information about full\n *  screen windows, including the creation of so called _windowed full screen_\n *  or _borderless full screen_ windows, see @ref window_windowed_full_screen.\n *\n *  By default, newly created windows use the placement recommended by the\n *  window system.  To create the window at a specific position, make it\n *  initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window\n *  hint, set its [position](@ref window_pos) and then [show](@ref window_hide)\n *  it.\n *\n *  As long as at least one full screen window is not iconified, the screensaver\n *  is prohibited from starting.\n *\n *  Window systems put limits on window sizes.  Very large or very small window\n *  dimensions may be overridden by the window system on creation.  Check the\n *  actual [size](@ref window_size) after creation.\n *\n *  The [swap interval](@ref buffer_swap) is not set during window creation and\n *  the initial value may vary depending on driver settings and defaults.\n *\n *  @param[in] width The desired width, in screen coordinates, of the window.\n *  This must be greater than zero.\n *  @param[in] height The desired height, in screen coordinates, of the window.\n *  This must be greater than zero.\n *  @param[in] title The initial, UTF-8 encoded window title.\n *  @param[in] monitor The monitor to use for full screen mode, or `NULL` for\n *  windowed mode.\n *  @param[in] share The window whose context to share resources with, or `NULL`\n *  to not share resources.\n *  @return The handle of the created window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref\n *  GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @remark @win32 Window creation will fail if the Microsoft GDI software\n *  OpenGL implementation is the only one available.\n *\n *  @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it\n *  will be set as the initial icon for the window.  If no such icon is present,\n *  the `IDI_WINLOGO` icon will be used instead.  To set a different icon, see\n *  @ref glfwSetWindowIcon.\n *\n *  @remark @win32 The context to share resources with must not be current on\n *  any other thread.\n *\n *  @remark @osx The GLFW window has no icon, as it is not a document\n *  window, but the dock icon will be the same as the application bundle's icon.\n *  For more information on bundles, see the\n *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)\n *  in the Mac Developer Library.\n *\n *  @remark @osx The first time a window is created the menu bar is populated\n *  with common commands like Hide, Quit and About.  The About entry opens\n *  a minimal about dialog with information from the application's bundle.  The\n *  menu bar can be disabled with a\n *  [compile-time option](@ref compile_options_osx).\n *\n *  @remark @osx On OS X 10.10 and later the window frame will not be rendered\n *  at full resolution on Retina displays unless the `NSHighResolutionCapable`\n *  key is enabled in the application bundle's `Info.plist`.  For more\n *  information, see\n *  [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)\n *  in the Mac Developer Library.  The GLFW test and example programs use\n *  a custom `Info.plist` template for this, which can be found as\n *  `CMake/MacOSXBundleInfo.plist.in` in the source tree.\n *\n *  @remark @x11 Some window managers will not respect the placement of\n *  initially hidden windows.\n *\n *  @remark @x11 Due to the asynchronous nature of X11, it may take a moment for\n *  a window to reach its requested state.  This means you may not be able to\n *  query the final size, position or other attributes directly after window\n *  creation.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_creation\n *  @sa glfwDestroyWindow\n *\n *  @since Added in version 3.0.  Replaces `glfwOpenWindow`.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);\n\n/*! @brief Destroys the specified window and its context.\n *\n *  This function destroys the specified window and its context.  On calling\n *  this function, no further callbacks will be called for that window.\n *\n *  If the context of the specified window is current on the main thread, it is\n *  detached before being destroyed.\n *\n *  @param[in] window The window to destroy.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @note The context of the specified window must not be current on any other\n *  thread when this function is called.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_creation\n *  @sa glfwCreateWindow\n *\n *  @since Added in version 3.0.  Replaces `glfwCloseWindow`.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwDestroyWindow(GLFWwindow* window);\n\n/*! @brief Checks the close flag of the specified window.\n *\n *  This function returns the value of the close flag of the specified window.\n *\n *  @param[in] window The window to query.\n *  @return The value of the close flag.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_close\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI int glfwWindowShouldClose(GLFWwindow* window);\n\n/*! @brief Sets the close flag of the specified window.\n *\n *  This function sets the value of the close flag of the specified window.\n *  This can be used to override the user's attempt to close the window, or\n *  to signal that it should be closed.\n *\n *  @param[in] window The window whose flag to change.\n *  @param[in] value The new value.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_close\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);\n\n/*! @brief Sets the title of the specified window.\n *\n *  This function sets the window title, encoded as UTF-8, of the specified\n *  window.\n *\n *  @param[in] window The window whose title to change.\n *  @param[in] title The UTF-8 encoded window title.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @remark @osx The window title will not be updated until the next time you\n *  process events.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_title\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);\n\n/*! @brief Sets the icon for the specified window.\n *\n *  This function sets the icon of the specified window.  If passed an array of\n *  candidate images, those of or closest to the sizes desired by the system are\n *  selected.  If no images are specified, the window reverts to its default\n *  icon.\n *\n *  The desired image sizes varies depending on platform and system settings.\n *  The selected images will be rescaled as needed.  Good sizes include 16x16,\n *  32x32 and 48x48.\n *\n *  @param[in] window The window whose icon to set.\n *  @param[in] count The number of images in the specified array, or zero to\n *  revert to the default window icon.\n *  @param[in] images The images to create the icon from.  This is ignored if\n *  count is zero.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The specified image data is copied before this function\n *  returns.\n *\n *  @remark @osx The GLFW window has no icon, as it is not a document\n *  window, so this function does nothing.  The dock icon will be the same as\n *  the application bundle's icon.  For more information on bundles, see the\n *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)\n *  in the Mac Developer Library.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_icon\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);\n\n/*! @brief Retrieves the position of the client area of the specified window.\n *\n *  This function retrieves the position, in screen coordinates, of the\n *  upper-left corner of the client area of the specified window.\n *\n *  Any or all of the position arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` position arguments will be set to zero.\n *\n *  @param[in] window The window to query.\n *  @param[out] xpos Where to store the x-coordinate of the upper-left corner of\n *  the client area, or `NULL`.\n *  @param[out] ypos Where to store the y-coordinate of the upper-left corner of\n *  the client area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_pos\n *  @sa glfwSetWindowPos\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);\n\n/*! @brief Sets the position of the client area of the specified window.\n *\n *  This function sets the position, in screen coordinates, of the upper-left\n *  corner of the client area of the specified windowed mode window.  If the\n *  window is a full screen window, this function does nothing.\n *\n *  __Do not use this function__ to move an already visible window unless you\n *  have very good reasons for doing so, as it will confuse and annoy the user.\n *\n *  The window manager may put limits on what positions are allowed.  GLFW\n *  cannot and should not override these limits.\n *\n *  @param[in] window The window to query.\n *  @param[in] xpos The x-coordinate of the upper-left corner of the client area.\n *  @param[in] ypos The y-coordinate of the upper-left corner of the client area.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_pos\n *  @sa glfwGetWindowPos\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);\n\n/*! @brief Retrieves the size of the client area of the specified window.\n *\n *  This function retrieves the size, in screen coordinates, of the client area\n *  of the specified window.  If you wish to retrieve the size of the\n *  framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] window The window whose size to retrieve.\n *  @param[out] width Where to store the width, in screen coordinates, of the\n *  client area, or `NULL`.\n *  @param[out] height Where to store the height, in screen coordinates, of the\n *  client area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *  @sa glfwSetWindowSize\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);\n\n/*! @brief Sets the size limits of the specified window.\n *\n *  This function sets the size limits of the client area of the specified\n *  window.  If the window is full screen, the size limits only take effect\n *  once it is made windowed.  If the window is not resizable, this function\n *  does nothing.\n *\n *  The size limits are applied immediately to a windowed mode window and may\n *  cause it to be resized.\n *\n *  The maximum dimensions must be greater than or equal to the minimum\n *  dimensions and all must be greater than or equal to zero.\n *\n *  @param[in] window The window to set limits for.\n *  @param[in] minwidth The minimum width, in screen coordinates, of the client\n *  area, or `GLFW_DONT_CARE`.\n *  @param[in] minheight The minimum height, in screen coordinates, of the\n *  client area, or `GLFW_DONT_CARE`.\n *  @param[in] maxwidth The maximum width, in screen coordinates, of the client\n *  area, or `GLFW_DONT_CARE`.\n *  @param[in] maxheight The maximum height, in screen coordinates, of the\n *  client area, or `GLFW_DONT_CARE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark If you set size limits and an aspect ratio that conflict, the\n *  results are undefined.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_sizelimits\n *  @sa glfwSetWindowAspectRatio\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);\n\n/*! @brief Sets the aspect ratio of the specified window.\n *\n *  This function sets the required aspect ratio of the client area of the\n *  specified window.  If the window is full screen, the aspect ratio only takes\n *  effect once it is made windowed.  If the window is not resizable, this\n *  function does nothing.\n *\n *  The aspect ratio is specified as a numerator and a denominator and both\n *  values must be greater than zero.  For example, the common 16:9 aspect ratio\n *  is specified as 16 and 9, respectively.\n *\n *  If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect\n *  ratio limit is disabled.\n *\n *  The aspect ratio is applied immediately to a windowed mode window and may\n *  cause it to be resized.\n *\n *  @param[in] window The window to set limits for.\n *  @param[in] numer The numerator of the desired aspect ratio, or\n *  `GLFW_DONT_CARE`.\n *  @param[in] denom The denominator of the desired aspect ratio, or\n *  `GLFW_DONT_CARE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark If you set size limits and an aspect ratio that conflict, the\n *  results are undefined.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_sizelimits\n *  @sa glfwSetWindowSizeLimits\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);\n\n/*! @brief Sets the size of the client area of the specified window.\n *\n *  This function sets the size, in screen coordinates, of the client area of\n *  the specified window.\n *\n *  For full screen windows, this function updates the resolution of its desired\n *  video mode and switches to the video mode closest to it, without affecting\n *  the window's context.  As the context is unaffected, the bit depths of the\n *  framebuffer remain unchanged.\n *\n *  If you wish to update the refresh rate of the desired video mode in addition\n *  to its resolution, see @ref glfwSetWindowMonitor.\n *\n *  The window manager may put limits on what sizes are allowed.  GLFW cannot\n *  and should not override these limits.\n *\n *  @param[in] window The window to resize.\n *  @param[in] width The desired width, in screen coordinates, of the window\n *  client area.\n *  @param[in] height The desired height, in screen coordinates, of the window\n *  client area.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *  @sa glfwGetWindowSize\n *  @sa glfwSetWindowMonitor\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);\n\n/*! @brief Retrieves the size of the framebuffer of the specified window.\n *\n *  This function retrieves the size, in pixels, of the framebuffer of the\n *  specified window.  If you wish to retrieve the size of the window in screen\n *  coordinates, see @ref glfwGetWindowSize.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] window The window whose framebuffer to query.\n *  @param[out] width Where to store the width, in pixels, of the framebuffer,\n *  or `NULL`.\n *  @param[out] height Where to store the height, in pixels, of the framebuffer,\n *  or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_fbsize\n *  @sa glfwSetFramebufferSizeCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);\n\n/*! @brief Retrieves the size of the frame of the window.\n *\n *  This function retrieves the size, in screen coordinates, of each edge of the\n *  frame of the specified window.  This size includes the title bar, if the\n *  window has one.  The size of the frame may vary depending on the\n *  [window-related hints](@ref window_hints_wnd) used to create it.\n *\n *  Because this function retrieves the size of each window frame edge and not\n *  the offset along a particular coordinate axis, the retrieved values will\n *  always be zero or positive.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] window The window whose frame size to query.\n *  @param[out] left Where to store the size, in screen coordinates, of the left\n *  edge of the window frame, or `NULL`.\n *  @param[out] top Where to store the size, in screen coordinates, of the top\n *  edge of the window frame, or `NULL`.\n *  @param[out] right Where to store the size, in screen coordinates, of the\n *  right edge of the window frame, or `NULL`.\n *  @param[out] bottom Where to store the size, in screen coordinates, of the\n *  bottom edge of the window frame, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);\n\n/*! @brief Iconifies the specified window.\n *\n *  This function iconifies (minimizes) the specified window if it was\n *  previously restored.  If the window is already iconified, this function does\n *  nothing.\n *\n *  If the specified window is a full screen window, the original monitor\n *  resolution is restored until the window is restored.\n *\n *  @param[in] window The window to iconify.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *  @sa glfwRestoreWindow\n *  @sa glfwMaximizeWindow\n *\n *  @since Added in version 2.1.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwIconifyWindow(GLFWwindow* window);\n\n/*! @brief Restores the specified window.\n *\n *  This function restores the specified window if it was previously iconified\n *  (minimized) or maximized.  If the window is already restored, this function\n *  does nothing.\n *\n *  If the specified window is a full screen window, the resolution chosen for\n *  the window is restored on the selected monitor.\n *\n *  @param[in] window The window to restore.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *  @sa glfwIconifyWindow\n *  @sa glfwMaximizeWindow\n *\n *  @since Added in version 2.1.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwRestoreWindow(GLFWwindow* window);\n\n/*! @brief Maximizes the specified window.\n *\n *  This function maximizes the specified window if it was previously not\n *  maximized.  If the window is already maximized, this function does nothing.\n *\n *  If the specified window is a full screen window, this function does nothing.\n *\n *  @param[in] window The window to maximize.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @par Thread Safety\n *  This function may only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *  @sa glfwIconifyWindow\n *  @sa glfwRestoreWindow\n *\n *  @since Added in GLFW 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwMaximizeWindow(GLFWwindow* window);\n\n/*! @brief Makes the specified window visible.\n *\n *  This function makes the specified window visible if it was previously\n *  hidden.  If the window is already visible or is in full screen mode, this\n *  function does nothing.\n *\n *  @param[in] window The window to make visible.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hide\n *  @sa glfwHideWindow\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwShowWindow(GLFWwindow* window);\n\n/*! @brief Hides the specified window.\n *\n *  This function hides the specified window if it was previously visible.  If\n *  the window is already hidden or is in full screen mode, this function does\n *  nothing.\n *\n *  @param[in] window The window to hide.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hide\n *  @sa glfwShowWindow\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwHideWindow(GLFWwindow* window);\n\n/*! @brief Brings the specified window to front and sets input focus.\n *\n *  This function brings the specified window to front and sets input focus.\n *  The window should already be visible and not iconified.\n *\n *  By default, both windowed and full screen mode windows are focused when\n *  initially created.  Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable\n *  this behavior.\n *\n *  __Do not use this function__ to steal focus from other applications unless\n *  you are certain that is what the user wants.  Focus stealing can be\n *  extremely disruptive.\n *\n *  @param[in] window The window to give input focus.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_focus\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwFocusWindow(GLFWwindow* window);\n\n/*! @brief Returns the monitor that the window uses for full screen mode.\n *\n *  This function returns the handle of the monitor that the specified window is\n *  in full screen on.\n *\n *  @param[in] window The window to query.\n *  @return The monitor, or `NULL` if the window is in windowed mode or an error\n *  occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_monitor\n *  @sa glfwSetWindowMonitor\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);\n\n/*! @brief Sets the mode, monitor, video mode and placement of a window.\n *\n *  This function sets the monitor that the window uses for full screen mode or,\n *  if the monitor is `NULL`, makes it windowed mode.\n *\n *  When setting a monitor, this function updates the width, height and refresh\n *  rate of the desired video mode and switches to the video mode closest to it.\n *  The window position is ignored when setting a monitor.\n *\n *  When the monitor is `NULL`, the position, width and height are used to\n *  place the window client area.  The refresh rate is ignored when no monitor\n *  is specified.\n *\n *  If you only wish to update the resolution of a full screen window or the\n *  size of a windowed mode window, see @ref glfwSetWindowSize.\n *\n *  When a window transitions from full screen to windowed mode, this function\n *  restores any previous window settings such as whether it is decorated,\n *  floating, resizable, has size or aspect ratio limits, etc..\n *\n *  @param[in] window The window whose monitor, size or video mode to set.\n *  @param[in] monitor The desired monitor, or `NULL` to set windowed mode.\n *  @param[in] xpos The desired x-coordinate of the upper-left corner of the\n *  client area.\n *  @param[in] ypos The desired y-coordinate of the upper-left corner of the\n *  client area.\n *  @param[in] width The desired with, in screen coordinates, of the client area\n *  or video mode.\n *  @param[in] height The desired height, in screen coordinates, of the client\n *  area or video mode.\n *  @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,\n *  or `GLFW_DONT_CARE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_monitor\n *  @sa @ref window_full_screen\n *  @sa glfwGetWindowMonitor\n *  @sa glfwSetWindowSize\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);\n\n/*! @brief Returns an attribute of the specified window.\n *\n *  This function returns the value of an attribute of the specified window or\n *  its OpenGL or OpenGL ES context.\n *\n *  @param[in] window The window to query.\n *  @param[in] attrib The [window attribute](@ref window_attribs) whose value to\n *  return.\n *  @return The value of the attribute, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark Framebuffer related hints are not window attributes.  See @ref\n *  window_attribs_fb for more information.\n *\n *  @remark Zero is a valid value for many window and context related\n *  attributes so you cannot use a return value of zero as an indication of\n *  errors.  However, this function should not fail as long as it is passed\n *  valid arguments and the library has been [initialized](@ref intro_init).\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_attribs\n *\n *  @since Added in version 3.0.  Replaces `glfwGetWindowParam` and\n *  `glfwGetGLVersion`.\n *\n *  @ingroup window\n */\nGLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);\n\n/*! @brief Sets the user pointer of the specified window.\n *\n *  This function sets the user-defined pointer of the specified window.  The\n *  current value is retained until the window is destroyed.  The initial value\n *  is `NULL`.\n *\n *  @param[in] window The window whose pointer to set.\n *  @param[in] pointer The new value.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_userptr\n *  @sa glfwGetWindowUserPointer\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);\n\n/*! @brief Returns the user pointer of the specified window.\n *\n *  This function returns the current value of the user-defined pointer of the\n *  specified window.  The initial value is `NULL`.\n *\n *  @param[in] window The window whose pointer to return.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_userptr\n *  @sa glfwSetWindowUserPointer\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);\n\n/*! @brief Sets the position callback for the specified window.\n *\n *  This function sets the position callback of the specified window, which is\n *  called when the window is moved.  The callback is provided with the screen\n *  position of the upper-left corner of the client area of the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_pos\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);\n\n/*! @brief Sets the size callback for the specified window.\n *\n *  This function sets the size callback of the specified window, which is\n *  called when the window is resized.  The callback is provided with the size,\n *  in screen coordinates, of the client area of the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);\n\n/*! @brief Sets the close callback for the specified window.\n *\n *  This function sets the close callback of the specified window, which is\n *  called when the user attempts to close the window, for example by clicking\n *  the close widget in the title bar.\n *\n *  The close flag is set before this callback is called, but you can modify it\n *  at any time with @ref glfwSetWindowShouldClose.\n *\n *  The close callback is not triggered by @ref glfwDestroyWindow.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @remark @osx Selecting Quit from the application menu will trigger the close\n *  callback for all windows.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_close\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);\n\n/*! @brief Sets the refresh callback for the specified window.\n *\n *  This function sets the refresh callback of the specified window, which is\n *  called when the client area of the window needs to be redrawn, for example\n *  if the window has been exposed after having been covered by another window.\n *\n *  On compositing window systems such as Aero, Compiz or Aqua, where the window\n *  contents are saved off-screen, this callback may be called only very\n *  infrequently or never at all.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_refresh\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);\n\n/*! @brief Sets the focus callback for the specified window.\n *\n *  This function sets the focus callback of the specified window, which is\n *  called when the window gains or loses input focus.\n *\n *  After the focus callback is called for a window that lost input focus,\n *  synthetic key and mouse button release events will be generated for all such\n *  that had been pressed.  For more information, see @ref glfwSetKeyCallback\n *  and @ref glfwSetMouseButtonCallback.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_focus\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);\n\n/*! @brief Sets the iconify callback for the specified window.\n *\n *  This function sets the iconification callback of the specified window, which\n *  is called when the window is iconified or restored.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);\n\n/*! @brief Sets the framebuffer resize callback for the specified window.\n *\n *  This function sets the framebuffer resize callback of the specified window,\n *  which is called when the framebuffer of the specified window is resized.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_fbsize\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);\n\n/*! @brief Processes all pending events.\n *\n *  This function processes only those events that are already in the event\n *  queue and then returns immediately.  Processing events will cause the window\n *  and input callbacks associated with those events to be called.\n *\n *  On some platforms, a window move, resize or menu operation will cause event\n *  processing to block.  This is due to how event processing is designed on\n *  those platforms.  You can use the\n *  [window refresh callback](@ref window_refresh) to redraw the contents of\n *  your window when necessary during such operations.\n *\n *  On some platforms, certain events are sent directly to the application\n *  without going through the event queue, causing callbacks to be called\n *  outside of a call to one of the event processing functions.\n *\n *  Event processing is not required for joystick input to work.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref events\n *  @sa glfwWaitEvents\n *  @sa glfwWaitEventsTimeout\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwPollEvents(void);\n\n/*! @brief Waits until events are queued and processes them.\n *\n *  This function puts the calling thread to sleep until at least one event is\n *  available in the event queue.  Once one or more events are available,\n *  it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue\n *  are processed and the function then returns immediately.  Processing events\n *  will cause the window and input callbacks associated with those events to be\n *  called.\n *\n *  Since not all events are associated with callbacks, this function may return\n *  without a callback having been called even if you are monitoring all\n *  callbacks.\n *\n *  On some platforms, a window move, resize or menu operation will cause event\n *  processing to block.  This is due to how event processing is designed on\n *  those platforms.  You can use the\n *  [window refresh callback](@ref window_refresh) to redraw the contents of\n *  your window when necessary during such operations.\n *\n *  On some platforms, certain callbacks may be called outside of a call to one\n *  of the event processing functions.\n *\n *  If no windows exist, this function returns immediately.  For synchronization\n *  of threads in applications that do not create windows, use your threading\n *  library of choice.\n *\n *  Event processing is not required for joystick input to work.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref events\n *  @sa glfwPollEvents\n *  @sa glfwWaitEventsTimeout\n *\n *  @since Added in version 2.5.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwWaitEvents(void);\n\n/*! @brief Waits with timeout until events are queued and processes them.\n *\n *  This function puts the calling thread to sleep until at least one event is\n *  available in the event queue, or until the specified timeout is reached.  If\n *  one or more events are available, it behaves exactly like @ref\n *  glfwPollEvents, i.e. the events in the queue are processed and the function\n *  then returns immediately.  Processing events will cause the window and input\n *  callbacks associated with those events to be called.\n *\n *  The timeout value must be a positive finite number.\n *\n *  Since not all events are associated with callbacks, this function may return\n *  without a callback having been called even if you are monitoring all\n *  callbacks.\n *\n *  On some platforms, a window move, resize or menu operation will cause event\n *  processing to block.  This is due to how event processing is designed on\n *  those platforms.  You can use the\n *  [window refresh callback](@ref window_refresh) to redraw the contents of\n *  your window when necessary during such operations.\n *\n *  On some platforms, certain callbacks may be called outside of a call to one\n *  of the event processing functions.\n *\n *  If no windows exist, this function returns immediately.  For synchronization\n *  of threads in applications that do not create windows, use your threading\n *  library of choice.\n *\n *  Event processing is not required for joystick input to work.\n *\n *  @param[in] timeout The maximum amount of time, in seconds, to wait.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref events\n *  @sa glfwPollEvents\n *  @sa glfwWaitEvents\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwWaitEventsTimeout(double timeout);\n\n/*! @brief Posts an empty event to the event queue.\n *\n *  This function posts an empty event from the current thread to the event\n *  queue, causing @ref glfwWaitEvents to return.\n *\n *  If no windows exist, this function returns immediately.  For synchronization\n *  of threads in applications that do not create windows, use your threading\n *  library of choice.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref events\n *  @sa glfwWaitEvents\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwPostEmptyEvent(void);\n\n/*! @brief Returns the value of an input option for the specified window.\n *\n *  This function returns the value of an input option for the specified window.\n *  The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *\n *  @param[in] window The window to query.\n *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa glfwSetInputMode\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);\n\n/*! @brief Sets an input option for the specified window.\n *\n *  This function sets an input mode option for the specified window.  The mode\n *  must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *\n *  If the mode is `GLFW_CURSOR`, the value must be one of the following cursor\n *  modes:\n *  - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.\n *  - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client\n *    area of the window but does not restrict the cursor from leaving.\n *  - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual\n *    and unlimited cursor movement.  This is useful for implementing for\n *    example 3D camera controls.\n *\n *  If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to\n *  enable sticky keys, or `GLFW_FALSE` to disable it.  If sticky keys are\n *  enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`\n *  the next time it is called even if the key had been released before the\n *  call.  This is useful when you are only interested in whether keys have been\n *  pressed but not when or in which order.\n *\n *  If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either\n *  `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.\n *  If sticky mouse buttons are enabled, a mouse button press will ensure that\n *  @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even\n *  if the mouse button had been released before the call.  This is useful when\n *  you are only interested in whether mouse buttons have been pressed but not\n *  when or in which order.\n *\n *  @param[in] window The window whose input mode to set.\n *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *  @param[in] value The new value of the specified input mode.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa glfwGetInputMode\n *\n *  @since Added in version 3.0.  Replaces `glfwEnable` and `glfwDisable`.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);\n\n/*! @brief Returns the localized name of the specified printable key.\n *\n *  This function returns the localized name of the specified printable key.\n *  This is intended for displaying key bindings to the user.\n *\n *  If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise\n *  the scancode is ignored.  If a non-printable key or (if the key is\n *  `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is\n *  specified, this function returns `NULL`.          \n *\n *  This behavior allows you to pass in the arguments passed to the\n *  [key callback](@ref input_key) without modification.\n *\n *  The printable keys are:\n *  - `GLFW_KEY_APOSTROPHE`\n *  - `GLFW_KEY_COMMA`\n *  - `GLFW_KEY_MINUS`\n *  - `GLFW_KEY_PERIOD`\n *  - `GLFW_KEY_SLASH`\n *  - `GLFW_KEY_SEMICOLON`\n *  - `GLFW_KEY_EQUAL`\n *  - `GLFW_KEY_LEFT_BRACKET`\n *  - `GLFW_KEY_RIGHT_BRACKET`\n *  - `GLFW_KEY_BACKSLASH`\n *  - `GLFW_KEY_WORLD_1`\n *  - `GLFW_KEY_WORLD_2`\n *  - `GLFW_KEY_0` to `GLFW_KEY_9`\n *  - `GLFW_KEY_A` to `GLFW_KEY_Z`\n *  - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`\n *  - `GLFW_KEY_KP_DECIMAL`\n *  - `GLFW_KEY_KP_DIVIDE`\n *  - `GLFW_KEY_KP_MULTIPLY`\n *  - `GLFW_KEY_KP_SUBTRACT`\n *  - `GLFW_KEY_KP_ADD`\n *  - `GLFW_KEY_KP_EQUAL`\n *\n *  @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.\n *  @param[in] scancode The scancode of the key to query.\n *  @return The localized name of the key, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the next call to @ref\n *  glfwGetKeyName, or until the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_key_name\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI const char* glfwGetKeyName(int key, int scancode);\n\n/*! @brief Returns the last reported state of a keyboard key for the specified\n *  window.\n *\n *  This function returns the last state reported for the specified key to the\n *  specified window.  The returned state is one of `GLFW_PRESS` or\n *  `GLFW_RELEASE`.  The higher-level action `GLFW_REPEAT` is only reported to\n *  the key callback.\n *\n *  If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns\n *  `GLFW_PRESS` the first time you call it for a key that was pressed, even if\n *  that key has already been released.\n *\n *  The key functions deal with physical keys, with [key tokens](@ref keys)\n *  named after their use on the standard US keyboard layout.  If you want to\n *  input text, use the Unicode character callback instead.\n *\n *  The [modifier key bit masks](@ref mods) are not key tokens and cannot be\n *  used with this function.\n *\n *  __Do not use this function__ to implement [text input](@ref input_char).\n *\n *  @param[in] window The desired window.\n *  @param[in] key The desired [keyboard key](@ref keys).  `GLFW_KEY_UNKNOWN` is\n *  not a valid key for this function.\n *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_key\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwGetKey(GLFWwindow* window, int key);\n\n/*! @brief Returns the last reported state of a mouse button for the specified\n *  window.\n *\n *  This function returns the last state reported for the specified mouse button\n *  to the specified window.  The returned state is one of `GLFW_PRESS` or\n *  `GLFW_RELEASE`.\n *\n *  If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function\n *  `GLFW_PRESS` the first time you call it for a mouse button that was pressed,\n *  even if that mouse button has already been released.\n *\n *  @param[in] window The desired window.\n *  @param[in] button The desired [mouse button](@ref buttons).\n *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_mouse_button\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);\n\n/*! @brief Retrieves the position of the cursor relative to the client area of\n *  the window.\n *\n *  This function returns the position of the cursor, in screen coordinates,\n *  relative to the upper-left corner of the client area of the specified\n *  window.\n *\n *  If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor\n *  position is unbounded and limited only by the minimum and maximum values of\n *  a `double`.\n *\n *  The coordinate can be converted to their integer equivalents with the\n *  `floor` function.  Casting directly to an integer type works for positive\n *  coordinates, but fails for negative ones.\n *\n *  Any or all of the position arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` position arguments will be set to zero.\n *\n *  @param[in] window The desired window.\n *  @param[out] xpos Where to store the cursor x-coordinate, relative to the\n *  left edge of the client area, or `NULL`.\n *  @param[out] ypos Where to store the cursor y-coordinate, relative to the to\n *  top edge of the client area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_pos\n *  @sa glfwSetCursorPos\n *\n *  @since Added in version 3.0.  Replaces `glfwGetMousePos`.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);\n\n/*! @brief Sets the position of the cursor, relative to the client area of the\n *  window.\n *\n *  This function sets the position, in screen coordinates, of the cursor\n *  relative to the upper-left corner of the client area of the specified\n *  window.  The window must have input focus.  If the window does not have\n *  input focus when this function is called, it fails silently.\n *\n *  __Do not use this function__ to implement things like camera controls.  GLFW\n *  already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the\n *  cursor, transparently re-centers it and provides unconstrained cursor\n *  motion.  See @ref glfwSetInputMode for more information.\n *\n *  If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is\n *  unconstrained and limited only by the minimum and maximum values of\n *  a `double`.\n *\n *  @param[in] window The desired window.\n *  @param[in] xpos The desired x-coordinate, relative to the left edge of the\n *  client area.\n *  @param[in] ypos The desired y-coordinate, relative to the top edge of the\n *  client area.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_pos\n *  @sa glfwGetCursorPos\n *\n *  @since Added in version 3.0.  Replaces `glfwSetMousePos`.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);\n\n/*! @brief Creates a custom cursor.\n *\n *  Creates a new custom cursor image that can be set for a window with @ref\n *  glfwSetCursor.  The cursor can be destroyed with @ref glfwDestroyCursor.\n *  Any remaining cursors are destroyed by @ref glfwTerminate.\n *\n *  The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight\n *  bits per channel.  They are arranged canonically as packed sequential rows,\n *  starting from the top-left corner.\n *\n *  The cursor hotspot is specified in pixels, relative to the upper-left corner\n *  of the cursor image.  Like all other coordinate systems in GLFW, the X-axis\n *  points to the right and the Y-axis points down.\n *\n *  @param[in] image The desired cursor image.\n *  @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.\n *  @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.\n *  @return The handle of the created cursor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The specified image data is copied before this function\n *  returns.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *  @sa glfwDestroyCursor\n *  @sa glfwCreateStandardCursor\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);\n\n/*! @brief Creates a cursor with a standard shape.\n *\n *  Returns a cursor with a [standard shape](@ref shapes), that can be set for\n *  a window with @ref glfwSetCursor.\n *\n *  @param[in] shape One of the [standard shapes](@ref shapes).\n *  @return A new cursor ready to use or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *  @sa glfwCreateCursor\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);\n\n/*! @brief Destroys a cursor.\n *\n *  This function destroys a cursor previously created with @ref\n *  glfwCreateCursor.  Any remaining cursors will be destroyed by @ref\n *  glfwTerminate.\n *\n *  @param[in] cursor The cursor object to destroy.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *  @sa glfwCreateCursor\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);\n\n/*! @brief Sets the cursor for the window.\n *\n *  This function sets the cursor image to be used when the cursor is over the\n *  client area of the specified window.  The set cursor will only be visible\n *  when the [cursor mode](@ref cursor_mode) of the window is\n *  `GLFW_CURSOR_NORMAL`.\n *\n *  On some platforms, the set cursor may not be visible unless the window also\n *  has input focus.\n *\n *  @param[in] window The window to set the cursor for.\n *  @param[in] cursor The cursor to set, or `NULL` to switch back to the default\n *  arrow cursor.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);\n\n/*! @brief Sets the key callback.\n *\n *  This function sets the key callback of the specified window, which is called\n *  when a key is pressed, repeated or released.\n *\n *  The key functions deal with physical keys, with layout independent\n *  [key tokens](@ref keys) named after their values in the standard US keyboard\n *  layout.  If you want to input text, use the\n *  [character callback](@ref glfwSetCharCallback) instead.\n *\n *  When a window loses input focus, it will generate synthetic key release\n *  events for all pressed keys.  You can tell these events from user-generated\n *  events by the fact that the synthetic ones are generated after the focus\n *  loss event has been processed, i.e. after the\n *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.\n *\n *  The scancode of a key is specific to that platform or sometimes even to that\n *  machine.  Scancodes are intended to allow users to bind keys that don't have\n *  a GLFW key token.  Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their\n *  state is not saved and so it cannot be queried with @ref glfwGetKey.\n *\n *  Sometimes GLFW needs to generate synthetic key events, in which case the\n *  scancode may be zero.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new key callback, or `NULL` to remove the currently\n *  set callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_key\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);\n\n/*! @brief Sets the Unicode character callback.\n *\n *  This function sets the character callback of the specified window, which is\n *  called when a Unicode character is input.\n *\n *  The character callback is intended for Unicode text input.  As it deals with\n *  characters, it is keyboard layout dependent, whereas the\n *  [key callback](@ref glfwSetKeyCallback) is not.  Characters do not map 1:1\n *  to physical keys, as a key may produce zero, one or more characters.  If you\n *  want to know whether a specific physical key was pressed or released, see\n *  the key callback instead.\n *\n *  The character callback behaves as system text input normally does and will\n *  not be called if modifier keys are held down that would prevent normal text\n *  input on that platform, for example a Super (Command) key on OS X or Alt key\n *  on Windows.  There is a\n *  [character with modifiers callback](@ref glfwSetCharModsCallback) that\n *  receives these events.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_char\n *\n *  @since Added in version 2.4.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);\n\n/*! @brief Sets the Unicode character with modifiers callback.\n *\n *  This function sets the character with modifiers callback of the specified\n *  window, which is called when a Unicode character is input regardless of what\n *  modifier keys are used.\n *\n *  The character with modifiers callback is intended for implementing custom\n *  Unicode character input.  For regular Unicode text input, see the\n *  [character callback](@ref glfwSetCharCallback).  Like the character\n *  callback, the character with modifiers callback deals with characters and is\n *  keyboard layout dependent.  Characters do not map 1:1 to physical keys, as\n *  a key may produce zero, one or more characters.  If you want to know whether\n *  a specific physical key was pressed or released, see the\n *  [key callback](@ref glfwSetKeyCallback) instead.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or an\n *  error occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_char\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);\n\n/*! @brief Sets the mouse button callback.\n *\n *  This function sets the mouse button callback of the specified window, which\n *  is called when a mouse button is pressed or released.\n *\n *  When a window loses input focus, it will generate synthetic mouse button\n *  release events for all pressed mouse buttons.  You can tell these events\n *  from user-generated events by the fact that the synthetic ones are generated\n *  after the focus loss event has been processed, i.e. after the\n *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_mouse_button\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);\n\n/*! @brief Sets the cursor position callback.\n *\n *  This function sets the cursor position callback of the specified window,\n *  which is called when the cursor is moved.  The callback is provided with the\n *  position, in screen coordinates, relative to the upper-left corner of the\n *  client area of the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_pos\n *\n *  @since Added in version 3.0.  Replaces `glfwSetMousePosCallback`.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);\n\n/*! @brief Sets the cursor enter/exit callback.\n *\n *  This function sets the cursor boundary crossing callback of the specified\n *  window, which is called when the cursor enters or leaves the client area of\n *  the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_enter\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);\n\n/*! @brief Sets the scroll callback.\n *\n *  This function sets the scroll callback of the specified window, which is\n *  called when a scrolling device is used, such as a mouse wheel or scrolling\n *  area of a touchpad.\n *\n *  The scroll callback receives all scrolling input, like that from a mouse\n *  wheel or a touchpad scrolling area.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new scroll callback, or `NULL` to remove the currently\n *  set callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref scrolling\n *\n *  @since Added in version 3.0.  Replaces `glfwSetMouseWheelCallback`.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);\n\n/*! @brief Sets the file drop callback.\n *\n *  This function sets the file drop callback of the specified window, which is\n *  called when one or more dragged files are dropped on the window.\n *\n *  Because the path array and its strings may have been generated specifically\n *  for that event, they are not guaranteed to be valid after the callback has\n *  returned.  If you wish to use them after the callback returns, you need to\n *  make a deep copy.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new file drop callback, or `NULL` to remove the\n *  currently set callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref path_drop\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);\n\n/*! @brief Returns whether the specified joystick is present.\n *\n *  This function returns whether the specified joystick is present.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick\n *\n *  @since Added in version 3.0.  Replaces `glfwGetJoystickParam`.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwJoystickPresent(int joy);\n\n/*! @brief Returns the values of all axes of the specified joystick.\n *\n *  This function returns the values of all axes of the specified joystick.\n *  Each element in the array is a value between -1.0 and 1.0.\n *\n *  Querying a joystick slot with no device present is not an error, but will\n *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to\n *  check device presence.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @param[out] count Where to store the number of axis values in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of axis values, or `NULL` if the joystick is not present.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified joystick is\n *  disconnected, this function is called again for that joystick or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_axis\n *\n *  @since Added in version 3.0.  Replaces `glfwGetJoystickPos`.\n *\n *  @ingroup input\n */\nGLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);\n\n/*! @brief Returns the state of all buttons of the specified joystick.\n *\n *  This function returns the state of all buttons of the specified joystick.\n *  Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.\n *\n *  Querying a joystick slot with no device present is not an error, but will\n *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to\n *  check device presence.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @param[out] count Where to store the number of button states in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of button states, or `NULL` if the joystick is not present.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified joystick is\n *  disconnected, this function is called again for that joystick or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_button\n *\n *  @since Added in version 2.2.\n *  @glfw3 Changed to return a dynamic array.\n *\n *  @ingroup input\n */\nGLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);\n\n/*! @brief Returns the name of the specified joystick.\n *\n *  This function returns the name, encoded as UTF-8, of the specified joystick.\n *  The returned string is allocated and freed by GLFW.  You should not free it\n *  yourself.\n *\n *  Querying a joystick slot with no device present is not an error, but will\n *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to\n *  check device presence.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick\n *  is not present.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified joystick is\n *  disconnected, this function is called again for that joystick or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_name\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI const char* glfwGetJoystickName(int joy);\n\n/*! @brief Sets the joystick configuration callback.\n *\n *  This function sets the joystick configuration callback, or removes the\n *  currently set callback.  This is called when a joystick is connected to or\n *  disconnected from the system.\n *\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_event\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);\n\n/*! @brief Sets the clipboard to the specified string.\n *\n *  This function sets the system clipboard to the specified, UTF-8 encoded\n *  string.\n *\n *  @param[in] window The window that will own the clipboard contents.\n *  @param[in] string A UTF-8 encoded string.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The specified string is copied before this function\n *  returns.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref clipboard\n *  @sa glfwGetClipboardString\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);\n\n/*! @brief Returns the contents of the clipboard as a string.\n *\n *  This function returns the contents of the system clipboard, if it contains\n *  or is convertible to a UTF-8 encoded string.  If the clipboard is empty or\n *  if its contents cannot be converted, `NULL` is returned and a @ref\n *  GLFW_FORMAT_UNAVAILABLE error is generated.\n *\n *  @param[in] window The window that will request the clipboard contents.\n *  @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`\n *  if an [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the next call to @ref\n *  glfwGetClipboardString or @ref glfwSetClipboardString, or until the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref clipboard\n *  @sa glfwSetClipboardString\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);\n\n/*! @brief Returns the value of the GLFW timer.\n *\n *  This function returns the value of the GLFW timer.  Unless the timer has\n *  been set using @ref glfwSetTime, the timer measures time elapsed since GLFW\n *  was initialized.\n *\n *  The resolution of the timer is system dependent, but is usually on the order\n *  of a few micro- or nanoseconds.  It uses the highest-resolution monotonic\n *  time source on each supported platform.\n *\n *  @return The current value, in seconds, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Reading and\n *  writing of the internal timer offset is not atomic, so it needs to be\n *  externally synchronized with calls to @ref glfwSetTime.\n *\n *  @sa @ref time\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup input\n */\nGLFWAPI double glfwGetTime(void);\n\n/*! @brief Sets the GLFW timer.\n *\n *  This function sets the value of the GLFW timer.  It then continues to count\n *  up from that value.  The value must be a positive finite number less than\n *  or equal to 18446744073.0, which is approximately 584.5 years.\n *\n *  @param[in] time The new value, in seconds.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_VALUE.\n *\n *  @remark The upper limit of the timer is calculated as\n *  floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations\n *  storing nanoseconds in 64 bits.  The limit may be increased in the future.\n *\n *  @thread_safety This function may be called from any thread.  Reading and\n *  writing of the internal timer offset is not atomic, so it needs to be\n *  externally synchronized with calls to @ref glfwGetTime.\n *\n *  @sa @ref time\n *\n *  @since Added in version 2.2.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetTime(double time);\n\n/*! @brief Returns the current value of the raw timer.\n *\n *  This function returns the current value of the raw timer, measured in\n *  1&nbsp;/&nbsp;frequency seconds.  To get the frequency, call @ref\n *  glfwGetTimerFrequency.\n *\n *  @return The value of the timer, or zero if an \n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref time\n *  @sa glfwGetTimerFrequency\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI uint64_t glfwGetTimerValue(void);\n\n/*! @brief Returns the frequency, in Hz, of the raw timer.\n *\n *  This function returns the frequency, in Hz, of the raw timer.\n *\n *  @return The frequency of the timer, in Hz, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref time\n *  @sa glfwGetTimerValue\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI uint64_t glfwGetTimerFrequency(void);\n\n/*! @brief Makes the context of the specified window current for the calling\n *  thread.\n *\n *  This function makes the OpenGL or OpenGL ES context of the specified window\n *  current on the calling thread.  A context can only be made current on\n *  a single thread at a time and each thread can have only a single current\n *  context at a time.\n *\n *  By default, making a context non-current implicitly forces a pipeline flush.\n *  On machines that support `GL_KHR_context_flush_control`, you can control\n *  whether a context performs this flush by setting the\n *  [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.\n *\n *  The specified window must have an OpenGL or OpenGL ES context.  Specifying\n *  a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT\n *  error.\n *\n *  @param[in] window The window whose context to make current, or `NULL` to\n *  detach the current context.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_current\n *  @sa glfwGetCurrentContext\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup context\n */\nGLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);\n\n/*! @brief Returns the window whose context is current on the calling thread.\n *\n *  This function returns the window whose OpenGL or OpenGL ES context is\n *  current on the calling thread.\n *\n *  @return The window whose context is current, or `NULL` if no window's\n *  context is current.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_current\n *  @sa glfwMakeContextCurrent\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup context\n */\nGLFWAPI GLFWwindow* glfwGetCurrentContext(void);\n\n/*! @brief Swaps the front and back buffers of the specified window.\n *\n *  This function swaps the front and back buffers of the specified window when\n *  rendering with OpenGL or OpenGL ES.  If the swap interval is greater than\n *  zero, the GPU driver waits the specified number of screen updates before\n *  swapping the buffers.\n *\n *  The specified window must have an OpenGL or OpenGL ES context.  Specifying\n *  a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT\n *  error.\n *\n *  This function does not apply to Vulkan.  If you are rendering with Vulkan,\n *  see `vkQueuePresentKHR` instead.\n *\n *  @param[in] window The window whose buffers to swap.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark __EGL:__ The context of the specified window must be current on the\n *  calling thread.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref buffer_swap\n *  @sa glfwSwapInterval\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSwapBuffers(GLFWwindow* window);\n\n/*! @brief Sets the swap interval for the current context.\n *\n *  This function sets the swap interval for the current OpenGL or OpenGL ES\n *  context, i.e. the number of screen updates to wait from the time @ref\n *  glfwSwapBuffers was called before swapping the buffers and returning.  This\n *  is sometimes called _vertical synchronization_, _vertical retrace\n *  synchronization_ or just _vsync_.\n *\n *  Contexts that support either of the `WGL_EXT_swap_control_tear` and\n *  `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,\n *  which allow the driver to swap even if a frame arrives a little bit late.\n *  You can check for the presence of these extensions using @ref\n *  glfwExtensionSupported.  For more information about swap tearing, see the\n *  extension specifications.\n *\n *  A context must be current on the calling thread.  Calling this function\n *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.\n *\n *  This function does not apply to Vulkan.  If you are rendering with Vulkan,\n *  see the present mode of your swapchain instead.\n *\n *  @param[in] interval The minimum number of screen updates to wait for\n *  until the buffers are swapped by @ref glfwSwapBuffers.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark This function is not called during context creation, leaving the\n *  swap interval set to whatever is the default on that platform.  This is done\n *  because some swap interval extensions used by GLFW do not allow the swap\n *  interval to be reset to zero once it has been set to a non-zero value.\n *\n *  @remark Some GPU drivers do not honor the requested swap interval, either\n *  because of a user setting that overrides the application's request or due to\n *  bugs in the driver.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref buffer_swap\n *  @sa glfwSwapBuffers\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup context\n */\nGLFWAPI void glfwSwapInterval(int interval);\n\n/*! @brief Returns whether the specified extension is available.\n *\n *  This function returns whether the specified\n *  [API extension](@ref context_glext) is supported by the current OpenGL or\n *  OpenGL ES context.  It searches both for client API extension and context\n *  creation API extensions.\n *\n *  A context must be current on the calling thread.  Calling this function\n *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.\n *\n *  As this functions retrieves and searches one or more extension strings each\n *  call, it is recommended that you cache its results if it is going to be used\n *  frequently.  The extension strings will not change during the lifetime of\n *  a context, so there is no danger in doing this.\n *\n *  This function does not apply to Vulkan.  If you are using Vulkan, see @ref\n *  glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`\n *  and `vkEnumerateDeviceExtensionProperties` instead.\n *\n *  @param[in] extension The ASCII encoded name of the extension.\n *  @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`\n *  otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_glext\n *  @sa glfwGetProcAddress\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup context\n */\nGLFWAPI int glfwExtensionSupported(const char* extension);\n\n/*! @brief Returns the address of the specified function for the current\n *  context.\n *\n *  This function returns the address of the specified OpenGL or OpenGL ES\n *  [core or extension function](@ref context_glext), if it is supported\n *  by the current context.\n *\n *  A context must be current on the calling thread.  Calling this function\n *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.\n *\n *  This function does not apply to Vulkan.  If you are rendering with Vulkan,\n *  see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and\n *  `vkGetDeviceProcAddr` instead.\n *\n *  @param[in] procname The ASCII encoded name of the function.\n *  @return The address of the function, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark The address of a given function is not guaranteed to be the same\n *  between contexts.\n *\n *  @remark This function may return a non-`NULL` address despite the\n *  associated version or extension not being available.  Always check the\n *  context version or extension string first.\n *\n *  @pointer_lifetime The returned function pointer is valid until the context\n *  is destroyed or the library is terminated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_glext\n *  @sa glfwExtensionSupported\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup context\n */\nGLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);\n\n/*! @brief Returns whether the Vulkan loader has been found.\n *\n *  This function returns whether the Vulkan loader has been found.  This check\n *  is performed by @ref glfwInit.\n *\n *  The availability of a Vulkan loader does not by itself guarantee that window\n *  surface creation or even device creation is possible.  Call @ref\n *  glfwGetRequiredInstanceExtensions to check whether the extensions necessary\n *  for Vulkan surface creation are available and @ref\n *  glfwGetPhysicalDevicePresentationSupport to check whether a queue family of\n *  a physical device supports image presentation.\n *\n *  @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref vulkan_support\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI int glfwVulkanSupported(void);\n\n/*! @brief Returns the Vulkan instance extensions required by GLFW.\n *\n *  This function returns an array of names of Vulkan instance extensions required\n *  by GLFW for creating Vulkan surfaces for GLFW windows.  If successful, the\n *  list will always contains `VK_KHR_surface`, so if you don't require any\n *  additional extensions you can pass this list directly to the\n *  `VkInstanceCreateInfo` struct.\n *\n *  If Vulkan is not available on the machine, this function returns `NULL` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported\n *  to check whether Vulkan is available.\n *\n *  If Vulkan is available but no set of extensions allowing window surface\n *  creation was found, this function returns `NULL`.  You may still use Vulkan\n *  for off-screen rendering and compute work.\n *\n *  @param[out] count Where to store the number of extensions in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of ASCII encoded extension names, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_API_UNAVAILABLE.\n *\n *  @remarks Additional extensions may be required by future versions of GLFW.\n *  You should check if any extensions you wish to enable are already in the\n *  returned array, as it is an error to specify an extension more than once in\n *  the `VkInstanceCreateInfo` struct.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is guaranteed to be valid only until the\n *  library is terminated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref vulkan_ext\n *  @sa glfwCreateWindowSurface\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);\n\n#if defined(VK_VERSION_1_0)\n\n/*! @brief Returns the address of the specified Vulkan instance function.\n *\n *  This function returns the address of the specified Vulkan core or extension\n *  function for the specified instance.  If instance is set to `NULL` it can\n *  return any function exported from the Vulkan loader, including at least the\n *  following functions:\n *\n *  - `vkEnumerateInstanceExtensionProperties`\n *  - `vkEnumerateInstanceLayerProperties`\n *  - `vkCreateInstance`\n *  - `vkGetInstanceProcAddr`\n *\n *  If Vulkan is not available on the machine, this function returns `NULL` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported\n *  to check whether Vulkan is available.\n *\n *  This function is equivalent to calling `vkGetInstanceProcAddr` with\n *  a platform-specific query of the Vulkan loader as a fallback.\n *\n *  @param[in] instance The Vulkan instance to query, or `NULL` to retrieve\n *  functions related to instance creation.\n *  @param[in] procname The ASCII encoded name of the function.\n *  @return The address of the function, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_API_UNAVAILABLE.\n *\n *  @pointer_lifetime The returned function pointer is valid until the library\n *  is terminated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref vulkan_proc\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);\n\n/*! @brief Returns whether the specified queue family can present images.\n *\n *  This function returns whether the specified queue family of the specified\n *  physical device supports presentation to the platform GLFW was built for.\n *\n *  If Vulkan or the required window surface creation instance extensions are\n *  not available on the machine, or if the specified instance was not created\n *  with the required extensions, this function returns `GLFW_FALSE` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported\n *  to check whether Vulkan is available and @ref\n *  glfwGetRequiredInstanceExtensions to check what instance extensions are\n *  required.\n *\n *  @param[in] instance The instance that the physical device belongs to.\n *  @param[in] device The physical device that the queue family belongs to.\n *  @param[in] queuefamily The index of the queue family to query.\n *  @return `GLFW_TRUE` if the queue family supports presentation, or\n *  `GLFW_FALSE` otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.  For\n *  synchronization details of Vulkan objects, see the Vulkan specification.\n *\n *  @sa @ref vulkan_present\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);\n\n/*! @brief Creates a Vulkan surface for the specified window.\n *\n *  This function creates a Vulkan surface for the specified window.\n *\n *  If the Vulkan loader was not found at initialization, this function returns\n *  `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE\n *  error.  Call @ref glfwVulkanSupported to check whether the Vulkan loader was\n *  found.\n *\n *  If the required window surface creation instance extensions are not\n *  available or if the specified instance was not created with these extensions\n *  enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref\n *  glfwGetRequiredInstanceExtensions to check what instance extensions are\n *  required.\n *\n *  The window surface must be destroyed before the specified Vulkan instance.\n *  It is the responsibility of the caller to destroy the window surface.  GLFW\n *  does not destroy it for you.  Call `vkDestroySurfaceKHR` to destroy the\n *  surface.\n *\n *  @param[in] instance The Vulkan instance to create the surface in.\n *  @param[in] window The window to create the surface for.\n *  @param[in] allocator The allocator to use, or `NULL` to use the default\n *  allocator.\n *  @param[out] surface Where to store the handle of the surface.  This is set\n *  to `VK_NULL_HANDLE` if an error occurred.\n *  @return `VK_SUCCESS` if successful, or a Vulkan error code if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remarks If an error occurs before the creation call is made, GLFW returns\n *  the Vulkan error code most appropriate for the error.  Appropriate use of\n *  @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should\n *  eliminate almost all occurrences of these errors.\n *\n *  @thread_safety This function may be called from any thread.  For\n *  synchronization details of Vulkan objects, see the Vulkan specification.\n *\n *  @sa @ref vulkan_surface\n *  @sa glfwGetRequiredInstanceExtensions\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);\n\n#endif /*VK_VERSION_1_0*/\n\n\n/*************************************************************************\n * Global definition cleanup\n *************************************************************************/\n\n/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */\n\n#ifdef GLFW_WINGDIAPI_DEFINED\n #undef WINGDIAPI\n #undef GLFW_WINGDIAPI_DEFINED\n#endif\n\n#ifdef GLFW_CALLBACK_DEFINED\n #undef CALLBACK\n #undef GLFW_CALLBACK_DEFINED\n#endif\n\n/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _glfw3_h_ */\n\n"
  },
  {
    "path": "samples/vs2015/glfw-3.2-WIN32/include/GLFW/glfw3native.h",
    "content": "/*************************************************************************\n * GLFW 3.2 - www.glfw.org\n * A library for OpenGL, window and input\n *------------------------------------------------------------------------\n * Copyright (c) 2002-2006 Marcus Geelnard\n * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n *\n *************************************************************************/\n\n#ifndef _glfw3_native_h_\n#define _glfw3_native_h_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/*************************************************************************\n * Doxygen documentation\n *************************************************************************/\n\n/*! @file glfw3native.h\n *  @brief The header of the native access functions.\n *\n *  This is the header file of the native access functions.  See @ref native for\n *  more information.\n */\n/*! @defgroup native Native access\n *\n *  **By using the native access functions you assert that you know what you're\n *  doing and how to fix problems caused by using them.  If you don't, you\n *  shouldn't be using them.**\n *\n *  Before the inclusion of @ref glfw3native.h, you may define exactly one\n *  window system API macro and zero or more context creation API macros.\n *\n *  The chosen backends must match those the library was compiled for.  Failure\n *  to do this will cause a link-time error.\n *\n *  The available window API macros are:\n *  * `GLFW_EXPOSE_NATIVE_WIN32`\n *  * `GLFW_EXPOSE_NATIVE_COCOA`\n *  * `GLFW_EXPOSE_NATIVE_X11`\n *  * `GLFW_EXPOSE_NATIVE_WAYLAND`\n *  * `GLFW_EXPOSE_NATIVE_MIR`\n *\n *  The available context API macros are:\n *  * `GLFW_EXPOSE_NATIVE_WGL`\n *  * `GLFW_EXPOSE_NATIVE_NSGL`\n *  * `GLFW_EXPOSE_NATIVE_GLX`\n *  * `GLFW_EXPOSE_NATIVE_EGL`\n *\n *  These macros select which of the native access functions that are declared\n *  and which platform-specific headers to include.  It is then up your (by\n *  definition platform-specific) code to handle which of these should be\n *  defined.\n */\n\n\n/*************************************************************************\n * System headers and types\n *************************************************************************/\n\n#if defined(GLFW_EXPOSE_NATIVE_WIN32)\n // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for\n // example to allow applications to correctly declare a GL_ARB_debug_output\n // callback) but windows.h assumes no one will define APIENTRY before it does\n #undef APIENTRY\n #include <windows.h>\n#elif defined(GLFW_EXPOSE_NATIVE_COCOA)\n #include <ApplicationServices/ApplicationServices.h>\n #if defined(__OBJC__)\n  #import <Cocoa/Cocoa.h>\n #else\n  typedef void* id;\n #endif\n#elif defined(GLFW_EXPOSE_NATIVE_X11)\n #include <X11/Xlib.h>\n #include <X11/extensions/Xrandr.h>\n#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)\n #include <wayland-client.h>\n#elif defined(GLFW_EXPOSE_NATIVE_MIR)\n #include <mir_toolkit/mir_client_library.h>\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_WGL)\n /* WGL is declared by windows.h */\n#endif\n#if defined(GLFW_EXPOSE_NATIVE_NSGL)\n /* NSGL is declared by Cocoa.h */\n#endif\n#if defined(GLFW_EXPOSE_NATIVE_GLX)\n #include <GL/glx.h>\n#endif\n#if defined(GLFW_EXPOSE_NATIVE_EGL)\n #include <EGL/egl.h>\n#endif\n\n\n/*************************************************************************\n * Functions\n *************************************************************************/\n\n#if defined(GLFW_EXPOSE_NATIVE_WIN32)\n/*! @brief Returns the adapter device name of the specified monitor.\n *\n *  @return The UTF-8 encoded adapter device name (for example `\\\\.\\DISPLAY1`)\n *  of the specified monitor, or `NULL` if an [error](@ref error_handling)\n *  occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);\n\n/*! @brief Returns the display device name of the specified monitor.\n *\n *  @return The UTF-8 encoded display device name (for example\n *  `\\\\.\\DISPLAY1\\Monitor0`) of the specified monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `HWND` of the specified window.\n *\n *  @return The `HWND` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_WGL)\n/*! @brief Returns the `HGLRC` of the specified window.\n *\n *  @return The `HGLRC` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_COCOA)\n/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.\n *\n *  @return The `CGDirectDisplayID` of the specified monitor, or\n *  `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `NSWindow` of the specified window.\n *\n *  @return The `NSWindow` of the specified window, or `nil` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_NSGL)\n/*! @brief Returns the `NSOpenGLContext` of the specified window.\n *\n *  @return The `NSOpenGLContext` of the specified window, or `nil` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI id glfwGetNSGLContext(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_X11)\n/*! @brief Returns the `Display` used by GLFW.\n *\n *  @return The `Display` used by GLFW, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI Display* glfwGetX11Display(void);\n\n/*! @brief Returns the `RRCrtc` of the specified monitor.\n *\n *  @return The `RRCrtc` of the specified monitor, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);\n\n/*! @brief Returns the `RROutput` of the specified monitor.\n *\n *  @return The `RROutput` of the specified monitor, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `Window` of the specified window.\n *\n *  @return The `Window` of the specified window, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI Window glfwGetX11Window(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_GLX)\n/*! @brief Returns the `GLXContext` of the specified window.\n *\n *  @return The `GLXContext` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);\n\n/*! @brief Returns the `GLXWindow` of the specified window.\n *\n *  @return The `GLXWindow` of the specified window, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)\n/*! @brief Returns the `struct wl_display*` used by GLFW.\n *\n *  @return The `struct wl_display*` used by GLFW, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI struct wl_display* glfwGetWaylandDisplay(void);\n\n/*! @brief Returns the `struct wl_output*` of the specified monitor.\n *\n *  @return The `struct wl_output*` of the specified monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the main `struct wl_surface*` of the specified window.\n *\n *  @return The main `struct wl_surface*` of the specified window, or `NULL` if\n *  an [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_MIR)\n/*! @brief Returns the `MirConnection*` used by GLFW.\n *\n *  @return The `MirConnection*` used by GLFW, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI MirConnection* glfwGetMirDisplay(void);\n\n/*! @brief Returns the Mir output ID of the specified monitor.\n *\n *  @return The Mir output ID of the specified monitor, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `MirSurface*` of the specified window.\n *\n *  @return The `MirSurface*` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_EGL)\n/*! @brief Returns the `EGLDisplay` used by GLFW.\n *\n *  @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI EGLDisplay glfwGetEGLDisplay(void);\n\n/*! @brief Returns the `EGLContext` of the specified window.\n *\n *  @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);\n\n/*! @brief Returns the `EGLSurface` of the specified window.\n *\n *  @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _glfw3_native_h_ */\n\n"
  },
  {
    "path": "samples/vs2015/glfw-3.2-WIN64/COPYING.txt",
    "content": "Copyright (c) 2002-2006 Marcus Geelnard\nCopyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would\n   be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\n   distribution.\n\n"
  },
  {
    "path": "samples/vs2015/glfw-3.2-WIN64/include/GLFW/glfw3.h",
    "content": "/*************************************************************************\n * GLFW 3.2 - www.glfw.org\n * A library for OpenGL, window and input\n *------------------------------------------------------------------------\n * Copyright (c) 2002-2006 Marcus Geelnard\n * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n *\n *************************************************************************/\n\n#ifndef _glfw3_h_\n#define _glfw3_h_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/*************************************************************************\n * Doxygen documentation\n *************************************************************************/\n\n/*! @file glfw3.h\n *  @brief The header of the GLFW 3 API.\n *\n *  This is the header file of the GLFW 3 API.  It defines all its types and\n *  declares all its functions.\n *\n *  For more information about how to use this file, see @ref build_include.\n */\n/*! @defgroup context Context reference\n *\n *  This is the reference documentation for OpenGL and OpenGL ES context related\n *  functions.  For more task-oriented information, see the @ref context_guide.\n */\n/*! @defgroup vulkan Vulkan reference\n *\n *  This is the reference documentation for Vulkan related functions and types.\n *  For more task-oriented information, see the @ref vulkan_guide.\n */\n/*! @defgroup init Initialization, version and error reference\n *\n *  This is the reference documentation for initialization and termination of\n *  the library, version management and error handling.  For more task-oriented\n *  information, see the @ref intro_guide.\n */\n/*! @defgroup input Input reference\n *\n *  This is the reference documentation for input related functions and types.\n *  For more task-oriented information, see the @ref input_guide.\n */\n/*! @defgroup monitor Monitor reference\n *\n *  This is the reference documentation for monitor related functions and types.\n *  For more task-oriented information, see the @ref monitor_guide.\n */\n/*! @defgroup window Window reference\n *\n *  This is the reference documentation for window related functions and types,\n *  including creation, deletion and event polling.  For more task-oriented\n *  information, see the @ref window_guide.\n */\n\n\n/*************************************************************************\n * Compiler- and platform-specific preprocessor work\n *************************************************************************/\n\n/* If we are we on Windows, we want a single define for it.\n */\n#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))\n #define _WIN32\n#endif /* _WIN32 */\n\n/* It is customary to use APIENTRY for OpenGL function pointer declarations on\n * all platforms.  Additionally, the Windows OpenGL header needs APIENTRY.\n */\n#ifndef APIENTRY\n #ifdef _WIN32\n  #define APIENTRY __stdcall\n #else\n  #define APIENTRY\n #endif\n#endif /* APIENTRY */\n\n/* Some Windows OpenGL headers need this.\n */\n#if !defined(WINGDIAPI) && defined(_WIN32)\n #define WINGDIAPI __declspec(dllimport)\n #define GLFW_WINGDIAPI_DEFINED\n#endif /* WINGDIAPI */\n\n/* Some Windows GLU headers need this.\n */\n#if !defined(CALLBACK) && defined(_WIN32)\n #define CALLBACK __stdcall\n #define GLFW_CALLBACK_DEFINED\n#endif /* CALLBACK */\n\n/* Most Windows GLU headers need wchar_t.\n * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.\n * Include it unconditionally to avoid surprising side-effects.\n */\n#include <stddef.h>\n#include <stdint.h>\n\n/* Include the chosen client API headers.\n */\n#if defined(__APPLE__)\n #if defined(GLFW_INCLUDE_GLCOREARB)\n  #include <OpenGL/gl3.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <OpenGL/gl3ext.h>\n  #endif\n #elif !defined(GLFW_INCLUDE_NONE)\n  #if !defined(GLFW_INCLUDE_GLEXT)\n   #define GL_GLEXT_LEGACY\n  #endif\n  #include <OpenGL/gl.h>\n #endif\n #if defined(GLFW_INCLUDE_GLU)\n  #include <OpenGL/glu.h>\n #endif\n#else\n #if defined(GLFW_INCLUDE_GLCOREARB)\n  #include <GL/glcorearb.h>\n #elif defined(GLFW_INCLUDE_ES1)\n  #include <GLES/gl.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES/glext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_ES2)\n  #include <GLES2/gl2.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES2/gl2ext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_ES3)\n  #include <GLES3/gl3.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES2/gl2ext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_ES31)\n  #include <GLES3/gl31.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GLES2/gl2ext.h>\n  #endif\n #elif defined(GLFW_INCLUDE_VULKAN)\n  #include <vulkan/vulkan.h>\n #elif !defined(GLFW_INCLUDE_NONE)\n  #include <GL/gl.h>\n  #if defined(GLFW_INCLUDE_GLEXT)\n   #include <GL/glext.h>\n  #endif\n #endif\n #if defined(GLFW_INCLUDE_GLU)\n  #include <GL/glu.h>\n #endif\n#endif\n\n#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)\n /* GLFW_DLL must be defined by applications that are linking against the DLL\n  * version of the GLFW library.  _GLFW_BUILD_DLL is defined by the GLFW\n  * configuration header when compiling the DLL version of the library.\n  */\n #error \"You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined\"\n#endif\n\n/* GLFWAPI is used to declare public API functions for export\n * from the DLL / shared library / dynamic library.\n */\n#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)\n /* We are building GLFW as a Win32 DLL */\n #define GLFWAPI __declspec(dllexport)\n#elif defined(_WIN32) && defined(GLFW_DLL)\n /* We are calling GLFW as a Win32 DLL */\n #define GLFWAPI __declspec(dllimport)\n#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)\n /* We are building GLFW as a shared / dynamic library */\n #define GLFWAPI __attribute__((visibility(\"default\")))\n#else\n /* We are building or calling GLFW as a static library */\n #define GLFWAPI\n#endif\n\n\n/*************************************************************************\n * GLFW API tokens\n *************************************************************************/\n\n/*! @name GLFW version macros\n *  @{ */\n/*! @brief The major version number of the GLFW library.\n *\n *  This is incremented when the API is changed in non-compatible ways.\n *  @ingroup init\n */\n#define GLFW_VERSION_MAJOR          3\n/*! @brief The minor version number of the GLFW library.\n *\n *  This is incremented when features are added to the API but it remains\n *  backward-compatible.\n *  @ingroup init\n */\n#define GLFW_VERSION_MINOR          2\n/*! @brief The revision number of the GLFW library.\n *\n *  This is incremented when a bug fix release is made that does not contain any\n *  API changes.\n *  @ingroup init\n */\n#define GLFW_VERSION_REVISION       0\n/*! @} */\n\n/*! @name Boolean values\n *  @{ */\n/*! @brief One.\n *\n *  One.  Seriously.  You don't _need_ to use this symbol in your code.  It's\n *  just semantic sugar for the number 1.  You can use `1` or `true` or `_True`\n *  or `GL_TRUE` or whatever you want.\n */\n#define GLFW_TRUE                   1\n/*! @brief Zero.\n *\n *  Zero.  Seriously.  You don't _need_ to use this symbol in your code.  It's\n *  just just semantic sugar for the number 0.  You can use `0` or `false` or\n *  `_False` or `GL_FALSE` or whatever you want.\n */\n#define GLFW_FALSE                  0\n/*! @} */\n\n/*! @name Key and button actions\n *  @{ */\n/*! @brief The key or mouse button was released.\n *\n *  The key or mouse button was released.\n *\n *  @ingroup input\n */\n#define GLFW_RELEASE                0\n/*! @brief The key or mouse button was pressed.\n *\n *  The key or mouse button was pressed.\n *\n *  @ingroup input\n */\n#define GLFW_PRESS                  1\n/*! @brief The key was held down until it repeated.\n *\n *  The key was held down until it repeated.\n *\n *  @ingroup input\n */\n#define GLFW_REPEAT                 2\n/*! @} */\n\n/*! @defgroup keys Keyboard keys\n *\n *  See [key input](@ref input_key) for how these are used.\n *\n *  These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),\n *  but re-arranged to map to 7-bit ASCII for printable keys (function keys are\n *  put in the 256+ range).\n *\n *  The naming of the key codes follow these rules:\n *   - The US keyboard layout is used\n *   - Names of printable alpha-numeric characters are used (e.g. \"A\", \"R\",\n *     \"3\", etc.)\n *   - For non-alphanumeric characters, Unicode:ish names are used (e.g.\n *     \"COMMA\", \"LEFT_SQUARE_BRACKET\", etc.). Note that some names do not\n *     correspond to the Unicode standard (usually for brevity)\n *   - Keys that lack a clear US mapping are named \"WORLD_x\"\n *   - For non-printable keys, custom names are used (e.g. \"F4\",\n *     \"BACKSPACE\", etc.)\n *\n *  @ingroup input\n *  @{\n */\n\n/* The unknown key */\n#define GLFW_KEY_UNKNOWN            -1\n\n/* Printable keys */\n#define GLFW_KEY_SPACE              32\n#define GLFW_KEY_APOSTROPHE         39  /* ' */\n#define GLFW_KEY_COMMA              44  /* , */\n#define GLFW_KEY_MINUS              45  /* - */\n#define GLFW_KEY_PERIOD             46  /* . */\n#define GLFW_KEY_SLASH              47  /* / */\n#define GLFW_KEY_0                  48\n#define GLFW_KEY_1                  49\n#define GLFW_KEY_2                  50\n#define GLFW_KEY_3                  51\n#define GLFW_KEY_4                  52\n#define GLFW_KEY_5                  53\n#define GLFW_KEY_6                  54\n#define GLFW_KEY_7                  55\n#define GLFW_KEY_8                  56\n#define GLFW_KEY_9                  57\n#define GLFW_KEY_SEMICOLON          59  /* ; */\n#define GLFW_KEY_EQUAL              61  /* = */\n#define GLFW_KEY_A                  65\n#define GLFW_KEY_B                  66\n#define GLFW_KEY_C                  67\n#define GLFW_KEY_D                  68\n#define GLFW_KEY_E                  69\n#define GLFW_KEY_F                  70\n#define GLFW_KEY_G                  71\n#define GLFW_KEY_H                  72\n#define GLFW_KEY_I                  73\n#define GLFW_KEY_J                  74\n#define GLFW_KEY_K                  75\n#define GLFW_KEY_L                  76\n#define GLFW_KEY_M                  77\n#define GLFW_KEY_N                  78\n#define GLFW_KEY_O                  79\n#define GLFW_KEY_P                  80\n#define GLFW_KEY_Q                  81\n#define GLFW_KEY_R                  82\n#define GLFW_KEY_S                  83\n#define GLFW_KEY_T                  84\n#define GLFW_KEY_U                  85\n#define GLFW_KEY_V                  86\n#define GLFW_KEY_W                  87\n#define GLFW_KEY_X                  88\n#define GLFW_KEY_Y                  89\n#define GLFW_KEY_Z                  90\n#define GLFW_KEY_LEFT_BRACKET       91  /* [ */\n#define GLFW_KEY_BACKSLASH          92  /* \\ */\n#define GLFW_KEY_RIGHT_BRACKET      93  /* ] */\n#define GLFW_KEY_GRAVE_ACCENT       96  /* ` */\n#define GLFW_KEY_WORLD_1            161 /* non-US #1 */\n#define GLFW_KEY_WORLD_2            162 /* non-US #2 */\n\n/* Function keys */\n#define GLFW_KEY_ESCAPE             256\n#define GLFW_KEY_ENTER              257\n#define GLFW_KEY_TAB                258\n#define GLFW_KEY_BACKSPACE          259\n#define GLFW_KEY_INSERT             260\n#define GLFW_KEY_DELETE             261\n#define GLFW_KEY_RIGHT              262\n#define GLFW_KEY_LEFT               263\n#define GLFW_KEY_DOWN               264\n#define GLFW_KEY_UP                 265\n#define GLFW_KEY_PAGE_UP            266\n#define GLFW_KEY_PAGE_DOWN          267\n#define GLFW_KEY_HOME               268\n#define GLFW_KEY_END                269\n#define GLFW_KEY_CAPS_LOCK          280\n#define GLFW_KEY_SCROLL_LOCK        281\n#define GLFW_KEY_NUM_LOCK           282\n#define GLFW_KEY_PRINT_SCREEN       283\n#define GLFW_KEY_PAUSE              284\n#define GLFW_KEY_F1                 290\n#define GLFW_KEY_F2                 291\n#define GLFW_KEY_F3                 292\n#define GLFW_KEY_F4                 293\n#define GLFW_KEY_F5                 294\n#define GLFW_KEY_F6                 295\n#define GLFW_KEY_F7                 296\n#define GLFW_KEY_F8                 297\n#define GLFW_KEY_F9                 298\n#define GLFW_KEY_F10                299\n#define GLFW_KEY_F11                300\n#define GLFW_KEY_F12                301\n#define GLFW_KEY_F13                302\n#define GLFW_KEY_F14                303\n#define GLFW_KEY_F15                304\n#define GLFW_KEY_F16                305\n#define GLFW_KEY_F17                306\n#define GLFW_KEY_F18                307\n#define GLFW_KEY_F19                308\n#define GLFW_KEY_F20                309\n#define GLFW_KEY_F21                310\n#define GLFW_KEY_F22                311\n#define GLFW_KEY_F23                312\n#define GLFW_KEY_F24                313\n#define GLFW_KEY_F25                314\n#define GLFW_KEY_KP_0               320\n#define GLFW_KEY_KP_1               321\n#define GLFW_KEY_KP_2               322\n#define GLFW_KEY_KP_3               323\n#define GLFW_KEY_KP_4               324\n#define GLFW_KEY_KP_5               325\n#define GLFW_KEY_KP_6               326\n#define GLFW_KEY_KP_7               327\n#define GLFW_KEY_KP_8               328\n#define GLFW_KEY_KP_9               329\n#define GLFW_KEY_KP_DECIMAL         330\n#define GLFW_KEY_KP_DIVIDE          331\n#define GLFW_KEY_KP_MULTIPLY        332\n#define GLFW_KEY_KP_SUBTRACT        333\n#define GLFW_KEY_KP_ADD             334\n#define GLFW_KEY_KP_ENTER           335\n#define GLFW_KEY_KP_EQUAL           336\n#define GLFW_KEY_LEFT_SHIFT         340\n#define GLFW_KEY_LEFT_CONTROL       341\n#define GLFW_KEY_LEFT_ALT           342\n#define GLFW_KEY_LEFT_SUPER         343\n#define GLFW_KEY_RIGHT_SHIFT        344\n#define GLFW_KEY_RIGHT_CONTROL      345\n#define GLFW_KEY_RIGHT_ALT          346\n#define GLFW_KEY_RIGHT_SUPER        347\n#define GLFW_KEY_MENU               348\n\n#define GLFW_KEY_LAST               GLFW_KEY_MENU\n\n/*! @} */\n\n/*! @defgroup mods Modifier key flags\n *\n *  See [key input](@ref input_key) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n\n/*! @brief If this bit is set one or more Shift keys were held down.\n */\n#define GLFW_MOD_SHIFT           0x0001\n/*! @brief If this bit is set one or more Control keys were held down.\n */\n#define GLFW_MOD_CONTROL         0x0002\n/*! @brief If this bit is set one or more Alt keys were held down.\n */\n#define GLFW_MOD_ALT             0x0004\n/*! @brief If this bit is set one or more Super keys were held down.\n */\n#define GLFW_MOD_SUPER           0x0008\n\n/*! @} */\n\n/*! @defgroup buttons Mouse buttons\n *\n *  See [mouse button input](@ref input_mouse_button) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n#define GLFW_MOUSE_BUTTON_1         0\n#define GLFW_MOUSE_BUTTON_2         1\n#define GLFW_MOUSE_BUTTON_3         2\n#define GLFW_MOUSE_BUTTON_4         3\n#define GLFW_MOUSE_BUTTON_5         4\n#define GLFW_MOUSE_BUTTON_6         5\n#define GLFW_MOUSE_BUTTON_7         6\n#define GLFW_MOUSE_BUTTON_8         7\n#define GLFW_MOUSE_BUTTON_LAST      GLFW_MOUSE_BUTTON_8\n#define GLFW_MOUSE_BUTTON_LEFT      GLFW_MOUSE_BUTTON_1\n#define GLFW_MOUSE_BUTTON_RIGHT     GLFW_MOUSE_BUTTON_2\n#define GLFW_MOUSE_BUTTON_MIDDLE    GLFW_MOUSE_BUTTON_3\n/*! @} */\n\n/*! @defgroup joysticks Joysticks\n *\n *  See [joystick input](@ref joystick) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n#define GLFW_JOYSTICK_1             0\n#define GLFW_JOYSTICK_2             1\n#define GLFW_JOYSTICK_3             2\n#define GLFW_JOYSTICK_4             3\n#define GLFW_JOYSTICK_5             4\n#define GLFW_JOYSTICK_6             5\n#define GLFW_JOYSTICK_7             6\n#define GLFW_JOYSTICK_8             7\n#define GLFW_JOYSTICK_9             8\n#define GLFW_JOYSTICK_10            9\n#define GLFW_JOYSTICK_11            10\n#define GLFW_JOYSTICK_12            11\n#define GLFW_JOYSTICK_13            12\n#define GLFW_JOYSTICK_14            13\n#define GLFW_JOYSTICK_15            14\n#define GLFW_JOYSTICK_16            15\n#define GLFW_JOYSTICK_LAST          GLFW_JOYSTICK_16\n/*! @} */\n\n/*! @defgroup errors Error codes\n *\n *  See [error handling](@ref error_handling) for how these are used.\n *\n *  @ingroup init\n *  @{ */\n/*! @brief GLFW has not been initialized.\n *\n *  This occurs if a GLFW function was called that must not be called unless the\n *  library is [initialized](@ref intro_init).\n *\n *  @analysis Application programmer error.  Initialize GLFW before calling any\n *  function that requires initialization.\n */\n#define GLFW_NOT_INITIALIZED        0x00010001\n/*! @brief No context is current for this thread.\n *\n *  This occurs if a GLFW function was called that needs and operates on the\n *  current OpenGL or OpenGL ES context but no context is current on the calling\n *  thread.  One such function is @ref glfwSwapInterval.\n *\n *  @analysis Application programmer error.  Ensure a context is current before\n *  calling functions that require a current context.\n */\n#define GLFW_NO_CURRENT_CONTEXT     0x00010002\n/*! @brief One of the arguments to the function was an invalid enum value.\n *\n *  One of the arguments to the function was an invalid enum value, for example\n *  requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref\n *  glfwGetWindowAttrib.\n *\n *  @analysis Application programmer error.  Fix the offending call.\n */\n#define GLFW_INVALID_ENUM           0x00010003\n/*! @brief One of the arguments to the function was an invalid value.\n *\n *  One of the arguments to the function was an invalid value, for example\n *  requesting a non-existent OpenGL or OpenGL ES version like 2.7.\n *\n *  Requesting a valid but unavailable OpenGL or OpenGL ES version will instead\n *  result in a @ref GLFW_VERSION_UNAVAILABLE error.\n *\n *  @analysis Application programmer error.  Fix the offending call.\n */\n#define GLFW_INVALID_VALUE          0x00010004\n/*! @brief A memory allocation failed.\n *\n *  A memory allocation failed.\n *\n *  @analysis A bug in GLFW or the underlying operating system.  Report the bug\n *  to our [issue tracker](https://github.com/glfw/glfw/issues).\n */\n#define GLFW_OUT_OF_MEMORY          0x00010005\n/*! @brief GLFW could not find support for the requested API on the system.\n *\n *  GLFW could not find support for the requested API on the system.\n *\n *  @analysis The installed graphics driver does not support the requested\n *  API, or does not support it via the chosen context creation backend.\n *  Below are a few examples.\n *\n *  @par\n *  Some pre-installed Windows graphics drivers do not support OpenGL.  AMD only\n *  supports OpenGL ES via EGL, while Nvidia and Intel only support it via\n *  a WGL or GLX extension.  OS X does not provide OpenGL ES at all.  The Mesa\n *  EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary\n *  driver.  Older graphics drivers do not support Vulkan.\n */\n#define GLFW_API_UNAVAILABLE        0x00010006\n/*! @brief The requested OpenGL or OpenGL ES version is not available.\n *\n *  The requested OpenGL or OpenGL ES version (including any requested context\n *  or framebuffer hints) is not available on this machine.\n *\n *  @analysis The machine does not support your requirements.  If your\n *  application is sufficiently flexible, downgrade your requirements and try\n *  again.  Otherwise, inform the user that their machine does not match your\n *  requirements.\n *\n *  @par\n *  Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0\n *  comes out before the 4.x series gets that far, also fail with this error and\n *  not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions\n *  will exist.\n */\n#define GLFW_VERSION_UNAVAILABLE    0x00010007\n/*! @brief A platform-specific error occurred that does not match any of the\n *  more specific categories.\n *\n *  A platform-specific error occurred that does not match any of the more\n *  specific categories.\n *\n *  @analysis A bug or configuration error in GLFW, the underlying operating\n *  system or its drivers, or a lack of required resources.  Report the issue to\n *  our [issue tracker](https://github.com/glfw/glfw/issues).\n */\n#define GLFW_PLATFORM_ERROR         0x00010008\n/*! @brief The requested format is not supported or available.\n *\n *  If emitted during window creation, the requested pixel format is not\n *  supported.\n *\n *  If emitted when querying the clipboard, the contents of the clipboard could\n *  not be converted to the requested format.\n *\n *  @analysis If emitted during window creation, one or more\n *  [hard constraints](@ref window_hints_hard) did not match any of the\n *  available pixel formats.  If your application is sufficiently flexible,\n *  downgrade your requirements and try again.  Otherwise, inform the user that\n *  their machine does not match your requirements.\n *\n *  @par\n *  If emitted when querying the clipboard, ignore the error or report it to\n *  the user, as appropriate.\n */\n#define GLFW_FORMAT_UNAVAILABLE     0x00010009\n/*! @brief The specified window does not have an OpenGL or OpenGL ES context.\n *\n *  A window that does not have an OpenGL or OpenGL ES context was passed to\n *  a function that requires it to have one.\n *\n *  @analysis Application programmer error.  Fix the offending call.\n */\n#define GLFW_NO_WINDOW_CONTEXT      0x0001000A\n/*! @} */\n\n#define GLFW_FOCUSED                0x00020001\n#define GLFW_ICONIFIED              0x00020002\n#define GLFW_RESIZABLE              0x00020003\n#define GLFW_VISIBLE                0x00020004\n#define GLFW_DECORATED              0x00020005\n#define GLFW_AUTO_ICONIFY           0x00020006\n#define GLFW_FLOATING               0x00020007\n#define GLFW_MAXIMIZED              0x00020008\n\n#define GLFW_RED_BITS               0x00021001\n#define GLFW_GREEN_BITS             0x00021002\n#define GLFW_BLUE_BITS              0x00021003\n#define GLFW_ALPHA_BITS             0x00021004\n#define GLFW_DEPTH_BITS             0x00021005\n#define GLFW_STENCIL_BITS           0x00021006\n#define GLFW_ACCUM_RED_BITS         0x00021007\n#define GLFW_ACCUM_GREEN_BITS       0x00021008\n#define GLFW_ACCUM_BLUE_BITS        0x00021009\n#define GLFW_ACCUM_ALPHA_BITS       0x0002100A\n#define GLFW_AUX_BUFFERS            0x0002100B\n#define GLFW_STEREO                 0x0002100C\n#define GLFW_SAMPLES                0x0002100D\n#define GLFW_SRGB_CAPABLE           0x0002100E\n#define GLFW_REFRESH_RATE           0x0002100F\n#define GLFW_DOUBLEBUFFER           0x00021010\n\n#define GLFW_CLIENT_API             0x00022001\n#define GLFW_CONTEXT_VERSION_MAJOR  0x00022002\n#define GLFW_CONTEXT_VERSION_MINOR  0x00022003\n#define GLFW_CONTEXT_REVISION       0x00022004\n#define GLFW_CONTEXT_ROBUSTNESS     0x00022005\n#define GLFW_OPENGL_FORWARD_COMPAT  0x00022006\n#define GLFW_OPENGL_DEBUG_CONTEXT   0x00022007\n#define GLFW_OPENGL_PROFILE         0x00022008\n#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009\n#define GLFW_CONTEXT_NO_ERROR       0x0002200A\n#define GLFW_CONTEXT_CREATION_API   0x0002200B\n\n#define GLFW_NO_API                          0\n#define GLFW_OPENGL_API             0x00030001\n#define GLFW_OPENGL_ES_API          0x00030002\n\n#define GLFW_NO_ROBUSTNESS                   0\n#define GLFW_NO_RESET_NOTIFICATION  0x00031001\n#define GLFW_LOSE_CONTEXT_ON_RESET  0x00031002\n\n#define GLFW_OPENGL_ANY_PROFILE              0\n#define GLFW_OPENGL_CORE_PROFILE    0x00032001\n#define GLFW_OPENGL_COMPAT_PROFILE  0x00032002\n\n#define GLFW_CURSOR                 0x00033001\n#define GLFW_STICKY_KEYS            0x00033002\n#define GLFW_STICKY_MOUSE_BUTTONS   0x00033003\n\n#define GLFW_CURSOR_NORMAL          0x00034001\n#define GLFW_CURSOR_HIDDEN          0x00034002\n#define GLFW_CURSOR_DISABLED        0x00034003\n\n#define GLFW_ANY_RELEASE_BEHAVIOR            0\n#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001\n#define GLFW_RELEASE_BEHAVIOR_NONE  0x00035002\n\n#define GLFW_NATIVE_CONTEXT_API     0x00036001\n#define GLFW_EGL_CONTEXT_API        0x00036002\n\n/*! @defgroup shapes Standard cursor shapes\n *\n *  See [standard cursor creation](@ref cursor_standard) for how these are used.\n *\n *  @ingroup input\n *  @{ */\n\n/*! @brief The regular arrow cursor shape.\n *\n *  The regular arrow cursor.\n */\n#define GLFW_ARROW_CURSOR           0x00036001\n/*! @brief The text input I-beam cursor shape.\n *\n *  The text input I-beam cursor shape.\n */\n#define GLFW_IBEAM_CURSOR           0x00036002\n/*! @brief The crosshair shape.\n *\n *  The crosshair shape.\n */\n#define GLFW_CROSSHAIR_CURSOR       0x00036003\n/*! @brief The hand shape.\n *\n *  The hand shape.\n */\n#define GLFW_HAND_CURSOR            0x00036004\n/*! @brief The horizontal resize arrow shape.\n *\n *  The horizontal resize arrow shape.\n */\n#define GLFW_HRESIZE_CURSOR         0x00036005\n/*! @brief The vertical resize arrow shape.\n *\n *  The vertical resize arrow shape.\n */\n#define GLFW_VRESIZE_CURSOR         0x00036006\n/*! @} */\n\n#define GLFW_CONNECTED              0x00040001\n#define GLFW_DISCONNECTED           0x00040002\n\n#define GLFW_DONT_CARE              -1\n\n\n/*************************************************************************\n * GLFW API types\n *************************************************************************/\n\n/*! @brief Client API function pointer type.\n *\n *  Generic function pointer used for returning client API function pointers\n *  without forcing a cast from a regular pointer.\n *\n *  @sa @ref context_glext\n *  @sa glfwGetProcAddress\n *\n *  @since Added in version 3.0.\n \n *  @ingroup context\n */\ntypedef void (*GLFWglproc)(void);\n\n/*! @brief Vulkan API function pointer type.\n *\n *  Generic function pointer used for returning Vulkan API function pointers\n *  without forcing a cast from a regular pointer.\n *\n *  @sa @ref vulkan_proc\n *  @sa glfwGetInstanceProcAddress\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\ntypedef void (*GLFWvkproc)(void);\n\n/*! @brief Opaque monitor object.\n *\n *  Opaque monitor object.\n *\n *  @see @ref monitor_object\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\ntypedef struct GLFWmonitor GLFWmonitor;\n\n/*! @brief Opaque window object.\n *\n *  Opaque window object.\n *\n *  @see @ref window_object\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef struct GLFWwindow GLFWwindow;\n\n/*! @brief Opaque cursor object.\n *\n *  Opaque cursor object.\n *\n *  @see @ref cursor_object\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup cursor\n */\ntypedef struct GLFWcursor GLFWcursor;\n\n/*! @brief The function signature for error callbacks.\n *\n *  This is the function signature for error callback functions.\n *\n *  @param[in] error An [error code](@ref errors).\n *  @param[in] description A UTF-8 encoded string describing the error.\n *\n *  @sa @ref error_handling\n *  @sa glfwSetErrorCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup init\n */\ntypedef void (* GLFWerrorfun)(int,const char*);\n\n/*! @brief The function signature for window position callbacks.\n *\n *  This is the function signature for window position callback functions.\n *\n *  @param[in] window The window that was moved.\n *  @param[in] xpos The new x-coordinate, in screen coordinates, of the\n *  upper-left corner of the client area of the window.\n *  @param[in] ypos The new y-coordinate, in screen coordinates, of the\n *  upper-left corner of the client area of the window.\n *\n *  @sa @ref window_pos\n *  @sa glfwSetWindowPosCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);\n\n/*! @brief The function signature for window resize callbacks.\n *\n *  This is the function signature for window size callback functions.\n *\n *  @param[in] window The window that was resized.\n *  @param[in] width The new width, in screen coordinates, of the window.\n *  @param[in] height The new height, in screen coordinates, of the window.\n *\n *  @sa @ref window_size\n *  @sa glfwSetWindowSizeCallback\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);\n\n/*! @brief The function signature for window close callbacks.\n *\n *  This is the function signature for window close callback functions.\n *\n *  @param[in] window The window that the user attempted to close.\n *\n *  @sa @ref window_close\n *  @sa glfwSetWindowCloseCallback\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowclosefun)(GLFWwindow*);\n\n/*! @brief The function signature for window content refresh callbacks.\n *\n *  This is the function signature for window refresh callback functions.\n *\n *  @param[in] window The window whose content needs to be refreshed.\n *\n *  @sa @ref window_refresh\n *  @sa glfwSetWindowRefreshCallback\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowrefreshfun)(GLFWwindow*);\n\n/*! @brief The function signature for window focus/defocus callbacks.\n *\n *  This is the function signature for window focus callback functions.\n *\n *  @param[in] window The window that gained or lost input focus.\n *  @param[in] focused `GLFW_TRUE` if the window was given input focus, or\n *  `GLFW_FALSE` if it lost it.\n *\n *  @sa @ref window_focus\n *  @sa glfwSetWindowFocusCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);\n\n/*! @brief The function signature for window iconify/restore callbacks.\n *\n *  This is the function signature for window iconify/restore callback\n *  functions.\n *\n *  @param[in] window The window that was iconified or restored.\n *  @param[in] iconified `GLFW_TRUE` if the window was iconified, or\n *  `GLFW_FALSE` if it was restored.\n *\n *  @sa @ref window_iconify\n *  @sa glfwSetWindowIconifyCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);\n\n/*! @brief The function signature for framebuffer resize callbacks.\n *\n *  This is the function signature for framebuffer resize callback\n *  functions.\n *\n *  @param[in] window The window whose framebuffer was resized.\n *  @param[in] width The new width, in pixels, of the framebuffer.\n *  @param[in] height The new height, in pixels, of the framebuffer.\n *\n *  @sa @ref window_fbsize\n *  @sa glfwSetFramebufferSizeCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\ntypedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);\n\n/*! @brief The function signature for mouse button callbacks.\n *\n *  This is the function signature for mouse button callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] button The [mouse button](@ref buttons) that was pressed or\n *  released.\n *  @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.\n *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were\n *  held down.\n *\n *  @sa @ref input_mouse_button\n *  @sa glfwSetMouseButtonCallback\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle and modifier mask parameters.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);\n\n/*! @brief The function signature for cursor position callbacks.\n *\n *  This is the function signature for cursor position callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] xpos The new cursor x-coordinate, relative to the left edge of\n *  the client area.\n *  @param[in] ypos The new cursor y-coordinate, relative to the top edge of the\n *  client area.\n *\n *  @sa @ref cursor_pos\n *  @sa glfwSetCursorPosCallback\n *\n *  @since Added in version 3.0.  Replaces `GLFWmouseposfun`.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);\n\n/*! @brief The function signature for cursor enter/leave callbacks.\n *\n *  This is the function signature for cursor enter/leave callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] entered `GLFW_TRUE` if the cursor entered the window's client\n *  area, or `GLFW_FALSE` if it left it.\n *\n *  @sa @ref cursor_enter\n *  @sa glfwSetCursorEnterCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcursorenterfun)(GLFWwindow*,int);\n\n/*! @brief The function signature for scroll callbacks.\n *\n *  This is the function signature for scroll callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] xoffset The scroll offset along the x-axis.\n *  @param[in] yoffset The scroll offset along the y-axis.\n *\n *  @sa @ref scrolling\n *  @sa glfwSetScrollCallback\n *\n *  @since Added in version 3.0.  Replaces `GLFWmousewheelfun`.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWscrollfun)(GLFWwindow*,double,double);\n\n/*! @brief The function signature for keyboard key callbacks.\n *\n *  This is the function signature for keyboard key callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] key The [keyboard key](@ref keys) that was pressed or released.\n *  @param[in] scancode The system-specific scancode of the key.\n *  @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.\n *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were\n *  held down.\n *\n *  @sa @ref input_key\n *  @sa glfwSetKeyCallback\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle, scancode and modifier mask parameters.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);\n\n/*! @brief The function signature for Unicode character callbacks.\n *\n *  This is the function signature for Unicode character callback functions.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] codepoint The Unicode code point of the character.\n *\n *  @sa @ref input_char\n *  @sa glfwSetCharCallback\n *\n *  @since Added in version 2.4.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);\n\n/*! @brief The function signature for Unicode character with modifiers\n *  callbacks.\n *\n *  This is the function signature for Unicode character with modifiers callback\n *  functions.  It is called for each input character, regardless of what\n *  modifier keys are held down.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] codepoint The Unicode code point of the character.\n *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were\n *  held down.\n *\n *  @sa @ref input_char\n *  @sa glfwSetCharModsCallback\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);\n\n/*! @brief The function signature for file drop callbacks.\n *\n *  This is the function signature for file drop callbacks.\n *\n *  @param[in] window The window that received the event.\n *  @param[in] count The number of dropped files.\n *  @param[in] paths The UTF-8 encoded file and/or directory path names.\n *\n *  @sa @ref path_drop\n *  @sa glfwSetDropCallback\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);\n\n/*! @brief The function signature for monitor configuration callbacks.\n *\n *  This is the function signature for monitor configuration callback functions.\n *\n *  @param[in] monitor The monitor that was connected or disconnected.\n *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.\n *\n *  @sa @ref monitor_event\n *  @sa glfwSetMonitorCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\ntypedef void (* GLFWmonitorfun)(GLFWmonitor*,int);\n\n/*! @brief The function signature for joystick configuration callbacks.\n *\n *  This is the function signature for joystick configuration callback\n *  functions.\n *\n *  @param[in] joy The joystick that was connected or disconnected.\n *  @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.\n *\n *  @sa @ref joystick_event\n *  @sa glfwSetJoystickCallback\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\ntypedef void (* GLFWjoystickfun)(int,int);\n\n/*! @brief Video mode type.\n *\n *  This describes a single video mode.\n *\n *  @sa @ref monitor_modes\n *  @sa glfwGetVideoMode glfwGetVideoModes\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added refresh rate member.\n *\n *  @ingroup monitor\n */\ntypedef struct GLFWvidmode\n{\n    /*! The width, in screen coordinates, of the video mode.\n     */\n    int width;\n    /*! The height, in screen coordinates, of the video mode.\n     */\n    int height;\n    /*! The bit depth of the red channel of the video mode.\n     */\n    int redBits;\n    /*! The bit depth of the green channel of the video mode.\n     */\n    int greenBits;\n    /*! The bit depth of the blue channel of the video mode.\n     */\n    int blueBits;\n    /*! The refresh rate, in Hz, of the video mode.\n     */\n    int refreshRate;\n} GLFWvidmode;\n\n/*! @brief Gamma ramp.\n *\n *  This describes the gamma ramp for a monitor.\n *\n *  @sa @ref monitor_gamma\n *  @sa glfwGetGammaRamp glfwSetGammaRamp\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\ntypedef struct GLFWgammaramp\n{\n    /*! An array of value describing the response of the red channel.\n     */\n    unsigned short* red;\n    /*! An array of value describing the response of the green channel.\n     */\n    unsigned short* green;\n    /*! An array of value describing the response of the blue channel.\n     */\n    unsigned short* blue;\n    /*! The number of elements in each array.\n     */\n    unsigned int size;\n} GLFWgammaramp;\n\n/*! @brief Image data.\n *\n *  @sa @ref cursor_custom\n *\n *  @since Added in version 2.1.\n *  @glfw3 Removed format and bytes-per-pixel members.\n */\ntypedef struct GLFWimage\n{\n    /*! The width, in pixels, of this image.\n     */\n    int width;\n    /*! The height, in pixels, of this image.\n     */\n    int height;\n    /*! The pixel data of this image, arranged left-to-right, top-to-bottom.\n     */\n    unsigned char* pixels;\n} GLFWimage;\n\n\n/*************************************************************************\n * GLFW API functions\n *************************************************************************/\n\n/*! @brief Initializes the GLFW library.\n *\n *  This function initializes the GLFW library.  Before most GLFW functions can\n *  be used, GLFW must be initialized, and before an application terminates GLFW\n *  should be terminated in order to free any resources allocated during or\n *  after initialization.\n *\n *  If this function fails, it calls @ref glfwTerminate before returning.  If it\n *  succeeds, you should call @ref glfwTerminate before the application exits.\n *\n *  Additional calls to this function after successful initialization but before\n *  termination will return `GLFW_TRUE` immediately.\n *\n *  @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark @osx This function will change the current directory of the\n *  application to the `Contents/Resources` subdirectory of the application's\n *  bundle, if present.  This can be disabled with a\n *  [compile-time option](@ref compile_options_osx).\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref intro_init\n *  @sa glfwTerminate\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup init\n */\nGLFWAPI int glfwInit(void);\n\n/*! @brief Terminates the GLFW library.\n *\n *  This function destroys all remaining windows and cursors, restores any\n *  modified gamma ramps and frees any other allocated resources.  Once this\n *  function is called, you must again call @ref glfwInit successfully before\n *  you will be able to use most GLFW functions.\n *\n *  If GLFW has been successfully initialized, this function should be called\n *  before the application exits.  If initialization fails, there is no need to\n *  call this function, as it is called by @ref glfwInit before it returns\n *  failure.\n *\n *  @errors Possible errors include @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @warning The contexts of any remaining windows must not be current on any\n *  other thread when this function is called.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref intro_init\n *  @sa glfwInit\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup init\n */\nGLFWAPI void glfwTerminate(void);\n\n/*! @brief Retrieves the version of the GLFW library.\n *\n *  This function retrieves the major, minor and revision numbers of the GLFW\n *  library.  It is intended for when you are using GLFW as a shared library and\n *  want to ensure that you are using the minimum required version.\n *\n *  Any or all of the version arguments may be `NULL`.\n *\n *  @param[out] major Where to store the major version number, or `NULL`.\n *  @param[out] minor Where to store the minor version number, or `NULL`.\n *  @param[out] rev Where to store the revision number, or `NULL`.\n *\n *  @errors None.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref intro_version\n *  @sa glfwGetVersionString\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup init\n */\nGLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);\n\n/*! @brief Returns a string describing the compile-time configuration.\n *\n *  This function returns the compile-time generated\n *  [version string](@ref intro_version_string) of the GLFW library binary.  It\n *  describes the version, platform, compiler and any platform-specific\n *  compile-time options.  It should not be confused with the OpenGL or OpenGL\n *  ES version string, queried with `glGetString`.\n *\n *  __Do not use the version string__ to parse the GLFW library version.  The\n *  @ref glfwGetVersion function provides the version of the running library\n *  binary in numerical format.\n *\n *  @return The ASCII encoded GLFW version string.\n *\n *  @errors None.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @pointer_lifetime The returned string is static and compile-time generated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref intro_version\n *  @sa glfwGetVersion\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup init\n */\nGLFWAPI const char* glfwGetVersionString(void);\n\n/*! @brief Sets the error callback.\n *\n *  This function sets the error callback, which is called with an error code\n *  and a human-readable description each time a GLFW error occurs.\n *\n *  The error callback is called on the thread where the error occurred.  If you\n *  are using GLFW from multiple threads, your error callback needs to be\n *  written accordingly.\n *\n *  Because the description string may have been generated specifically for that\n *  error, it is not guaranteed to be valid after the callback has returned.  If\n *  you wish to use it after the callback returns, you need to make a copy.\n *\n *  Once set, the error callback remains set even after the library has been\n *  terminated.\n *\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set.\n *\n *  @errors None.\n *\n *  @remark This function may be called before @ref glfwInit.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref error_handling\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup init\n */\nGLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);\n\n/*! @brief Returns the currently connected monitors.\n *\n *  This function returns an array of handles for all currently connected\n *  monitors.  The primary monitor is always first in the returned array.  If no\n *  monitors were found, this function returns `NULL`.\n *\n *  @param[out] count Where to store the number of monitors in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of monitor handles, or `NULL` if no monitors were found or\n *  if an [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is guaranteed to be valid only until the\n *  monitor configuration changes or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_monitors\n *  @sa @ref monitor_event\n *  @sa glfwGetPrimaryMonitor\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI GLFWmonitor** glfwGetMonitors(int* count);\n\n/*! @brief Returns the primary monitor.\n *\n *  This function returns the primary monitor.  This is usually the monitor\n *  where elements like the task bar or global menu bar are located.\n *\n *  @return The primary monitor, or `NULL` if no monitors were found or if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @remark The primary monitor is always first in the array returned by @ref\n *  glfwGetMonitors.\n *\n *  @sa @ref monitor_monitors\n *  @sa glfwGetMonitors\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);\n\n/*! @brief Returns the position of the monitor's viewport on the virtual screen.\n *\n *  This function returns the position, in screen coordinates, of the upper-left\n *  corner of the specified monitor.\n *\n *  Any or all of the position arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` position arguments will be set to zero.\n *\n *  @param[in] monitor The monitor to query.\n *  @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.\n *  @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_properties\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);\n\n/*! @brief Returns the physical size of the monitor.\n *\n *  This function returns the size, in millimetres, of the display area of the\n *  specified monitor.\n *\n *  Some systems do not provide accurate monitor size information, either\n *  because the monitor\n *  [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)\n *  data is incorrect or because the driver does not report it accurately.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] monitor The monitor to query.\n *  @param[out] widthMM Where to store the width, in millimetres, of the\n *  monitor's display area, or `NULL`.\n *  @param[out] heightMM Where to store the height, in millimetres, of the\n *  monitor's display area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @remark @win32 calculates the returned physical size from the\n *  current resolution and system DPI instead of querying the monitor EDID data.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_properties\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);\n\n/*! @brief Returns the name of the specified monitor.\n *\n *  This function returns a human-readable name, encoded as UTF-8, of the\n *  specified monitor.  The name typically reflects the make and model of the\n *  monitor and is not guaranteed to be unique among the connected monitors.\n *\n *  @param[in] monitor The monitor to query.\n *  @return The UTF-8 encoded name of the monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified monitor is\n *  disconnected or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_properties\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);\n\n/*! @brief Sets the monitor configuration callback.\n *\n *  This function sets the monitor configuration callback, or removes the\n *  currently set callback.  This is called when a monitor is connected to or\n *  disconnected from the system.\n *\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_event\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);\n\n/*! @brief Returns the available video modes for the specified monitor.\n *\n *  This function returns an array of all video modes supported by the specified\n *  monitor.  The returned array is sorted in ascending order, first by color\n *  bit depth (the sum of all channel depths) and then by resolution area (the\n *  product of width and height).\n *\n *  @param[in] monitor The monitor to query.\n *  @param[out] count Where to store the number of video modes in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of video modes, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified monitor is\n *  disconnected, this function is called again for that monitor or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_modes\n *  @sa glfwGetVideoMode\n *\n *  @since Added in version 1.0.\n *  @glfw3 Changed to return an array of modes for a specific monitor.\n *\n *  @ingroup monitor\n */\nGLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);\n\n/*! @brief Returns the current mode of the specified monitor.\n *\n *  This function returns the current video mode of the specified monitor.  If\n *  you have created a full screen window for that monitor, the return value\n *  will depend on whether that window is iconified.\n *\n *  @param[in] monitor The monitor to query.\n *  @return The current mode of the monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified monitor is\n *  disconnected or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_modes\n *  @sa glfwGetVideoModes\n *\n *  @since Added in version 3.0.  Replaces `glfwGetDesktopMode`.\n *\n *  @ingroup monitor\n */\nGLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);\n\n/*! @brief Generates a gamma ramp and sets it for the specified monitor.\n *\n *  This function generates a 256-element gamma ramp from the specified exponent\n *  and then calls @ref glfwSetGammaRamp with it.  The value must be a finite\n *  number greater than zero.\n *\n *  @param[in] monitor The monitor whose gamma ramp to set.\n *  @param[in] gamma The desired exponent.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_gamma\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);\n\n/*! @brief Returns the current gamma ramp for the specified monitor.\n *\n *  This function returns the current gamma ramp of the specified monitor.\n *\n *  @param[in] monitor The monitor to query.\n *  @return The current gamma ramp, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned structure and its arrays are allocated and\n *  freed by GLFW.  You should not free them yourself.  They are valid until the\n *  specified monitor is disconnected, this function is called again for that\n *  monitor or the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_gamma\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);\n\n/*! @brief Sets the current gamma ramp for the specified monitor.\n *\n *  This function sets the current gamma ramp for the specified monitor.  The\n *  original gamma ramp for that monitor is saved by GLFW the first time this\n *  function is called and is restored by @ref glfwTerminate.\n *\n *  @param[in] monitor The monitor whose gamma ramp to set.\n *  @param[in] ramp The gamma ramp to use.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @remark Gamma ramp sizes other than 256 are not supported by all platforms\n *  or graphics hardware.\n *\n *  @remark @win32 The gamma ramp size must be 256.\n *\n *  @pointer_lifetime The specified gamma ramp is copied before this function\n *  returns.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref monitor_gamma\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup monitor\n */\nGLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);\n\n/*! @brief Resets all window hints to their default values.\n *\n *  This function resets all window hints to their\n *  [default values](@ref window_hints_values).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hints\n *  @sa glfwWindowHint\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwDefaultWindowHints(void);\n\n/*! @brief Sets the specified window hint to the desired value.\n *\n *  This function sets hints for the next call to @ref glfwCreateWindow.  The\n *  hints, once set, retain their values until changed by a call to @ref\n *  glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is\n *  terminated.\n *\n *  This function does not check whether the specified hint values are valid.\n *  If you set hints to invalid values this will instead be reported by the next\n *  call to @ref glfwCreateWindow.\n *\n *  @param[in] hint The [window hint](@ref window_hints) to set.\n *  @param[in] value The new value of the window hint.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hints\n *  @sa glfwDefaultWindowHints\n *\n *  @since Added in version 3.0.  Replaces `glfwOpenWindowHint`.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwWindowHint(int hint, int value);\n\n/*! @brief Creates a window and its associated context.\n *\n *  This function creates a window and its associated OpenGL or OpenGL ES\n *  context.  Most of the options controlling how the window and its context\n *  should be created are specified with [window hints](@ref window_hints).\n *\n *  Successful creation does not change which context is current.  Before you\n *  can use the newly created context, you need to\n *  [make it current](@ref context_current).  For information about the `share`\n *  parameter, see @ref context_sharing.\n *\n *  The created window, framebuffer and context may differ from what you\n *  requested, as not all parameters and hints are\n *  [hard constraints](@ref window_hints_hard).  This includes the size of the\n *  window, especially for full screen windows.  To query the actual attributes\n *  of the created window, framebuffer and context, see @ref\n *  glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.\n *\n *  To create a full screen window, you need to specify the monitor the window\n *  will cover.  If no monitor is specified, the window will be windowed mode.\n *  Unless you have a way for the user to choose a specific monitor, it is\n *  recommended that you pick the primary monitor.  For more information on how\n *  to query connected monitors, see @ref monitor_monitors.\n *\n *  For full screen windows, the specified size becomes the resolution of the\n *  window's _desired video mode_.  As long as a full screen window is not\n *  iconified, the supported video mode most closely matching the desired video\n *  mode is set for the specified monitor.  For more information about full\n *  screen windows, including the creation of so called _windowed full screen_\n *  or _borderless full screen_ windows, see @ref window_windowed_full_screen.\n *\n *  By default, newly created windows use the placement recommended by the\n *  window system.  To create the window at a specific position, make it\n *  initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window\n *  hint, set its [position](@ref window_pos) and then [show](@ref window_hide)\n *  it.\n *\n *  As long as at least one full screen window is not iconified, the screensaver\n *  is prohibited from starting.\n *\n *  Window systems put limits on window sizes.  Very large or very small window\n *  dimensions may be overridden by the window system on creation.  Check the\n *  actual [size](@ref window_size) after creation.\n *\n *  The [swap interval](@ref buffer_swap) is not set during window creation and\n *  the initial value may vary depending on driver settings and defaults.\n *\n *  @param[in] width The desired width, in screen coordinates, of the window.\n *  This must be greater than zero.\n *  @param[in] height The desired height, in screen coordinates, of the window.\n *  This must be greater than zero.\n *  @param[in] title The initial, UTF-8 encoded window title.\n *  @param[in] monitor The monitor to use for full screen mode, or `NULL` for\n *  windowed mode.\n *  @param[in] share The window whose context to share resources with, or `NULL`\n *  to not share resources.\n *  @return The handle of the created window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref\n *  GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @remark @win32 Window creation will fail if the Microsoft GDI software\n *  OpenGL implementation is the only one available.\n *\n *  @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it\n *  will be set as the initial icon for the window.  If no such icon is present,\n *  the `IDI_WINLOGO` icon will be used instead.  To set a different icon, see\n *  @ref glfwSetWindowIcon.\n *\n *  @remark @win32 The context to share resources with must not be current on\n *  any other thread.\n *\n *  @remark @osx The GLFW window has no icon, as it is not a document\n *  window, but the dock icon will be the same as the application bundle's icon.\n *  For more information on bundles, see the\n *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)\n *  in the Mac Developer Library.\n *\n *  @remark @osx The first time a window is created the menu bar is populated\n *  with common commands like Hide, Quit and About.  The About entry opens\n *  a minimal about dialog with information from the application's bundle.  The\n *  menu bar can be disabled with a\n *  [compile-time option](@ref compile_options_osx).\n *\n *  @remark @osx On OS X 10.10 and later the window frame will not be rendered\n *  at full resolution on Retina displays unless the `NSHighResolutionCapable`\n *  key is enabled in the application bundle's `Info.plist`.  For more\n *  information, see\n *  [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)\n *  in the Mac Developer Library.  The GLFW test and example programs use\n *  a custom `Info.plist` template for this, which can be found as\n *  `CMake/MacOSXBundleInfo.plist.in` in the source tree.\n *\n *  @remark @x11 Some window managers will not respect the placement of\n *  initially hidden windows.\n *\n *  @remark @x11 Due to the asynchronous nature of X11, it may take a moment for\n *  a window to reach its requested state.  This means you may not be able to\n *  query the final size, position or other attributes directly after window\n *  creation.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_creation\n *  @sa glfwDestroyWindow\n *\n *  @since Added in version 3.0.  Replaces `glfwOpenWindow`.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);\n\n/*! @brief Destroys the specified window and its context.\n *\n *  This function destroys the specified window and its context.  On calling\n *  this function, no further callbacks will be called for that window.\n *\n *  If the context of the specified window is current on the main thread, it is\n *  detached before being destroyed.\n *\n *  @param[in] window The window to destroy.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @note The context of the specified window must not be current on any other\n *  thread when this function is called.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_creation\n *  @sa glfwCreateWindow\n *\n *  @since Added in version 3.0.  Replaces `glfwCloseWindow`.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwDestroyWindow(GLFWwindow* window);\n\n/*! @brief Checks the close flag of the specified window.\n *\n *  This function returns the value of the close flag of the specified window.\n *\n *  @param[in] window The window to query.\n *  @return The value of the close flag.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_close\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI int glfwWindowShouldClose(GLFWwindow* window);\n\n/*! @brief Sets the close flag of the specified window.\n *\n *  This function sets the value of the close flag of the specified window.\n *  This can be used to override the user's attempt to close the window, or\n *  to signal that it should be closed.\n *\n *  @param[in] window The window whose flag to change.\n *  @param[in] value The new value.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_close\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);\n\n/*! @brief Sets the title of the specified window.\n *\n *  This function sets the window title, encoded as UTF-8, of the specified\n *  window.\n *\n *  @param[in] window The window whose title to change.\n *  @param[in] title The UTF-8 encoded window title.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @remark @osx The window title will not be updated until the next time you\n *  process events.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_title\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);\n\n/*! @brief Sets the icon for the specified window.\n *\n *  This function sets the icon of the specified window.  If passed an array of\n *  candidate images, those of or closest to the sizes desired by the system are\n *  selected.  If no images are specified, the window reverts to its default\n *  icon.\n *\n *  The desired image sizes varies depending on platform and system settings.\n *  The selected images will be rescaled as needed.  Good sizes include 16x16,\n *  32x32 and 48x48.\n *\n *  @param[in] window The window whose icon to set.\n *  @param[in] count The number of images in the specified array, or zero to\n *  revert to the default window icon.\n *  @param[in] images The images to create the icon from.  This is ignored if\n *  count is zero.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The specified image data is copied before this function\n *  returns.\n *\n *  @remark @osx The GLFW window has no icon, as it is not a document\n *  window, so this function does nothing.  The dock icon will be the same as\n *  the application bundle's icon.  For more information on bundles, see the\n *  [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)\n *  in the Mac Developer Library.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_icon\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);\n\n/*! @brief Retrieves the position of the client area of the specified window.\n *\n *  This function retrieves the position, in screen coordinates, of the\n *  upper-left corner of the client area of the specified window.\n *\n *  Any or all of the position arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` position arguments will be set to zero.\n *\n *  @param[in] window The window to query.\n *  @param[out] xpos Where to store the x-coordinate of the upper-left corner of\n *  the client area, or `NULL`.\n *  @param[out] ypos Where to store the y-coordinate of the upper-left corner of\n *  the client area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_pos\n *  @sa glfwSetWindowPos\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);\n\n/*! @brief Sets the position of the client area of the specified window.\n *\n *  This function sets the position, in screen coordinates, of the upper-left\n *  corner of the client area of the specified windowed mode window.  If the\n *  window is a full screen window, this function does nothing.\n *\n *  __Do not use this function__ to move an already visible window unless you\n *  have very good reasons for doing so, as it will confuse and annoy the user.\n *\n *  The window manager may put limits on what positions are allowed.  GLFW\n *  cannot and should not override these limits.\n *\n *  @param[in] window The window to query.\n *  @param[in] xpos The x-coordinate of the upper-left corner of the client area.\n *  @param[in] ypos The y-coordinate of the upper-left corner of the client area.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_pos\n *  @sa glfwGetWindowPos\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);\n\n/*! @brief Retrieves the size of the client area of the specified window.\n *\n *  This function retrieves the size, in screen coordinates, of the client area\n *  of the specified window.  If you wish to retrieve the size of the\n *  framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] window The window whose size to retrieve.\n *  @param[out] width Where to store the width, in screen coordinates, of the\n *  client area, or `NULL`.\n *  @param[out] height Where to store the height, in screen coordinates, of the\n *  client area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *  @sa glfwSetWindowSize\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);\n\n/*! @brief Sets the size limits of the specified window.\n *\n *  This function sets the size limits of the client area of the specified\n *  window.  If the window is full screen, the size limits only take effect\n *  once it is made windowed.  If the window is not resizable, this function\n *  does nothing.\n *\n *  The size limits are applied immediately to a windowed mode window and may\n *  cause it to be resized.\n *\n *  The maximum dimensions must be greater than or equal to the minimum\n *  dimensions and all must be greater than or equal to zero.\n *\n *  @param[in] window The window to set limits for.\n *  @param[in] minwidth The minimum width, in screen coordinates, of the client\n *  area, or `GLFW_DONT_CARE`.\n *  @param[in] minheight The minimum height, in screen coordinates, of the\n *  client area, or `GLFW_DONT_CARE`.\n *  @param[in] maxwidth The maximum width, in screen coordinates, of the client\n *  area, or `GLFW_DONT_CARE`.\n *  @param[in] maxheight The maximum height, in screen coordinates, of the\n *  client area, or `GLFW_DONT_CARE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark If you set size limits and an aspect ratio that conflict, the\n *  results are undefined.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_sizelimits\n *  @sa glfwSetWindowAspectRatio\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);\n\n/*! @brief Sets the aspect ratio of the specified window.\n *\n *  This function sets the required aspect ratio of the client area of the\n *  specified window.  If the window is full screen, the aspect ratio only takes\n *  effect once it is made windowed.  If the window is not resizable, this\n *  function does nothing.\n *\n *  The aspect ratio is specified as a numerator and a denominator and both\n *  values must be greater than zero.  For example, the common 16:9 aspect ratio\n *  is specified as 16 and 9, respectively.\n *\n *  If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect\n *  ratio limit is disabled.\n *\n *  The aspect ratio is applied immediately to a windowed mode window and may\n *  cause it to be resized.\n *\n *  @param[in] window The window to set limits for.\n *  @param[in] numer The numerator of the desired aspect ratio, or\n *  `GLFW_DONT_CARE`.\n *  @param[in] denom The denominator of the desired aspect ratio, or\n *  `GLFW_DONT_CARE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark If you set size limits and an aspect ratio that conflict, the\n *  results are undefined.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_sizelimits\n *  @sa glfwSetWindowSizeLimits\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);\n\n/*! @brief Sets the size of the client area of the specified window.\n *\n *  This function sets the size, in screen coordinates, of the client area of\n *  the specified window.\n *\n *  For full screen windows, this function updates the resolution of its desired\n *  video mode and switches to the video mode closest to it, without affecting\n *  the window's context.  As the context is unaffected, the bit depths of the\n *  framebuffer remain unchanged.\n *\n *  If you wish to update the refresh rate of the desired video mode in addition\n *  to its resolution, see @ref glfwSetWindowMonitor.\n *\n *  The window manager may put limits on what sizes are allowed.  GLFW cannot\n *  and should not override these limits.\n *\n *  @param[in] window The window to resize.\n *  @param[in] width The desired width, in screen coordinates, of the window\n *  client area.\n *  @param[in] height The desired height, in screen coordinates, of the window\n *  client area.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *  @sa glfwGetWindowSize\n *  @sa glfwSetWindowMonitor\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);\n\n/*! @brief Retrieves the size of the framebuffer of the specified window.\n *\n *  This function retrieves the size, in pixels, of the framebuffer of the\n *  specified window.  If you wish to retrieve the size of the window in screen\n *  coordinates, see @ref glfwGetWindowSize.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] window The window whose framebuffer to query.\n *  @param[out] width Where to store the width, in pixels, of the framebuffer,\n *  or `NULL`.\n *  @param[out] height Where to store the height, in pixels, of the framebuffer,\n *  or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_fbsize\n *  @sa glfwSetFramebufferSizeCallback\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);\n\n/*! @brief Retrieves the size of the frame of the window.\n *\n *  This function retrieves the size, in screen coordinates, of each edge of the\n *  frame of the specified window.  This size includes the title bar, if the\n *  window has one.  The size of the frame may vary depending on the\n *  [window-related hints](@ref window_hints_wnd) used to create it.\n *\n *  Because this function retrieves the size of each window frame edge and not\n *  the offset along a particular coordinate axis, the retrieved values will\n *  always be zero or positive.\n *\n *  Any or all of the size arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` size arguments will be set to zero.\n *\n *  @param[in] window The window whose frame size to query.\n *  @param[out] left Where to store the size, in screen coordinates, of the left\n *  edge of the window frame, or `NULL`.\n *  @param[out] top Where to store the size, in screen coordinates, of the top\n *  edge of the window frame, or `NULL`.\n *  @param[out] right Where to store the size, in screen coordinates, of the\n *  right edge of the window frame, or `NULL`.\n *  @param[out] bottom Where to store the size, in screen coordinates, of the\n *  bottom edge of the window frame, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);\n\n/*! @brief Iconifies the specified window.\n *\n *  This function iconifies (minimizes) the specified window if it was\n *  previously restored.  If the window is already iconified, this function does\n *  nothing.\n *\n *  If the specified window is a full screen window, the original monitor\n *  resolution is restored until the window is restored.\n *\n *  @param[in] window The window to iconify.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *  @sa glfwRestoreWindow\n *  @sa glfwMaximizeWindow\n *\n *  @since Added in version 2.1.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwIconifyWindow(GLFWwindow* window);\n\n/*! @brief Restores the specified window.\n *\n *  This function restores the specified window if it was previously iconified\n *  (minimized) or maximized.  If the window is already restored, this function\n *  does nothing.\n *\n *  If the specified window is a full screen window, the resolution chosen for\n *  the window is restored on the selected monitor.\n *\n *  @param[in] window The window to restore.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *  @sa glfwIconifyWindow\n *  @sa glfwMaximizeWindow\n *\n *  @since Added in version 2.1.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwRestoreWindow(GLFWwindow* window);\n\n/*! @brief Maximizes the specified window.\n *\n *  This function maximizes the specified window if it was previously not\n *  maximized.  If the window is already maximized, this function does nothing.\n *\n *  If the specified window is a full screen window, this function does nothing.\n *\n *  @param[in] window The window to maximize.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @par Thread Safety\n *  This function may only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *  @sa glfwIconifyWindow\n *  @sa glfwRestoreWindow\n *\n *  @since Added in GLFW 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwMaximizeWindow(GLFWwindow* window);\n\n/*! @brief Makes the specified window visible.\n *\n *  This function makes the specified window visible if it was previously\n *  hidden.  If the window is already visible or is in full screen mode, this\n *  function does nothing.\n *\n *  @param[in] window The window to make visible.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hide\n *  @sa glfwHideWindow\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwShowWindow(GLFWwindow* window);\n\n/*! @brief Hides the specified window.\n *\n *  This function hides the specified window if it was previously visible.  If\n *  the window is already hidden or is in full screen mode, this function does\n *  nothing.\n *\n *  @param[in] window The window to hide.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_hide\n *  @sa glfwShowWindow\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwHideWindow(GLFWwindow* window);\n\n/*! @brief Brings the specified window to front and sets input focus.\n *\n *  This function brings the specified window to front and sets input focus.\n *  The window should already be visible and not iconified.\n *\n *  By default, both windowed and full screen mode windows are focused when\n *  initially created.  Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable\n *  this behavior.\n *\n *  __Do not use this function__ to steal focus from other applications unless\n *  you are certain that is what the user wants.  Focus stealing can be\n *  extremely disruptive.\n *\n *  @param[in] window The window to give input focus.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_focus\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwFocusWindow(GLFWwindow* window);\n\n/*! @brief Returns the monitor that the window uses for full screen mode.\n *\n *  This function returns the handle of the monitor that the specified window is\n *  in full screen on.\n *\n *  @param[in] window The window to query.\n *  @return The monitor, or `NULL` if the window is in windowed mode or an error\n *  occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_monitor\n *  @sa glfwSetWindowMonitor\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);\n\n/*! @brief Sets the mode, monitor, video mode and placement of a window.\n *\n *  This function sets the monitor that the window uses for full screen mode or,\n *  if the monitor is `NULL`, makes it windowed mode.\n *\n *  When setting a monitor, this function updates the width, height and refresh\n *  rate of the desired video mode and switches to the video mode closest to it.\n *  The window position is ignored when setting a monitor.\n *\n *  When the monitor is `NULL`, the position, width and height are used to\n *  place the window client area.  The refresh rate is ignored when no monitor\n *  is specified.\n *\n *  If you only wish to update the resolution of a full screen window or the\n *  size of a windowed mode window, see @ref glfwSetWindowSize.\n *\n *  When a window transitions from full screen to windowed mode, this function\n *  restores any previous window settings such as whether it is decorated,\n *  floating, resizable, has size or aspect ratio limits, etc..\n *\n *  @param[in] window The window whose monitor, size or video mode to set.\n *  @param[in] monitor The desired monitor, or `NULL` to set windowed mode.\n *  @param[in] xpos The desired x-coordinate of the upper-left corner of the\n *  client area.\n *  @param[in] ypos The desired y-coordinate of the upper-left corner of the\n *  client area.\n *  @param[in] width The desired with, in screen coordinates, of the client area\n *  or video mode.\n *  @param[in] height The desired height, in screen coordinates, of the client\n *  area or video mode.\n *  @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,\n *  or `GLFW_DONT_CARE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_monitor\n *  @sa @ref window_full_screen\n *  @sa glfwGetWindowMonitor\n *  @sa glfwSetWindowSize\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);\n\n/*! @brief Returns an attribute of the specified window.\n *\n *  This function returns the value of an attribute of the specified window or\n *  its OpenGL or OpenGL ES context.\n *\n *  @param[in] window The window to query.\n *  @param[in] attrib The [window attribute](@ref window_attribs) whose value to\n *  return.\n *  @return The value of the attribute, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark Framebuffer related hints are not window attributes.  See @ref\n *  window_attribs_fb for more information.\n *\n *  @remark Zero is a valid value for many window and context related\n *  attributes so you cannot use a return value of zero as an indication of\n *  errors.  However, this function should not fail as long as it is passed\n *  valid arguments and the library has been [initialized](@ref intro_init).\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_attribs\n *\n *  @since Added in version 3.0.  Replaces `glfwGetWindowParam` and\n *  `glfwGetGLVersion`.\n *\n *  @ingroup window\n */\nGLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);\n\n/*! @brief Sets the user pointer of the specified window.\n *\n *  This function sets the user-defined pointer of the specified window.  The\n *  current value is retained until the window is destroyed.  The initial value\n *  is `NULL`.\n *\n *  @param[in] window The window whose pointer to set.\n *  @param[in] pointer The new value.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_userptr\n *  @sa glfwGetWindowUserPointer\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);\n\n/*! @brief Returns the user pointer of the specified window.\n *\n *  This function returns the current value of the user-defined pointer of the\n *  specified window.  The initial value is `NULL`.\n *\n *  @param[in] window The window whose pointer to return.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @sa @ref window_userptr\n *  @sa glfwSetWindowUserPointer\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);\n\n/*! @brief Sets the position callback for the specified window.\n *\n *  This function sets the position callback of the specified window, which is\n *  called when the window is moved.  The callback is provided with the screen\n *  position of the upper-left corner of the client area of the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_pos\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);\n\n/*! @brief Sets the size callback for the specified window.\n *\n *  This function sets the size callback of the specified window, which is\n *  called when the window is resized.  The callback is provided with the size,\n *  in screen coordinates, of the client area of the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_size\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);\n\n/*! @brief Sets the close callback for the specified window.\n *\n *  This function sets the close callback of the specified window, which is\n *  called when the user attempts to close the window, for example by clicking\n *  the close widget in the title bar.\n *\n *  The close flag is set before this callback is called, but you can modify it\n *  at any time with @ref glfwSetWindowShouldClose.\n *\n *  The close callback is not triggered by @ref glfwDestroyWindow.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @remark @osx Selecting Quit from the application menu will trigger the close\n *  callback for all windows.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_close\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);\n\n/*! @brief Sets the refresh callback for the specified window.\n *\n *  This function sets the refresh callback of the specified window, which is\n *  called when the client area of the window needs to be redrawn, for example\n *  if the window has been exposed after having been covered by another window.\n *\n *  On compositing window systems such as Aero, Compiz or Aqua, where the window\n *  contents are saved off-screen, this callback may be called only very\n *  infrequently or never at all.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_refresh\n *\n *  @since Added in version 2.5.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);\n\n/*! @brief Sets the focus callback for the specified window.\n *\n *  This function sets the focus callback of the specified window, which is\n *  called when the window gains or loses input focus.\n *\n *  After the focus callback is called for a window that lost input focus,\n *  synthetic key and mouse button release events will be generated for all such\n *  that had been pressed.  For more information, see @ref glfwSetKeyCallback\n *  and @ref glfwSetMouseButtonCallback.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_focus\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);\n\n/*! @brief Sets the iconify callback for the specified window.\n *\n *  This function sets the iconification callback of the specified window, which\n *  is called when the window is iconified or restored.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_iconify\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);\n\n/*! @brief Sets the framebuffer resize callback for the specified window.\n *\n *  This function sets the framebuffer resize callback of the specified window,\n *  which is called when the framebuffer of the specified window is resized.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref window_fbsize\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup window\n */\nGLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);\n\n/*! @brief Processes all pending events.\n *\n *  This function processes only those events that are already in the event\n *  queue and then returns immediately.  Processing events will cause the window\n *  and input callbacks associated with those events to be called.\n *\n *  On some platforms, a window move, resize or menu operation will cause event\n *  processing to block.  This is due to how event processing is designed on\n *  those platforms.  You can use the\n *  [window refresh callback](@ref window_refresh) to redraw the contents of\n *  your window when necessary during such operations.\n *\n *  On some platforms, certain events are sent directly to the application\n *  without going through the event queue, causing callbacks to be called\n *  outside of a call to one of the event processing functions.\n *\n *  Event processing is not required for joystick input to work.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref events\n *  @sa glfwWaitEvents\n *  @sa glfwWaitEventsTimeout\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwPollEvents(void);\n\n/*! @brief Waits until events are queued and processes them.\n *\n *  This function puts the calling thread to sleep until at least one event is\n *  available in the event queue.  Once one or more events are available,\n *  it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue\n *  are processed and the function then returns immediately.  Processing events\n *  will cause the window and input callbacks associated with those events to be\n *  called.\n *\n *  Since not all events are associated with callbacks, this function may return\n *  without a callback having been called even if you are monitoring all\n *  callbacks.\n *\n *  On some platforms, a window move, resize or menu operation will cause event\n *  processing to block.  This is due to how event processing is designed on\n *  those platforms.  You can use the\n *  [window refresh callback](@ref window_refresh) to redraw the contents of\n *  your window when necessary during such operations.\n *\n *  On some platforms, certain callbacks may be called outside of a call to one\n *  of the event processing functions.\n *\n *  If no windows exist, this function returns immediately.  For synchronization\n *  of threads in applications that do not create windows, use your threading\n *  library of choice.\n *\n *  Event processing is not required for joystick input to work.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref events\n *  @sa glfwPollEvents\n *  @sa glfwWaitEventsTimeout\n *\n *  @since Added in version 2.5.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwWaitEvents(void);\n\n/*! @brief Waits with timeout until events are queued and processes them.\n *\n *  This function puts the calling thread to sleep until at least one event is\n *  available in the event queue, or until the specified timeout is reached.  If\n *  one or more events are available, it behaves exactly like @ref\n *  glfwPollEvents, i.e. the events in the queue are processed and the function\n *  then returns immediately.  Processing events will cause the window and input\n *  callbacks associated with those events to be called.\n *\n *  The timeout value must be a positive finite number.\n *\n *  Since not all events are associated with callbacks, this function may return\n *  without a callback having been called even if you are monitoring all\n *  callbacks.\n *\n *  On some platforms, a window move, resize or menu operation will cause event\n *  processing to block.  This is due to how event processing is designed on\n *  those platforms.  You can use the\n *  [window refresh callback](@ref window_refresh) to redraw the contents of\n *  your window when necessary during such operations.\n *\n *  On some platforms, certain callbacks may be called outside of a call to one\n *  of the event processing functions.\n *\n *  If no windows exist, this function returns immediately.  For synchronization\n *  of threads in applications that do not create windows, use your threading\n *  library of choice.\n *\n *  Event processing is not required for joystick input to work.\n *\n *  @param[in] timeout The maximum amount of time, in seconds, to wait.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref events\n *  @sa glfwPollEvents\n *  @sa glfwWaitEvents\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwWaitEventsTimeout(double timeout);\n\n/*! @brief Posts an empty event to the event queue.\n *\n *  This function posts an empty event from the current thread to the event\n *  queue, causing @ref glfwWaitEvents to return.\n *\n *  If no windows exist, this function returns immediately.  For synchronization\n *  of threads in applications that do not create windows, use your threading\n *  library of choice.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref events\n *  @sa glfwWaitEvents\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwPostEmptyEvent(void);\n\n/*! @brief Returns the value of an input option for the specified window.\n *\n *  This function returns the value of an input option for the specified window.\n *  The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *\n *  @param[in] window The window to query.\n *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa glfwSetInputMode\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);\n\n/*! @brief Sets an input option for the specified window.\n *\n *  This function sets an input mode option for the specified window.  The mode\n *  must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *\n *  If the mode is `GLFW_CURSOR`, the value must be one of the following cursor\n *  modes:\n *  - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.\n *  - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client\n *    area of the window but does not restrict the cursor from leaving.\n *  - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual\n *    and unlimited cursor movement.  This is useful for implementing for\n *    example 3D camera controls.\n *\n *  If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to\n *  enable sticky keys, or `GLFW_FALSE` to disable it.  If sticky keys are\n *  enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`\n *  the next time it is called even if the key had been released before the\n *  call.  This is useful when you are only interested in whether keys have been\n *  pressed but not when or in which order.\n *\n *  If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either\n *  `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.\n *  If sticky mouse buttons are enabled, a mouse button press will ensure that\n *  @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even\n *  if the mouse button had been released before the call.  This is useful when\n *  you are only interested in whether mouse buttons have been pressed but not\n *  when or in which order.\n *\n *  @param[in] window The window whose input mode to set.\n *  @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or\n *  `GLFW_STICKY_MOUSE_BUTTONS`.\n *  @param[in] value The new value of the specified input mode.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa glfwGetInputMode\n *\n *  @since Added in version 3.0.  Replaces `glfwEnable` and `glfwDisable`.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);\n\n/*! @brief Returns the localized name of the specified printable key.\n *\n *  This function returns the localized name of the specified printable key.\n *  This is intended for displaying key bindings to the user.\n *\n *  If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise\n *  the scancode is ignored.  If a non-printable key or (if the key is\n *  `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is\n *  specified, this function returns `NULL`.          \n *\n *  This behavior allows you to pass in the arguments passed to the\n *  [key callback](@ref input_key) without modification.\n *\n *  The printable keys are:\n *  - `GLFW_KEY_APOSTROPHE`\n *  - `GLFW_KEY_COMMA`\n *  - `GLFW_KEY_MINUS`\n *  - `GLFW_KEY_PERIOD`\n *  - `GLFW_KEY_SLASH`\n *  - `GLFW_KEY_SEMICOLON`\n *  - `GLFW_KEY_EQUAL`\n *  - `GLFW_KEY_LEFT_BRACKET`\n *  - `GLFW_KEY_RIGHT_BRACKET`\n *  - `GLFW_KEY_BACKSLASH`\n *  - `GLFW_KEY_WORLD_1`\n *  - `GLFW_KEY_WORLD_2`\n *  - `GLFW_KEY_0` to `GLFW_KEY_9`\n *  - `GLFW_KEY_A` to `GLFW_KEY_Z`\n *  - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`\n *  - `GLFW_KEY_KP_DECIMAL`\n *  - `GLFW_KEY_KP_DIVIDE`\n *  - `GLFW_KEY_KP_MULTIPLY`\n *  - `GLFW_KEY_KP_SUBTRACT`\n *  - `GLFW_KEY_KP_ADD`\n *  - `GLFW_KEY_KP_EQUAL`\n *\n *  @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.\n *  @param[in] scancode The scancode of the key to query.\n *  @return The localized name of the key, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the next call to @ref\n *  glfwGetKeyName, or until the library is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_key_name\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI const char* glfwGetKeyName(int key, int scancode);\n\n/*! @brief Returns the last reported state of a keyboard key for the specified\n *  window.\n *\n *  This function returns the last state reported for the specified key to the\n *  specified window.  The returned state is one of `GLFW_PRESS` or\n *  `GLFW_RELEASE`.  The higher-level action `GLFW_REPEAT` is only reported to\n *  the key callback.\n *\n *  If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns\n *  `GLFW_PRESS` the first time you call it for a key that was pressed, even if\n *  that key has already been released.\n *\n *  The key functions deal with physical keys, with [key tokens](@ref keys)\n *  named after their use on the standard US keyboard layout.  If you want to\n *  input text, use the Unicode character callback instead.\n *\n *  The [modifier key bit masks](@ref mods) are not key tokens and cannot be\n *  used with this function.\n *\n *  __Do not use this function__ to implement [text input](@ref input_char).\n *\n *  @param[in] window The desired window.\n *  @param[in] key The desired [keyboard key](@ref keys).  `GLFW_KEY_UNKNOWN` is\n *  not a valid key for this function.\n *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_key\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwGetKey(GLFWwindow* window, int key);\n\n/*! @brief Returns the last reported state of a mouse button for the specified\n *  window.\n *\n *  This function returns the last state reported for the specified mouse button\n *  to the specified window.  The returned state is one of `GLFW_PRESS` or\n *  `GLFW_RELEASE`.\n *\n *  If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function\n *  `GLFW_PRESS` the first time you call it for a mouse button that was pressed,\n *  even if that mouse button has already been released.\n *\n *  @param[in] window The desired window.\n *  @param[in] button The desired [mouse button](@ref buttons).\n *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_ENUM.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_mouse_button\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);\n\n/*! @brief Retrieves the position of the cursor relative to the client area of\n *  the window.\n *\n *  This function returns the position of the cursor, in screen coordinates,\n *  relative to the upper-left corner of the client area of the specified\n *  window.\n *\n *  If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor\n *  position is unbounded and limited only by the minimum and maximum values of\n *  a `double`.\n *\n *  The coordinate can be converted to their integer equivalents with the\n *  `floor` function.  Casting directly to an integer type works for positive\n *  coordinates, but fails for negative ones.\n *\n *  Any or all of the position arguments may be `NULL`.  If an error occurs, all\n *  non-`NULL` position arguments will be set to zero.\n *\n *  @param[in] window The desired window.\n *  @param[out] xpos Where to store the cursor x-coordinate, relative to the\n *  left edge of the client area, or `NULL`.\n *  @param[out] ypos Where to store the cursor y-coordinate, relative to the to\n *  top edge of the client area, or `NULL`.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_pos\n *  @sa glfwSetCursorPos\n *\n *  @since Added in version 3.0.  Replaces `glfwGetMousePos`.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);\n\n/*! @brief Sets the position of the cursor, relative to the client area of the\n *  window.\n *\n *  This function sets the position, in screen coordinates, of the cursor\n *  relative to the upper-left corner of the client area of the specified\n *  window.  The window must have input focus.  If the window does not have\n *  input focus when this function is called, it fails silently.\n *\n *  __Do not use this function__ to implement things like camera controls.  GLFW\n *  already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the\n *  cursor, transparently re-centers it and provides unconstrained cursor\n *  motion.  See @ref glfwSetInputMode for more information.\n *\n *  If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is\n *  unconstrained and limited only by the minimum and maximum values of\n *  a `double`.\n *\n *  @param[in] window The desired window.\n *  @param[in] xpos The desired x-coordinate, relative to the left edge of the\n *  client area.\n *  @param[in] ypos The desired y-coordinate, relative to the top edge of the\n *  client area.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_pos\n *  @sa glfwGetCursorPos\n *\n *  @since Added in version 3.0.  Replaces `glfwSetMousePos`.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);\n\n/*! @brief Creates a custom cursor.\n *\n *  Creates a new custom cursor image that can be set for a window with @ref\n *  glfwSetCursor.  The cursor can be destroyed with @ref glfwDestroyCursor.\n *  Any remaining cursors are destroyed by @ref glfwTerminate.\n *\n *  The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight\n *  bits per channel.  They are arranged canonically as packed sequential rows,\n *  starting from the top-left corner.\n *\n *  The cursor hotspot is specified in pixels, relative to the upper-left corner\n *  of the cursor image.  Like all other coordinate systems in GLFW, the X-axis\n *  points to the right and the Y-axis points down.\n *\n *  @param[in] image The desired cursor image.\n *  @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.\n *  @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.\n *  @return The handle of the created cursor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The specified image data is copied before this function\n *  returns.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *  @sa glfwDestroyCursor\n *  @sa glfwCreateStandardCursor\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);\n\n/*! @brief Creates a cursor with a standard shape.\n *\n *  Returns a cursor with a [standard shape](@ref shapes), that can be set for\n *  a window with @ref glfwSetCursor.\n *\n *  @param[in] shape One of the [standard shapes](@ref shapes).\n *  @return A new cursor ready to use or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *  @sa glfwCreateCursor\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);\n\n/*! @brief Destroys a cursor.\n *\n *  This function destroys a cursor previously created with @ref\n *  glfwCreateCursor.  Any remaining cursors will be destroyed by @ref\n *  glfwTerminate.\n *\n *  @param[in] cursor The cursor object to destroy.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @reentrancy This function must not be called from a callback.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *  @sa glfwCreateCursor\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);\n\n/*! @brief Sets the cursor for the window.\n *\n *  This function sets the cursor image to be used when the cursor is over the\n *  client area of the specified window.  The set cursor will only be visible\n *  when the [cursor mode](@ref cursor_mode) of the window is\n *  `GLFW_CURSOR_NORMAL`.\n *\n *  On some platforms, the set cursor may not be visible unless the window also\n *  has input focus.\n *\n *  @param[in] window The window to set the cursor for.\n *  @param[in] cursor The cursor to set, or `NULL` to switch back to the default\n *  arrow cursor.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_object\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);\n\n/*! @brief Sets the key callback.\n *\n *  This function sets the key callback of the specified window, which is called\n *  when a key is pressed, repeated or released.\n *\n *  The key functions deal with physical keys, with layout independent\n *  [key tokens](@ref keys) named after their values in the standard US keyboard\n *  layout.  If you want to input text, use the\n *  [character callback](@ref glfwSetCharCallback) instead.\n *\n *  When a window loses input focus, it will generate synthetic key release\n *  events for all pressed keys.  You can tell these events from user-generated\n *  events by the fact that the synthetic ones are generated after the focus\n *  loss event has been processed, i.e. after the\n *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.\n *\n *  The scancode of a key is specific to that platform or sometimes even to that\n *  machine.  Scancodes are intended to allow users to bind keys that don't have\n *  a GLFW key token.  Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their\n *  state is not saved and so it cannot be queried with @ref glfwGetKey.\n *\n *  Sometimes GLFW needs to generate synthetic key events, in which case the\n *  scancode may be zero.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new key callback, or `NULL` to remove the currently\n *  set callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_key\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);\n\n/*! @brief Sets the Unicode character callback.\n *\n *  This function sets the character callback of the specified window, which is\n *  called when a Unicode character is input.\n *\n *  The character callback is intended for Unicode text input.  As it deals with\n *  characters, it is keyboard layout dependent, whereas the\n *  [key callback](@ref glfwSetKeyCallback) is not.  Characters do not map 1:1\n *  to physical keys, as a key may produce zero, one or more characters.  If you\n *  want to know whether a specific physical key was pressed or released, see\n *  the key callback instead.\n *\n *  The character callback behaves as system text input normally does and will\n *  not be called if modifier keys are held down that would prevent normal text\n *  input on that platform, for example a Super (Command) key on OS X or Alt key\n *  on Windows.  There is a\n *  [character with modifiers callback](@ref glfwSetCharModsCallback) that\n *  receives these events.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_char\n *\n *  @since Added in version 2.4.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);\n\n/*! @brief Sets the Unicode character with modifiers callback.\n *\n *  This function sets the character with modifiers callback of the specified\n *  window, which is called when a Unicode character is input regardless of what\n *  modifier keys are used.\n *\n *  The character with modifiers callback is intended for implementing custom\n *  Unicode character input.  For regular Unicode text input, see the\n *  [character callback](@ref glfwSetCharCallback).  Like the character\n *  callback, the character with modifiers callback deals with characters and is\n *  keyboard layout dependent.  Characters do not map 1:1 to physical keys, as\n *  a key may produce zero, one or more characters.  If you want to know whether\n *  a specific physical key was pressed or released, see the\n *  [key callback](@ref glfwSetKeyCallback) instead.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or an\n *  error occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_char\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);\n\n/*! @brief Sets the mouse button callback.\n *\n *  This function sets the mouse button callback of the specified window, which\n *  is called when a mouse button is pressed or released.\n *\n *  When a window loses input focus, it will generate synthetic mouse button\n *  release events for all pressed mouse buttons.  You can tell these events\n *  from user-generated events by the fact that the synthetic ones are generated\n *  after the focus loss event has been processed, i.e. after the\n *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref input_mouse_button\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter and return value.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);\n\n/*! @brief Sets the cursor position callback.\n *\n *  This function sets the cursor position callback of the specified window,\n *  which is called when the cursor is moved.  The callback is provided with the\n *  position, in screen coordinates, relative to the upper-left corner of the\n *  client area of the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_pos\n *\n *  @since Added in version 3.0.  Replaces `glfwSetMousePosCallback`.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);\n\n/*! @brief Sets the cursor enter/exit callback.\n *\n *  This function sets the cursor boundary crossing callback of the specified\n *  window, which is called when the cursor enters or leaves the client area of\n *  the window.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref cursor_enter\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);\n\n/*! @brief Sets the scroll callback.\n *\n *  This function sets the scroll callback of the specified window, which is\n *  called when a scrolling device is used, such as a mouse wheel or scrolling\n *  area of a touchpad.\n *\n *  The scroll callback receives all scrolling input, like that from a mouse\n *  wheel or a touchpad scrolling area.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new scroll callback, or `NULL` to remove the currently\n *  set callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref scrolling\n *\n *  @since Added in version 3.0.  Replaces `glfwSetMouseWheelCallback`.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);\n\n/*! @brief Sets the file drop callback.\n *\n *  This function sets the file drop callback of the specified window, which is\n *  called when one or more dragged files are dropped on the window.\n *\n *  Because the path array and its strings may have been generated specifically\n *  for that event, they are not guaranteed to be valid after the callback has\n *  returned.  If you wish to use them after the callback returns, you need to\n *  make a deep copy.\n *\n *  @param[in] window The window whose callback to set.\n *  @param[in] cbfun The new file drop callback, or `NULL` to remove the\n *  currently set callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref path_drop\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);\n\n/*! @brief Returns whether the specified joystick is present.\n *\n *  This function returns whether the specified joystick is present.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick\n *\n *  @since Added in version 3.0.  Replaces `glfwGetJoystickParam`.\n *\n *  @ingroup input\n */\nGLFWAPI int glfwJoystickPresent(int joy);\n\n/*! @brief Returns the values of all axes of the specified joystick.\n *\n *  This function returns the values of all axes of the specified joystick.\n *  Each element in the array is a value between -1.0 and 1.0.\n *\n *  Querying a joystick slot with no device present is not an error, but will\n *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to\n *  check device presence.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @param[out] count Where to store the number of axis values in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of axis values, or `NULL` if the joystick is not present.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified joystick is\n *  disconnected, this function is called again for that joystick or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_axis\n *\n *  @since Added in version 3.0.  Replaces `glfwGetJoystickPos`.\n *\n *  @ingroup input\n */\nGLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);\n\n/*! @brief Returns the state of all buttons of the specified joystick.\n *\n *  This function returns the state of all buttons of the specified joystick.\n *  Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.\n *\n *  Querying a joystick slot with no device present is not an error, but will\n *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to\n *  check device presence.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @param[out] count Where to store the number of button states in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of button states, or `NULL` if the joystick is not present.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified joystick is\n *  disconnected, this function is called again for that joystick or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_button\n *\n *  @since Added in version 2.2.\n *  @glfw3 Changed to return a dynamic array.\n *\n *  @ingroup input\n */\nGLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);\n\n/*! @brief Returns the name of the specified joystick.\n *\n *  This function returns the name, encoded as UTF-8, of the specified joystick.\n *  The returned string is allocated and freed by GLFW.  You should not free it\n *  yourself.\n *\n *  Querying a joystick slot with no device present is not an error, but will\n *  cause this function to return `NULL`.  Call @ref glfwJoystickPresent to\n *  check device presence.\n *\n *  @param[in] joy The [joystick](@ref joysticks) to query.\n *  @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick\n *  is not present.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the specified joystick is\n *  disconnected, this function is called again for that joystick or the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_name\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI const char* glfwGetJoystickName(int joy);\n\n/*! @brief Sets the joystick configuration callback.\n *\n *  This function sets the joystick configuration callback, or removes the\n *  currently set callback.  This is called when a joystick is connected to or\n *  disconnected from the system.\n *\n *  @param[in] cbfun The new callback, or `NULL` to remove the currently set\n *  callback.\n *  @return The previously set callback, or `NULL` if no callback was set or the\n *  library had not been [initialized](@ref intro_init).\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref joystick_event\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);\n\n/*! @brief Sets the clipboard to the specified string.\n *\n *  This function sets the system clipboard to the specified, UTF-8 encoded\n *  string.\n *\n *  @param[in] window The window that will own the clipboard contents.\n *  @param[in] string A UTF-8 encoded string.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The specified string is copied before this function\n *  returns.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref clipboard\n *  @sa glfwGetClipboardString\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);\n\n/*! @brief Returns the contents of the clipboard as a string.\n *\n *  This function returns the contents of the system clipboard, if it contains\n *  or is convertible to a UTF-8 encoded string.  If the clipboard is empty or\n *  if its contents cannot be converted, `NULL` is returned and a @ref\n *  GLFW_FORMAT_UNAVAILABLE error is generated.\n *\n *  @param[in] window The window that will request the clipboard contents.\n *  @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`\n *  if an [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @pointer_lifetime The returned string is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is valid until the next call to @ref\n *  glfwGetClipboardString or @ref glfwSetClipboardString, or until the library\n *  is terminated.\n *\n *  @thread_safety This function must only be called from the main thread.\n *\n *  @sa @ref clipboard\n *  @sa glfwSetClipboardString\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup input\n */\nGLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);\n\n/*! @brief Returns the value of the GLFW timer.\n *\n *  This function returns the value of the GLFW timer.  Unless the timer has\n *  been set using @ref glfwSetTime, the timer measures time elapsed since GLFW\n *  was initialized.\n *\n *  The resolution of the timer is system dependent, but is usually on the order\n *  of a few micro- or nanoseconds.  It uses the highest-resolution monotonic\n *  time source on each supported platform.\n *\n *  @return The current value, in seconds, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.  Reading and\n *  writing of the internal timer offset is not atomic, so it needs to be\n *  externally synchronized with calls to @ref glfwSetTime.\n *\n *  @sa @ref time\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup input\n */\nGLFWAPI double glfwGetTime(void);\n\n/*! @brief Sets the GLFW timer.\n *\n *  This function sets the value of the GLFW timer.  It then continues to count\n *  up from that value.  The value must be a positive finite number less than\n *  or equal to 18446744073.0, which is approximately 584.5 years.\n *\n *  @param[in] time The new value, in seconds.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_INVALID_VALUE.\n *\n *  @remark The upper limit of the timer is calculated as\n *  floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations\n *  storing nanoseconds in 64 bits.  The limit may be increased in the future.\n *\n *  @thread_safety This function may be called from any thread.  Reading and\n *  writing of the internal timer offset is not atomic, so it needs to be\n *  externally synchronized with calls to @ref glfwGetTime.\n *\n *  @sa @ref time\n *\n *  @since Added in version 2.2.\n *\n *  @ingroup input\n */\nGLFWAPI void glfwSetTime(double time);\n\n/*! @brief Returns the current value of the raw timer.\n *\n *  This function returns the current value of the raw timer, measured in\n *  1&nbsp;/&nbsp;frequency seconds.  To get the frequency, call @ref\n *  glfwGetTimerFrequency.\n *\n *  @return The value of the timer, or zero if an \n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref time\n *  @sa glfwGetTimerFrequency\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI uint64_t glfwGetTimerValue(void);\n\n/*! @brief Returns the frequency, in Hz, of the raw timer.\n *\n *  This function returns the frequency, in Hz, of the raw timer.\n *\n *  @return The frequency of the timer, in Hz, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref time\n *  @sa glfwGetTimerValue\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup input\n */\nGLFWAPI uint64_t glfwGetTimerFrequency(void);\n\n/*! @brief Makes the context of the specified window current for the calling\n *  thread.\n *\n *  This function makes the OpenGL or OpenGL ES context of the specified window\n *  current on the calling thread.  A context can only be made current on\n *  a single thread at a time and each thread can have only a single current\n *  context at a time.\n *\n *  By default, making a context non-current implicitly forces a pipeline flush.\n *  On machines that support `GL_KHR_context_flush_control`, you can control\n *  whether a context performs this flush by setting the\n *  [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.\n *\n *  The specified window must have an OpenGL or OpenGL ES context.  Specifying\n *  a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT\n *  error.\n *\n *  @param[in] window The window whose context to make current, or `NULL` to\n *  detach the current context.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_current\n *  @sa glfwGetCurrentContext\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup context\n */\nGLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);\n\n/*! @brief Returns the window whose context is current on the calling thread.\n *\n *  This function returns the window whose OpenGL or OpenGL ES context is\n *  current on the calling thread.\n *\n *  @return The window whose context is current, or `NULL` if no window's\n *  context is current.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_current\n *  @sa glfwMakeContextCurrent\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup context\n */\nGLFWAPI GLFWwindow* glfwGetCurrentContext(void);\n\n/*! @brief Swaps the front and back buffers of the specified window.\n *\n *  This function swaps the front and back buffers of the specified window when\n *  rendering with OpenGL or OpenGL ES.  If the swap interval is greater than\n *  zero, the GPU driver waits the specified number of screen updates before\n *  swapping the buffers.\n *\n *  The specified window must have an OpenGL or OpenGL ES context.  Specifying\n *  a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT\n *  error.\n *\n *  This function does not apply to Vulkan.  If you are rendering with Vulkan,\n *  see `vkQueuePresentKHR` instead.\n *\n *  @param[in] window The window whose buffers to swap.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark __EGL:__ The context of the specified window must be current on the\n *  calling thread.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref buffer_swap\n *  @sa glfwSwapInterval\n *\n *  @since Added in version 1.0.\n *  @glfw3 Added window handle parameter.\n *\n *  @ingroup window\n */\nGLFWAPI void glfwSwapBuffers(GLFWwindow* window);\n\n/*! @brief Sets the swap interval for the current context.\n *\n *  This function sets the swap interval for the current OpenGL or OpenGL ES\n *  context, i.e. the number of screen updates to wait from the time @ref\n *  glfwSwapBuffers was called before swapping the buffers and returning.  This\n *  is sometimes called _vertical synchronization_, _vertical retrace\n *  synchronization_ or just _vsync_.\n *\n *  Contexts that support either of the `WGL_EXT_swap_control_tear` and\n *  `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,\n *  which allow the driver to swap even if a frame arrives a little bit late.\n *  You can check for the presence of these extensions using @ref\n *  glfwExtensionSupported.  For more information about swap tearing, see the\n *  extension specifications.\n *\n *  A context must be current on the calling thread.  Calling this function\n *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.\n *\n *  This function does not apply to Vulkan.  If you are rendering with Vulkan,\n *  see the present mode of your swapchain instead.\n *\n *  @param[in] interval The minimum number of screen updates to wait for\n *  until the buffers are swapped by @ref glfwSwapBuffers.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark This function is not called during context creation, leaving the\n *  swap interval set to whatever is the default on that platform.  This is done\n *  because some swap interval extensions used by GLFW do not allow the swap\n *  interval to be reset to zero once it has been set to a non-zero value.\n *\n *  @remark Some GPU drivers do not honor the requested swap interval, either\n *  because of a user setting that overrides the application's request or due to\n *  bugs in the driver.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref buffer_swap\n *  @sa glfwSwapBuffers\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup context\n */\nGLFWAPI void glfwSwapInterval(int interval);\n\n/*! @brief Returns whether the specified extension is available.\n *\n *  This function returns whether the specified\n *  [API extension](@ref context_glext) is supported by the current OpenGL or\n *  OpenGL ES context.  It searches both for client API extension and context\n *  creation API extensions.\n *\n *  A context must be current on the calling thread.  Calling this function\n *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.\n *\n *  As this functions retrieves and searches one or more extension strings each\n *  call, it is recommended that you cache its results if it is going to be used\n *  frequently.  The extension strings will not change during the lifetime of\n *  a context, so there is no danger in doing this.\n *\n *  This function does not apply to Vulkan.  If you are using Vulkan, see @ref\n *  glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`\n *  and `vkEnumerateDeviceExtensionProperties` instead.\n *\n *  @param[in] extension The ASCII encoded name of the extension.\n *  @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`\n *  otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref\n *  GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_glext\n *  @sa glfwGetProcAddress\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup context\n */\nGLFWAPI int glfwExtensionSupported(const char* extension);\n\n/*! @brief Returns the address of the specified function for the current\n *  context.\n *\n *  This function returns the address of the specified OpenGL or OpenGL ES\n *  [core or extension function](@ref context_glext), if it is supported\n *  by the current context.\n *\n *  A context must be current on the calling thread.  Calling this function\n *  without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.\n *\n *  This function does not apply to Vulkan.  If you are rendering with Vulkan,\n *  see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and\n *  `vkGetDeviceProcAddr` instead.\n *\n *  @param[in] procname The ASCII encoded name of the function.\n *  @return The address of the function, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remark The address of a given function is not guaranteed to be the same\n *  between contexts.\n *\n *  @remark This function may return a non-`NULL` address despite the\n *  associated version or extension not being available.  Always check the\n *  context version or extension string first.\n *\n *  @pointer_lifetime The returned function pointer is valid until the context\n *  is destroyed or the library is terminated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref context_glext\n *  @sa glfwExtensionSupported\n *\n *  @since Added in version 1.0.\n *\n *  @ingroup context\n */\nGLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);\n\n/*! @brief Returns whether the Vulkan loader has been found.\n *\n *  This function returns whether the Vulkan loader has been found.  This check\n *  is performed by @ref glfwInit.\n *\n *  The availability of a Vulkan loader does not by itself guarantee that window\n *  surface creation or even device creation is possible.  Call @ref\n *  glfwGetRequiredInstanceExtensions to check whether the extensions necessary\n *  for Vulkan surface creation are available and @ref\n *  glfwGetPhysicalDevicePresentationSupport to check whether a queue family of\n *  a physical device supports image presentation.\n *\n *  @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref vulkan_support\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI int glfwVulkanSupported(void);\n\n/*! @brief Returns the Vulkan instance extensions required by GLFW.\n *\n *  This function returns an array of names of Vulkan instance extensions required\n *  by GLFW for creating Vulkan surfaces for GLFW windows.  If successful, the\n *  list will always contains `VK_KHR_surface`, so if you don't require any\n *  additional extensions you can pass this list directly to the\n *  `VkInstanceCreateInfo` struct.\n *\n *  If Vulkan is not available on the machine, this function returns `NULL` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported\n *  to check whether Vulkan is available.\n *\n *  If Vulkan is available but no set of extensions allowing window surface\n *  creation was found, this function returns `NULL`.  You may still use Vulkan\n *  for off-screen rendering and compute work.\n *\n *  @param[out] count Where to store the number of extensions in the returned\n *  array.  This is set to zero if an error occurred.\n *  @return An array of ASCII encoded extension names, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_API_UNAVAILABLE.\n *\n *  @remarks Additional extensions may be required by future versions of GLFW.\n *  You should check if any extensions you wish to enable are already in the\n *  returned array, as it is an error to specify an extension more than once in\n *  the `VkInstanceCreateInfo` struct.\n *\n *  @pointer_lifetime The returned array is allocated and freed by GLFW.  You\n *  should not free it yourself.  It is guaranteed to be valid only until the\n *  library is terminated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref vulkan_ext\n *  @sa glfwCreateWindowSurface\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);\n\n#if defined(VK_VERSION_1_0)\n\n/*! @brief Returns the address of the specified Vulkan instance function.\n *\n *  This function returns the address of the specified Vulkan core or extension\n *  function for the specified instance.  If instance is set to `NULL` it can\n *  return any function exported from the Vulkan loader, including at least the\n *  following functions:\n *\n *  - `vkEnumerateInstanceExtensionProperties`\n *  - `vkEnumerateInstanceLayerProperties`\n *  - `vkCreateInstance`\n *  - `vkGetInstanceProcAddr`\n *\n *  If Vulkan is not available on the machine, this function returns `NULL` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported\n *  to check whether Vulkan is available.\n *\n *  This function is equivalent to calling `vkGetInstanceProcAddr` with\n *  a platform-specific query of the Vulkan loader as a fallback.\n *\n *  @param[in] instance The Vulkan instance to query, or `NULL` to retrieve\n *  functions related to instance creation.\n *  @param[in] procname The ASCII encoded name of the function.\n *  @return The address of the function, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref\n *  GLFW_API_UNAVAILABLE.\n *\n *  @pointer_lifetime The returned function pointer is valid until the library\n *  is terminated.\n *\n *  @thread_safety This function may be called from any thread.\n *\n *  @sa @ref vulkan_proc\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);\n\n/*! @brief Returns whether the specified queue family can present images.\n *\n *  This function returns whether the specified queue family of the specified\n *  physical device supports presentation to the platform GLFW was built for.\n *\n *  If Vulkan or the required window surface creation instance extensions are\n *  not available on the machine, or if the specified instance was not created\n *  with the required extensions, this function returns `GLFW_FALSE` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref glfwVulkanSupported\n *  to check whether Vulkan is available and @ref\n *  glfwGetRequiredInstanceExtensions to check what instance extensions are\n *  required.\n *\n *  @param[in] instance The instance that the physical device belongs to.\n *  @param[in] device The physical device that the queue family belongs to.\n *  @param[in] queuefamily The index of the queue family to query.\n *  @return `GLFW_TRUE` if the queue family supports presentation, or\n *  `GLFW_FALSE` otherwise.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @thread_safety This function may be called from any thread.  For\n *  synchronization details of Vulkan objects, see the Vulkan specification.\n *\n *  @sa @ref vulkan_present\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);\n\n/*! @brief Creates a Vulkan surface for the specified window.\n *\n *  This function creates a Vulkan surface for the specified window.\n *\n *  If the Vulkan loader was not found at initialization, this function returns\n *  `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE\n *  error.  Call @ref glfwVulkanSupported to check whether the Vulkan loader was\n *  found.\n *\n *  If the required window surface creation instance extensions are not\n *  available or if the specified instance was not created with these extensions\n *  enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and\n *  generates a @ref GLFW_API_UNAVAILABLE error.  Call @ref\n *  glfwGetRequiredInstanceExtensions to check what instance extensions are\n *  required.\n *\n *  The window surface must be destroyed before the specified Vulkan instance.\n *  It is the responsibility of the caller to destroy the window surface.  GLFW\n *  does not destroy it for you.  Call `vkDestroySurfaceKHR` to destroy the\n *  surface.\n *\n *  @param[in] instance The Vulkan instance to create the surface in.\n *  @param[in] window The window to create the surface for.\n *  @param[in] allocator The allocator to use, or `NULL` to use the default\n *  allocator.\n *  @param[out] surface Where to store the handle of the surface.  This is set\n *  to `VK_NULL_HANDLE` if an error occurred.\n *  @return `VK_SUCCESS` if successful, or a Vulkan error code if an\n *  [error](@ref error_handling) occurred.\n *\n *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref\n *  GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.\n *\n *  @remarks If an error occurs before the creation call is made, GLFW returns\n *  the Vulkan error code most appropriate for the error.  Appropriate use of\n *  @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should\n *  eliminate almost all occurrences of these errors.\n *\n *  @thread_safety This function may be called from any thread.  For\n *  synchronization details of Vulkan objects, see the Vulkan specification.\n *\n *  @sa @ref vulkan_surface\n *  @sa glfwGetRequiredInstanceExtensions\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup vulkan\n */\nGLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);\n\n#endif /*VK_VERSION_1_0*/\n\n\n/*************************************************************************\n * Global definition cleanup\n *************************************************************************/\n\n/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */\n\n#ifdef GLFW_WINGDIAPI_DEFINED\n #undef WINGDIAPI\n #undef GLFW_WINGDIAPI_DEFINED\n#endif\n\n#ifdef GLFW_CALLBACK_DEFINED\n #undef CALLBACK\n #undef GLFW_CALLBACK_DEFINED\n#endif\n\n/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _glfw3_h_ */\n\n"
  },
  {
    "path": "samples/vs2015/glfw-3.2-WIN64/include/GLFW/glfw3native.h",
    "content": "/*************************************************************************\n * GLFW 3.2 - www.glfw.org\n * A library for OpenGL, window and input\n *------------------------------------------------------------------------\n * Copyright (c) 2002-2006 Marcus Geelnard\n * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n *\n *************************************************************************/\n\n#ifndef _glfw3_native_h_\n#define _glfw3_native_h_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/*************************************************************************\n * Doxygen documentation\n *************************************************************************/\n\n/*! @file glfw3native.h\n *  @brief The header of the native access functions.\n *\n *  This is the header file of the native access functions.  See @ref native for\n *  more information.\n */\n/*! @defgroup native Native access\n *\n *  **By using the native access functions you assert that you know what you're\n *  doing and how to fix problems caused by using them.  If you don't, you\n *  shouldn't be using them.**\n *\n *  Before the inclusion of @ref glfw3native.h, you may define exactly one\n *  window system API macro and zero or more context creation API macros.\n *\n *  The chosen backends must match those the library was compiled for.  Failure\n *  to do this will cause a link-time error.\n *\n *  The available window API macros are:\n *  * `GLFW_EXPOSE_NATIVE_WIN32`\n *  * `GLFW_EXPOSE_NATIVE_COCOA`\n *  * `GLFW_EXPOSE_NATIVE_X11`\n *  * `GLFW_EXPOSE_NATIVE_WAYLAND`\n *  * `GLFW_EXPOSE_NATIVE_MIR`\n *\n *  The available context API macros are:\n *  * `GLFW_EXPOSE_NATIVE_WGL`\n *  * `GLFW_EXPOSE_NATIVE_NSGL`\n *  * `GLFW_EXPOSE_NATIVE_GLX`\n *  * `GLFW_EXPOSE_NATIVE_EGL`\n *\n *  These macros select which of the native access functions that are declared\n *  and which platform-specific headers to include.  It is then up your (by\n *  definition platform-specific) code to handle which of these should be\n *  defined.\n */\n\n\n/*************************************************************************\n * System headers and types\n *************************************************************************/\n\n#if defined(GLFW_EXPOSE_NATIVE_WIN32)\n // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for\n // example to allow applications to correctly declare a GL_ARB_debug_output\n // callback) but windows.h assumes no one will define APIENTRY before it does\n #undef APIENTRY\n #include <windows.h>\n#elif defined(GLFW_EXPOSE_NATIVE_COCOA)\n #include <ApplicationServices/ApplicationServices.h>\n #if defined(__OBJC__)\n  #import <Cocoa/Cocoa.h>\n #else\n  typedef void* id;\n #endif\n#elif defined(GLFW_EXPOSE_NATIVE_X11)\n #include <X11/Xlib.h>\n #include <X11/extensions/Xrandr.h>\n#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)\n #include <wayland-client.h>\n#elif defined(GLFW_EXPOSE_NATIVE_MIR)\n #include <mir_toolkit/mir_client_library.h>\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_WGL)\n /* WGL is declared by windows.h */\n#endif\n#if defined(GLFW_EXPOSE_NATIVE_NSGL)\n /* NSGL is declared by Cocoa.h */\n#endif\n#if defined(GLFW_EXPOSE_NATIVE_GLX)\n #include <GL/glx.h>\n#endif\n#if defined(GLFW_EXPOSE_NATIVE_EGL)\n #include <EGL/egl.h>\n#endif\n\n\n/*************************************************************************\n * Functions\n *************************************************************************/\n\n#if defined(GLFW_EXPOSE_NATIVE_WIN32)\n/*! @brief Returns the adapter device name of the specified monitor.\n *\n *  @return The UTF-8 encoded adapter device name (for example `\\\\.\\DISPLAY1`)\n *  of the specified monitor, or `NULL` if an [error](@ref error_handling)\n *  occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);\n\n/*! @brief Returns the display device name of the specified monitor.\n *\n *  @return The UTF-8 encoded display device name (for example\n *  `\\\\.\\DISPLAY1\\Monitor0`) of the specified monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `HWND` of the specified window.\n *\n *  @return The `HWND` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_WGL)\n/*! @brief Returns the `HGLRC` of the specified window.\n *\n *  @return The `HGLRC` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_COCOA)\n/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.\n *\n *  @return The `CGDirectDisplayID` of the specified monitor, or\n *  `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `NSWindow` of the specified window.\n *\n *  @return The `NSWindow` of the specified window, or `nil` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_NSGL)\n/*! @brief Returns the `NSOpenGLContext` of the specified window.\n *\n *  @return The `NSOpenGLContext` of the specified window, or `nil` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI id glfwGetNSGLContext(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_X11)\n/*! @brief Returns the `Display` used by GLFW.\n *\n *  @return The `Display` used by GLFW, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI Display* glfwGetX11Display(void);\n\n/*! @brief Returns the `RRCrtc` of the specified monitor.\n *\n *  @return The `RRCrtc` of the specified monitor, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);\n\n/*! @brief Returns the `RROutput` of the specified monitor.\n *\n *  @return The `RROutput` of the specified monitor, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.1.\n *\n *  @ingroup native\n */\nGLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `Window` of the specified window.\n *\n *  @return The `Window` of the specified window, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI Window glfwGetX11Window(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_GLX)\n/*! @brief Returns the `GLXContext` of the specified window.\n *\n *  @return The `GLXContext` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);\n\n/*! @brief Returns the `GLXWindow` of the specified window.\n *\n *  @return The `GLXWindow` of the specified window, or `None` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)\n/*! @brief Returns the `struct wl_display*` used by GLFW.\n *\n *  @return The `struct wl_display*` used by GLFW, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI struct wl_display* glfwGetWaylandDisplay(void);\n\n/*! @brief Returns the `struct wl_output*` of the specified monitor.\n *\n *  @return The `struct wl_output*` of the specified monitor, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the main `struct wl_surface*` of the specified window.\n *\n *  @return The main `struct wl_surface*` of the specified window, or `NULL` if\n *  an [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_MIR)\n/*! @brief Returns the `MirConnection*` used by GLFW.\n *\n *  @return The `MirConnection*` used by GLFW, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI MirConnection* glfwGetMirDisplay(void);\n\n/*! @brief Returns the Mir output ID of the specified monitor.\n *\n *  @return The Mir output ID of the specified monitor, or zero if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);\n\n/*! @brief Returns the `MirSurface*` of the specified window.\n *\n *  @return The `MirSurface*` of the specified window, or `NULL` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.2.\n *\n *  @ingroup native\n */\nGLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);\n#endif\n\n#if defined(GLFW_EXPOSE_NATIVE_EGL)\n/*! @brief Returns the `EGLDisplay` used by GLFW.\n *\n *  @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI EGLDisplay glfwGetEGLDisplay(void);\n\n/*! @brief Returns the `EGLContext` of the specified window.\n *\n *  @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);\n\n/*! @brief Returns the `EGLSurface` of the specified window.\n *\n *  @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an\n *  [error](@ref error_handling) occurred.\n *\n *  @thread_safety This function may be called from any thread.  Access is not\n *  synchronized.\n *\n *  @since Added in version 3.0.\n *\n *  @ingroup native\n */\nGLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _glfw3_native_h_ */\n\n"
  }
]